kinto.js icon indicating copy to clipboard operation
kinto.js copied to clipboard

Prevent concurrent conflicting transactions by incrementing a local revision number

Open n1k0 opened this issue 10 years ago • 1 comments

Use case

  • We have an edition form for a given record in state A, and we don't have submitted the form yet;
  • Concurrently, a worker modifies this record and turns it into state B;
  • We now submit the form, which overrides what's just been updated by the worker, which is the problem we're trying to solve here.

Flow

  • Form loads existing record with local_rev==1 (eg. that value is contained in some hidden input field, CSRF-token protection style or any other way, eg in React component's props);
  • Worker loads existing record with local_rev==1;
  • Worker updates existing record, persistence layer bumps local_rev to 2;
  • Form is submitted, data are sent to the local persistence layer adapter;
  • Persistence layer knows that local_rev for that record is 2, but form has just sent local_rev==1: an error is raised.
Notes
  • Do not synchronize the local revision number to the server;
  • Each time we synchronize a remote record from the server to the local database, we reset its local revision number;
  • Any synchronized remote records should bump matching local equivalent record's local_rev number.

We'd love hearing thoughts and feedback from @daleharvey, @leplatrem, @Natim, @michielbdejong

n1k0 avatar Jun 25 '15 19:06 n1k0

Makes sense! Already needed for when a user has the same app open in multiple browser tabs, but becomes even more important when using workers. It's a pity that IndexedDB (unlike localStorage) doesn't implement something like StorageEvent, which would have been ideal for this, since it also gives a way to update the UI as soon as a worker (or other browser tab) changes something. In the absence of that, local revision numbers seem like a good second option.

michielbdejong avatar Sep 07 '15 12:09 michielbdejong