3 ms·
Whatever you can mount with a random token is always simpler than checking if Token_ID_A < Token_ID_B which needs a linearizable store. But basically this is ho
by antirez 11y ago
Whatever you can mount with a random token is always simpler than checking if Token_ID_A < Token_ID_B which needs a linearizable store. But basically this is how it works:
You want to modify locked resource X. You set X.currlock = token. Then you read, do whatever you want, and when you write, you "write-if-currlock == token". If another client did X.currlock = somethingelse, the transaction fails.
Edit: note that I noticed some confusion about this. Any other client is free to replace X.currlock even if set to a past value.
- deleted 11y ago[deleted]
- kapitalx 11y agoThe problem with this solution is that if A writes Token_A to resource, and then A dies, then the resource can never be written to again. How do you avoid not needing to time out the 'curr_lock'
- SomeCallMeTim 11y agoNo, when you acquire a lock, you are allowed to write to currlock immediately. It's AFTER you've done whatever processing you need to do that you do a compare-and-set transactional write that verifies no one else has written to currlock between your acquisition and the completion of your task.
- bogdando 11y agoThis pseudo code for random fence tokens should work as well safe as Martin's scenario with incremental IDs in the original article: try token=lock.aquire val=raw(shared, key, token) do_things awar(shared, key, val, token) except fail("Can't do!") finally lock.release Where a shared object has: 1) a key to store a value being changed in the critical section; 2) a currlock to store a random fence token associated with a lock. The raw reads the shared key's value after the currlock was written to the shared object. The awar does an atomic write of the value to the key, only if the currlock has an expected token (i.e. is unchanged). When things go wrong, the do_things may be executed more than once, in parallel, but the key is safe and guaranteed to have no lost updates to its value.
- viraptor 11y agoBut your "write" action is separate from the "X.currlock" operations, right? Doesn't it mean that this can happen? A: X.currlock = Token_ID_A A: resource read A: is X.currlock still Token_ID_A? yes B: X.currlock = Token_ID_B B: resource read B: is X.currlock still Token_ID_B? yes B: resource write A: resource write Is there anything that makes the "write-if-currlock == token" operation atomic?
- tptacek 11y agoYes: it turns out, he's stipulating a single server, in which case this is a trivial feature to build. The problem then is, if you're willing to have that single point of failure, you don't need a lock service at all.