Shadow version mismatch scenario

14 views
Skip to first unread message

Martin Kreichgauer

unread,
Nov 16, 2010, 6:10:57 PM11/16/10
to MobWrite
I have a question about the implementation of the python daemon [0].
Lines 547 ff. deal with the case that a client sends an update with a
server shadow version number that doesn't match the servers current
state. That happens e.g. when the server does an unexpected restart.
In this case, view_obj.delta_ok is set to False and thus generateDiffs
will send a raw update (lines 635 ff.).

Also, viewobj.shadow_client_version is incremented by 1 (line 638) and
I'm not entirely sure if this is correct behaviour. Say the server has
to do an unexpected restart, then receives a delta with a wrong server
shadow version number and sends an empty raw update to that client
(because it couldn't load a text for that file from the storage).
Afterwards, the client's shadow version would be 0, while the view
object's shadow_client_version would be 1. Subsequently, another
version mismatch will occur.

Is there an explanation for this behaviour or is it a mistake in the
implementation?

[0] http://code.google.com/p/google-mobwrite/source/browse/trunk/daemon/mobwrite_daemon.py

Neil Fraser

unread,
Nov 16, 2010, 7:30:51 PM11/16/10
to MobWrite
On Nov 16, 3:10 pm, Martin Kreichgauer <kreichga...@gmail.com> wrote:
> That happens e.g. when the server does an unexpected restart.

The current implementation does not store the shadows or version
numbers to disk, which means that after a restart the server has an
unknown client arriving with an unknown version. In cases like this
where it is unknowable whether the server messed up or the client
messed up, the server wins. This way someone with a bad client isn't
going to poison the system for everyone.

Does this answer the question? If not, let me know and I'll look into
it more closely.

Neil Fraser

unread,
Nov 16, 2010, 7:35:09 PM11/16/10
to MobWrite
On Nov 16, 4:30 pm, Neil Fraser <neil.fra...@gmail.com> wrote:
> The current implementation does not store the shadows or version
> numbers to disk,

Clarification: The above only applies to the Python Daemon, which was
the subject of the original question. The App Engine version does
store all this information to disk and there is no state change when
the server is restarted.

Martin Kreichgauer

unread,
Nov 16, 2010, 9:44:35 PM11/16/10
to MobWrite
On Nov 16, 4:30 pm, Neil Fraser <neil.fra...@gmail.com> wrote:
> The current implementation does not store the shadows or version
> numbers to disk, which means that after a restart the server has an
> unknown client arriving with an unknown version.  In cases like this
> where it is unknowable whether the server messed up or the client
> messed up, the server wins.  This way someone with a bad client isn't
> going to poison the system for everyone.
>
> Does this answer the question?  If not, let me know and I'll look into
> it more closely.

I probably hid my question too well- The question is: Why does the
server increment the client shadow version to 1 in the example
outlined above, while it tells the client to set it to 0?

> The current implementation does not store the shadows or version
> numbers to disk, which means that after a restart the server has an
> unknown client arriving with an unknown version.

Yes. In this case the server sends an empty 'r:0:' (let's assume that
the server cannot load the text from disk and it's an 'r' not an 'R').
This has the client empty its server shadow and reset its server
shadow version number. Then it sends a diff from its local text, which
is still unmodified, against the (empty) server shadow. So the
client's response would look something like this:

F:0:foobar
d:0:(diff-text)

Now the server runs in the "action["client_version"] <
viewobj.shadow_client_version" part, because it has previously
incremented the shadow_client_version to 1. This means, it doesn't
apply the diff. And since the text is still empty, it sends the client

F:1:foobar
d:0:=0

The client now has a delta mismatch, because that diff is probably not
valid for its client text. So, the client in turn also sends an 'r:'
with its local text, thus ending up in sync again.

If the server had not incremented the version number in the first
place, the server would have simply applied the first diff from the
client to the empty shadow. Also probably hasn't got anything to do
with the server "winning" over the client because the _client_
actually sends the raw update that gets both parties back in sync. So
what am I missing here? :)

Cheers,
Martin
Reply all
Reply to author
Forward
0 new messages