[Standards] Proposed XMPP Extension: Roster Versioning
Dave Cridland
dave at cridland.net
Thu Mar 6 05:55:40 CST 2008
On Thu Mar 6 09:45:17 2008, Richard Dobson wrote:
>
>> A few hours of testing does not a reliable protocol make. Under
>> what
>> conditions? Is this a public server that people can test against?
>>
> No you are correct, but even so the tone of some of the messages on
> this subject as far as I read them said that it wouldn't work, and
> under my limited testing it does seem to. I can make it publically
> accessible if you like and actually want to and will have a go.
>
>
You can't rely on testing, sadly; you need to prove that it works.
Timestamps probably do work in most cases, as long as the updates to
the roster are atomically and sequentially performed on a single
point, and your implementation is sufficiently slow that timestamps
are obtained at a maximum frequency lower than their resolution. This
is simply because then you have a strictly increasing sequence.
However, timestamps don't always work like that even on a single
machine. It just happens that they usually do. I'm not terribly keen
on making the specification define a new RFC 2119 entry candidate for
MUST USUALLY. ;-)
>> "It's a lot more efficient with an int, and everything else is
>> either
>> worse performance, fails entirely, or else is equivalent
>> difficulty to
>> an int."
>>
> What sort of things are these? Im not trying to say im right and
> he's wrong but id like a more full explanation on the points above
> and below so I can understand why Dave thinks it will break,
> because as far as I can see all the problems pointed out so far in
> this thread can be easily overcome.
>
>
If you modify a timestamp value, or for that matter generate it in
such a way that it's strictly increasing, then everything *will*
work. But since you can model that trivially as a non-negative
integer, it's not a problem. But since you can, it's a lot easier to
simply use an arbitrary strictly increasing integer sequence anyway.
>> "One interesting point is that with an int, there's always
>> something a
>> client can use to get the entire roster, with versioning turned
>> on."
>>
> Yea it can just omit the version attribute.
>
>
Then it doesn't get versioning. (BTW, I hate that name - there are no
versions kept. It's not like a client can ask for a previous version,
and nor does a server need to keep any previous versions).
>> "Put it this way, since the counter-proposal involved timestamps,
>> which
>> are known to be broken, I'm pretty sure people will get stuff wrong
>> without it being a MUST."
>>
> Why are they broken?
>
>
See previous messages. They're not strictly increasing, nor are they
strictly non-decreasing, nor are they even unique.
>> And [3]:
>>
>> "You can't use timestamps - they're not strictly increasing, for
>> various reasons.
>>
> Why does it have to be strictly increasing, even if it was a
> timestamp?
>
>
Because you want them to have the property that for any known state,
the server can produce a delta to the current state. Now, as it
happens, we allow in this specification for a server to give up and
provide the complete roster, and given this escape hatch, "unique" is
sufficient if you wanted to produce a really poor implementation.
However, you do need to ensure it really is unique, and given
multi-core multi-threading clustered servers, about the simplest way
is to just use a strictly increasing integer sequence. After all, you
need some central point to perform atomic updates of the roster,
right?
Now, if what you have is a sequence which usually goes up, but
sometimes goes down, and is not unique, then updates can simply be
lost to a client.
>> Firstly, two roster changes could happen at precisely the same
>> moment. To be fair, by introducing cluster node identifiers, and
>> having a strict strong ordering of them, you could avoid this.
>>
> Why is it a problem if two updates share the same version
> identifier? Couldn't they not just become part of a single atomic
> change?
>
>
That's "strictly non-decreasing", and neither "unique" nor "strictly
increasing".
The problem here is that a roster push only contains one item, so two
roster pushes would involve the same sequence value. (See rfc3921bis,
Section 2.1.4)
Given this, you need to ensure that either:
a) There is some way to indicate to the client that it now has all
roster pushes up to and including the sequence value. (ACAP style, if
you're wondering, since ACAP also has atomic updates spanning
multiple notifications). This involves an additional stanza, and if
it's lost, a client will observe all the previous pushes with the
same sequence value repeated - as such, it's inherently less
efficient on dodgy connectivity.
b) You cheat and lower the sequence value included in the roster
pushes, such that the sequence value the client next produces to
resynchronize will include all those pushes - effectively using a
subsequent push as an indicator to the client that all pushes
relating to previous sequence values have now been received.
(b) is less efficient than (a), which has more failure cases than
simply using a strictly increasing sequence. (b) will always send the
client data it already has.
>> Secondly, the clock on a computer can, and surprisingly often does,
>> go backwards. That's a much harder problem to solve.
>>
> As previously requested could you describe this further or point to
> some more information on this so I can understand how much of a
> problem this actually is.
>
>
It happens. Really and truly, it happens. How often isn't really the
point.
What happens is typically this:
1) The machine receives updates from NTP.
2) Typically, it adjusts its clock skew to converge on the real time.
3) But, if the clock is sufficiently wrong, it's simply moved.
4) This might be backwards.
Some machines are also configured to move the clock to an NTP derived
time on reboot - again, if reboots are sufficiently fast, and the
clock's offset was sufficiently large, that can cause the clock to
reverse.
Finally, even with a timestamp that never goes backwards, you need to
ensure that all members of a clustered setup use the same source, and
moreover test that the obtained timestamp is higher than any previous
timestamp obtained, so I just fail to see any advantage, really.
>> Thirdly, in a clustering situation, you'd have to ensure that the
>> time on each cluster node was perfectly synchronized.
>>
> No they don't as previously pointed out (the database layer could
> generate all the ids).
>
>
Yes, and it can generate integer ids just as well, if not better.
>> So the closest you can do would be a modified timestamp that had
>> additional logic during generation to ensure it never went
>> backwards,
>> in which case you don't need the cluster identifier anymore, and
>> that's effectively the same as having a strictly increasing integer
>> sequence anyway, so it's easier to just do that. But even if you
>> did
>> want to use timestamps, just representing them as an integer is
>> pretty trivial. Look at the definition of "modtime" in ACAP (RFC
>> 2244), which defines a strictly increasing modified timestamp
>> represented using digits."
>>
> Yup exactly so the issue about clocks going backwards can be easily
> overcome then.
>
>
"represented using digits". Feel free to do this if you want. RFC
2244 section 3.1.1, although you'll need to fix the subsecond
accuracy, so it's comparable as an int rather than a string. But:
1) I would note that the same guys who designed that essentially
ported it to IMAP as CONDSTORE, and dropped the entire timestamp
thing, making it an integer sequence instead. (*NOT* a contiguous
integer sequence, please note - many of the IMAP CONDSTORE examples
use ACAP modtime formats)
2) I've written an ACAP server. Getting modtimes right is neither as
simple, nor as fast, as getting an integer sequence right. And it's
still a strictly increasing integer sequence. (Although it says
"strictly ascending"). In fact, I know there are failure cases in my
code, I just hope they're sufficiently unlikely as to not affect
anyone. Given that I'm probably the only user of my ACAP server, I'm
probably safe.
I've got a fondness for doing it this way, as it happens, but I'd
certainly not mandate it, nor encourage anyone else to do the same.
> Is there any chance we can use BASE64 or something to compress the
> version identifiers in the roster pushes and whatnot?, just like is
> done with the hashes in caps? Or do we think its probably not
> really going to be a problem in the future? Granted as an auto
> incrementing integer it probably wont be much of an issue unless
> you have an incredibly busy roster, just trying to plan ahead.
It won't compress them if they're integers until you get over 9999,
since base64 comes in multiples of four characters. So the best way
for efficiency for the majority is to ensure you use a compact
sequence.
FWIW, I'm not convinced that the additional traffic here is worth
worrying about at all either way.
Dave.
--
Dave Cridland - mailto:dave at cridland.net - xmpp:dwd at jabber.org
- acap://acap.dave.cridland.net/byowner/user/dwd/bookmarks/
- http://dave.cridland.net/
Infotrope Polymer - ACAP, IMAP, ESMTP, and Lemonade
More information about the Standards
mailing list