[Standards-JIG] An XMPP Race Condition most Vexing
chris.mullins at coversant.net
Wed Oct 25 17:38:22 UTC 2006
I'm pretty well versed with the common issues with multi-threaded programming, database concurrency, paralell algorithms, and other related issues.
The problem with this particular race condition, is that, conceptually, it can happen over an s2s link with each user on a different server. This really is a protocol level condition (albiet a very minor one), that I was hoping we could figure out a way to solve.
I can certainly solve it in the database via concurrency checks (as your example showed), or I can solve it in code in a variety of ways. I would rather solve it at the algorithm level, although I don't see an easy way to do it - which is why I posted it here. I suspect this will just end up as a "beware of this" footnote in PSA's "Implementors Guide".
From: standards-jig-bounces at jabber.org [mailto:standards-jig-bounces at jabber.org] On Behalf Of Matthias Wimmer
Sent: Wednesday, October 25, 2006 12:04 AM
To: Jabber protocol discussion list
Subject: Re: [Standards-JIG] An XMPP Race Condition most Vexing
Chris Mullins schrieb:
> I just came across a very unusual race condition that likely exists in
> all XMPP and Jabber servers, and I wanted to kick the idea around and
> see if we can come up with a solid answer.
> At one instant, the server will modify user1's roster to be
> "subscribe="from" and user2's roster to be "subscribe=to".
> At the SAME instant, the server will modify user2's roster to be
> "subscribe=from" and user1's roster to be "subscribe=to".
> At the time each user made the change, it was correct. All packets have
> been processed in order. The problem is that two packets were operating
> on the same logical construct at the same time and there's no lock to
> guarantee the item.
> The problem, and what we're missing in the protocol, is some sort of
> lock construct around a Roster Tuple. We solve almost all of the XMPP
> Race Conditions by requiring packets to be processed in order - but
> anytime two users interact there needs to be additional locking to
> prevent the issue.
> Any thoughts for a way to eliminate this at the protocol level? We can
> obviously fix this case this case in our codebase with an "items being
> edited" lock table, and acquiring and releasing locks when modifying
> roster items. A more general approach would sure be nice though.
I don't think that this is a problem present in all servers. If you are
implementing a multi-threaded program it has always been the programmers
responsibility to look data, that is accessed by different threads.
If you are storing your data in a database, and you are accessing it
from different processes, that's what database transactions are for. -
Or you can make your UPDATE query more intelligent, e.g.:
UPDATE SET subscription=(CASE WHEN subscription='none' THEN 'from' ELSE
'both' END) WHERE jid='foo at example.com';
-- or whatever your SQL server uses instead of CASE, e.g.
IF(subscription='none', 'from', 'both').
As well as you could have two different fields `from` and `to` in the
database, storing "both" as setting both. So it just gets something
like this: UPDATE SET from=1 WHERE jid='foo at example.com'.
I do not think, that this is something, that has to be handled at the
XMPP level. It is something that is an implementation detail of the
server and can be solved easily there.
Matthias Wimmer Fon +49-700 77 00 77 70
Züricher Str. 243 Fax +49-89 95 89 91 56
81476 München http://ma.tthias.eu/
More information about the Standards