Optimistic UI: How to handle local mutations while the Method is pending?


#1

I have a few scenarios in my site where I would like to use Optimistic UI, but I would like to allow the user to continue locally editing while the changes are round-tripping as described at https://guide.meteor.com/methods.html#call-lifecycle. The very simplest use case is a numeric slider that is synced via meteor between a number of clients and a reasonable latency of ~200ms between server and clients.

What is the best design practice to ‘ignore’ an update from the server because it has been superseded by a local change that happened while DDP was doing it’s thing?.. For example… I move the slider to ‘5’, then to ‘7’… but it sometimes moves back to 5 because the ‘5’ value just came back in from the server and the update stomped on the local (newer) 7… There are a few outcomes depending on these races of user vs DDP, but it is often janky and sometimes endos up persisting the non-latest value… So to be clear, the base problem can be shown with just one client and one server… but the solution must also handle the multi-client solution (and let’s assume I am happy with a simple policy like last-writer-wins at the server)

I can solve it by a data layer that double-buffers my changes and disregards inbound updates that I had tagged as coming from my client… But it feels like this should be a core mechanism in the Optimistic UI design - or there should be clear advice to not alter the data in MiniMongo while there are pending Method responses from the server.

Ideally I’d have a nice flag on the Method call to say “local minimongo data must not be replaced by incoming DDP data that originated from this client”… but I haven’t been able to find any discussion of such a topic in the Meteor forums or docs.

Thanks

David


#2

Any help folks?

I have looked also at https://docs.meteor.com/api/methods.html#Meteor-apply which offers the onResultReceived() callback:

onResultReceived()
(Client only) This callback is invoked with the error or result of the method (just like asyncCallback) as soon as the error or result is available. The local cache may not yet reflect the writes performed by the method.

… this would be the ideal opportunity to decide whether to abandon the local update (note that I don’t need to handle the pending-create scenario here so _id isn’t a special issue). However, I see no way to prevent meteor from overwriting the more recent copy in minimongo…

Today I have an extra buffer layer for these scenarios but it creates a lot of complexity for what should be a common case - allowing edits to continue while a save is pending.

Is this just an ‘undesigned area’ of Meteor?

David.