Skip to content

Commit f620e0a

Browse files
committed
Add tests for eventually getting the lock when SkipBlockingWait is set
1 parent dbc76cc commit f620e0a

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

src/main/java/com/amazonaws/services/dynamodbv2/AmazonDynamoDBLockClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ public class AmazonDynamoDBLockClient implements Runnable, Closeable {
233233
private final boolean holdLockOnServiceUnavailable;
234234
private final String ownerName;
235235
private final ConcurrentHashMap<String, LockItem> locks;
236-
private final ConcurrentHashMap<String, LockItem> notMyLocks;
236+
private final ConcurrentHashMap<String, LockItem> notMyLocks = new ConcurrentHashMap<>();
237237
private final ConcurrentHashMap<String, Thread> sessionMonitors;
238238
private final Optional<Thread> backgroundThread;
239239
private final Function<String, ThreadFactory> namedThreadCreator;

src/test/java/com/amazonaws/services/dynamodbv2/AmazonDynamoDBLockClientTest.java

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,10 +443,45 @@ public void acquireLock_whenLockAlreadyExistsAndIsNotReleased_andSkipBlockingWai
443443
.thenReturn(GetItemResponse.builder().item(item).build())
444444
.thenReturn(GetItemResponse.builder().build());
445445
AcquireLockOptions acquireLockOptions = AcquireLockOptions.builder("customer1")
446-
.withShouldSkipBlockingWait(true)
447-
.withDeleteLockOnRelease(false).build();
446+
.withShouldSkipBlockingWait(true)
447+
.withDeleteLockOnRelease(false).build();
448448
client.acquireLock(acquireLockOptions);
449449
}
450+
/*
451+
* Test case for the scenario, where the lock is being held by the first owner and the lock duration has not past
452+
* the lease duration. In this case, We should expect a LockAlreadyOwnedException when shouldSkipBlockingWait is set.
453+
* But if we try again later, we should get the lock.
454+
*/
455+
@Test
456+
public void acquireLock_whenLockAlreadyExistsAndIsNotReleased_andSkipBlockingWait_eventuallyGetsTheLock()
457+
throws InterruptedException {
458+
UUID uuid = setOwnerNameToUuid();
459+
AmazonDynamoDBLockClient client = getLockClient();
460+
Map<String, AttributeValue> item = new HashMap<>(5);
461+
item.put("customer", AttributeValue.builder().s("customer1").build());
462+
item.put("ownerName", AttributeValue.builder().s("foobar").build());
463+
item.put("recordVersionNumber", AttributeValue.builder().s(uuid.toString()).build());
464+
item.put("leaseDuration", AttributeValue.builder().s("100").build());
465+
when(dynamodb.getItem(Mockito.<GetItemRequest>any()))
466+
.thenReturn(GetItemResponse.builder().item(item).build())
467+
.thenReturn(GetItemResponse.builder().build());
468+
AcquireLockOptions acquireLockOptions = AcquireLockOptions.builder("customer1")
469+
.withShouldSkipBlockingWait(true)
470+
.withDeleteLockOnRelease(false).build();
471+
472+
try {
473+
client.acquireLock(acquireLockOptions);
474+
} catch (LockCurrentlyUnavailableException e) {
475+
// This is expected
476+
} catch (RuntimeException e) {
477+
Assert.fail("Expected LockCurrentlyUnavailableException, but got " + e.getClass().getName());
478+
}
479+
480+
// Now wait for the TTL to expire and try to acquire the lock again
481+
Thread.sleep(101);
482+
LockItem lockItem = client.acquireLock(acquireLockOptions);
483+
Assert.assertNotNull("Failed to get lock item, when the lock is not present in the db", lockItem);
484+
}
450485

451486
@Test(expected = IllegalArgumentException.class)
452487
public void sendHeartbeat_whenDeleteDataTrueAndDataNotNull_throwsIllegalArgumentException() {

0 commit comments

Comments
 (0)