You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I've been working on an alternative in Go, since I needed to support expiration, which gcslock does not support.
Your article was very helpful, thanks.
There are few places where I've diverged from your implementation, which you may (or may not) find useful.
Feel free to close the issue at your discretion.
I use generations (rather than metagenerations) to "refresh" the lock. I do this for 2 reasons: because the XML API (which I use) does not allow me to update just the metadata, and because I optionally allow the user to attach data to the lock (and update/inspect it - I use this to report progress of the running operation).
However, there is an advantage to this. The generation of an object is less predictable than its metageneration. Given that the metageneration is so predictable (sequential), I'm actually not convinced it is safe to delete the lock based on just the metageneration.
I do not retry using PUT (i.e. "create file"). Because of object immutability locking and unlocking a mutex is subject to the "once-per-second" quota. Contention from repeatedly trying to acquire the lock makes it harder to release it. So, after trying to optimistically acquire the lock, I immediately switch to using HEAD to test the lock, so I don't contend with DELETE, and only PUT once the lock is gone or expired. HEAD is also approximately 10 times cheaper than PUT, so it really is better to loop on HEAD.
I check for expiration based only on server time. I store a TTL in seconds in the metadata. I then use server date, last modification date of the lock and the TTL to determine if a lock is expired. Thus, local clock is one less thing to worry about.
The text was updated successfully, but these errors were encountered:
From my side, I've made a simple Python implementation: https://github.com/orsinium-labs/dimutex
It doesn't have healthcheck and leaves retries to the caller but otherwise should be about the same. I based it not on the Ruby implementation but on the article.
I've been working on an alternative in Go, since I needed to support expiration, which
gcslock
does not support.Your article was very helpful, thanks.
There are few places where I've diverged from your implementation, which you may (or may not) find useful.
Feel free to close the issue at your discretion.
I use generations (rather than metagenerations) to "refresh" the lock. I do this for 2 reasons: because the XML API (which I use) does not allow me to update just the metadata, and because I optionally allow the user to attach data to the lock (and update/inspect it - I use this to report progress of the running operation).
However, there is an advantage to this. The generation of an object is less predictable than its metageneration. Given that the metageneration is so predictable (sequential), I'm actually not convinced it is safe to delete the lock based on just the metageneration.
I do not retry using
PUT
(i.e. "create file"). Because of object immutability locking and unlocking a mutex is subject to the "once-per-second" quota. Contention from repeatedly trying to acquire the lock makes it harder to release it. So, after trying to optimistically acquire the lock, I immediately switch to usingHEAD
to test the lock, so I don't contend withDELETE
, and onlyPUT
once the lock is gone or expired.HEAD
is also approximately 10 times cheaper thanPUT
, so it really is better to loop onHEAD
.I check for expiration based only on server time. I store a TTL in seconds in the metadata. I then use server date, last modification date of the lock and the TTL to determine if a lock is expired. Thus, local clock is one less thing to worry about.
The text was updated successfully, but these errors were encountered: