I have a server and a client of that communicate with each other asynchronously using channels. This is all happening in a single process, but client and server are running on different threads.
- The server posts events describing changes.
- The client receives events.
- The client queries the server to get updated data.
In this case the server data is a Vec. It sends events such as "inserted range", "updated range", "deleted range" to describe changes to its data. The client wants to display this Vec as a UI list. It gets an event such as "inserted range" and in response it inserts some items into the list and then queries the server to get the values to display for those items.
This design has problems since the events coming from the server as asynchronous. That means that when the client is processing a given event the ranges referred to by the event may no longer be valid. I'm wondering what my options are for handling those cases.
The options that I see are:
-
Include all item data with each event. So instead of "inserted range" the event would say "inserted these items at this index". The problem with this approach is that you need to copy many items around.
-
Use immutable data (as provided by im.rs) to represent the server data. Anytime it is modified create a snapshot and include that snapshot version # with any event. Then when client needs to query the server for data it can also include the version of that data that it is interested in querying. This will allow the client to gracefully "lag" behind the server while still processing all updates. This seems nice to me at the moment, but it's a pretty big change to model implementation.
-
Something else?
I imagine this problem must come up often... are there some standard approaches with various tradeoffs?