[Standards-JIG] An XMPP Race Condition most Vexing

Matthias Wimmer m at tthias.eu
Wed Oct 25 07:04:12 UTC 2006

Hi Chris!

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.

Tot kijk

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 mailing list