0

I am about to design a system based on autobahn. I am frequently encountering the following pattern:

  • Clients can request a full state via an RPC topic - for example, all votes in the vote example
  • Updates to this state are published by the server - for example a changed vote of a specific subject
  • Clients keep track of the current state by combining the full state and the updates.

The problem is the following:
There is a potential race between querying the state and a published change due to the asynchronous nature of autobahn.
While the state is calculated on the server side an update might already be sent out to the client. Once the client receives the full state it is not up to date anymore. It must be patched with the earlier received update.

Somehow I have the feeling that this is a common problem. Is there some best practice on how to handle this case?

I am considering something like this:

  • Clients first subscribe to the update topic and only afterward do the RPC call.
  • All data sent by the server must be timestamped.
  • If an update is received before the RPC call returns it is saved.
  • Once the RPC call arrives the client patches the state with all received updates having a newer timestamp.

Does this make sense? Or am I missing something obvious?

I slightly modified the crossbar vote example to show the problem.
The RPC call to query the current votes is artificially delayed by 5 seconds. When opening the webapp and submitting a vote before the state is received, shortly the correct vote count is visible once the vote is processed and the update is received.
Eventually the delayed state arrives - and an outdated vote count is shown.

Yourstruly
  • 600
  • 5
  • 12

1 Answers1

0

The clean solution to this is a new (not yet documented feature in Crossbar.io: event retention.

This option provides subscribers with a single retained event before the first current subscription event. The retained event is selected by the publisher. If the publisher selects each event, then this feature provides you with the last published state.

There is an example for this at https://github.com/crossbario/autobahn-python/tree/master/examples/twisted/wamp/pubsub/retained

(Not sure about support in libraries except for Autobahn|Python.)

Otherwise: Your pattern with subscription before the call makes sense, as well as using timestamps.

gzost
  • 2,375
  • 1
  • 18
  • 25
  • I already played around with retained events. They work nicely when the complete state, compared to deltas, is published. I think Python and JS worked fine. In my case this does not help though as the subscriptions do not contain the complete state. When thinking about it, a simple counter sent when publishing events and as well attached to RPC answers might do the job as well. As soon as the RPC does something asynchronous, e.g. retrieving something from a database, one has really to take care that no races occur. – Yourstruly Jun 20 '17 at 12:27