logux / client

Logux base components to build web client
https://logux.org/
MIT License
663 stars 47 forks source link

fix: resubscribe on synchronize #94

Closed DecathectZero closed 2 years ago

DecathectZero commented 2 years ago

Context

We're using logux at https://voiceflow.com/ to enable a consistent multiplayer experience for designing conversations. The frontend is react-redux, with the logux store. Our persistence layer is MongoDB and we update the document from the server based on the action through mongo's query language. This may update deeply nested fields within an object.

Race Condition

I noticed a bug from my repeated testing of starting and stopping the server to see how logux syncs offline actions.

From a high level this is what is happening:

This is all fairly stochastic. TCP should ensure the websocket messages are sent in order, but the server itself might only partially process the syncMessage before processing the resubscribe (logux/subscribe)

This means it is possible for the channel's load function, which should send back the latest state with all the changes, to send back a state without the offline sync messages, or a partial amount. This is especially problematic for us because on the channel's load, we are fetching the state from MongoDB while actions are still being processed and read into the DB in the background.

Solution

This PR ensures that we only resubscribe to a channel AFTER everything is synchronized, instead of at the same time the syncMessage is being processed. This might lead to the slightest delay between reconnecting and reloading the state from the channel's load - but it's worth it to keep data parity.

ai commented 2 years ago

Thanks for well-formed PR with many details and explanations

ai commented 2 years ago

The fix was released in 0.16.