-
Notifications
You must be signed in to change notification settings - Fork 90
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: ShouldSkipBlockingWait should still acquire a dead lock if tried for longer than TTL #99
Fix: ShouldSkipBlockingWait should still acquire a dead lock if tried for longer than TTL #99
Conversation
if (notMyLocks.containsKey(id) && | ||
notMyLocks.get(id).getRecordVersionNumber() | ||
.equals(existingLock.get().getRecordVersionNumber())) { | ||
itReallyIsExpired = oldCopy.isExpired(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this approach works, with the following downsides:
- The very first acquire call on an existing lock will throw, always. There should be a separate check for
notMyLocks.containsKey(id)
. - Ownership changes for expired locks will take twice as long since
oldCopy.isExpired()
will return true only afterlease_duration
secs. Then the rest of the acquire will take anotherlease_duration
seconds.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For item 2, maybe try calling upsertAndMonitorExpiredLock()
immediately when it expired?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Item 2 fixed in latest push.
Item 1: the first call on an existing lock
- there is no way to know how long it has been acquired
- the only possible options is to return that the lock is held
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is another option which is to block on the first call. If it returned false, then the following calls should fail fast.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the user wants to block to wait for a lease, they should not set: ShouldSkipBlockingWait
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am fine with that approach as long as it is made clear (in the README?) that a return value of false does not only mean the lease is held. It may also mean that the client is, with the information that it has, not able to determine whether the lease is owned or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably outside the scope of this PR, but instead of using the skipBlockingWait
property there can be two acquire methods - one for blocking and another for non-blocking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #102 for updates to the README.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The message here needs to be updated as well since all acquires during the first LEASE_DURATION seconds will fail for an existing, expired lock.
src/main/java/com/amazonaws/services/dynamodbv2/AmazonDynamoDBLockClient.java
Show resolved
Hide resolved
@@ -233,6 +233,7 @@ public class AmazonDynamoDBLockClient implements Runnable, Closeable { | |||
private final boolean holdLockOnServiceUnavailable; | |||
private final String ownerName; | |||
private final ConcurrentHashMap<String, LockItem> locks; | |||
private final ConcurrentHashMap<String, LockItem> notMyLocks; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to purge entries from the map eventually?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If an app takes out leases with constantly changing names, then this can grow unboundedly.
If the lease names that it attempts to acquire are limited, then not.
949cb9b
to
d592483
Compare
d592483
to
dbc76cc
Compare
5fde650
to
f620e0a
Compare
Issue 44
Description of changes:
When a lock is not acquired because the
ShouldSkipBlockingWait
has been set, we cache the data pulled from DynamoDB. In future calls, if the recordVersion matches the cached version, we check is the cached version to see if it is expired rather than the freshly pulled copy, as the freshly pulled copy will never be expired.