Skip to content
This repository was archived by the owner on Nov 10, 2025. It is now read-only.

Commit a29d46c

Browse files
committed
GH-219: Fix DynamoDbLockReg for skip blocking
Fixes #219 Turns out the `AmazonDynamoDBLockClient` doesn't have a proper logic to determine correct `lookupTime` and if we want to skip blocking waits, the item is always treated as not expired because just obtained item from DB is updated to the current time for its `lookupTime` property * Remove the logic in the `DynamoDbLockRegistry` setting `withShouldSkipBlockingWait(true)` **Cherry-pick to `2.5.x`** # Conflicts: # src/test/java/org/springframework/integration/aws/lock/DynamoDbLockRegistryTests.java
1 parent 6afbac4 commit a29d46c

File tree

2 files changed

+48
-11
lines changed

2 files changed

+48
-11
lines changed

src/main/java/org/springframework/integration/aws/lock/DynamoDbLockRegistry.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018-2022 the original author or authors.
2+
* Copyright 2018-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -451,8 +451,7 @@ public void lock() {
451451
private void setupDefaultAcquireLockOptionsBuilder() {
452452
this.acquireLockOptionsBuilder
453453
.withAdditionalTimeToWaitForLock(Long.MAX_VALUE - DynamoDbLockRegistry.this.leaseDuration)
454-
.withRefreshPeriod(DynamoDbLockRegistry.this.refreshPeriod)
455-
.withShouldSkipBlockingWait(false);
454+
.withRefreshPeriod(DynamoDbLockRegistry.this.refreshPeriod);
456455
}
457456

458457
@Override
@@ -506,13 +505,7 @@ public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
506505
long additionalTimeToWait = Math
507506
.max(TimeUnit.MILLISECONDS.convert(time, unit) - System.currentTimeMillis() + start, 0L);
508507

509-
this.acquireLockOptionsBuilder.withAdditionalTimeToWaitForLock(additionalTimeToWait)
510-
.withRefreshPeriod(DynamoDbLockRegistry.this.refreshPeriod)
511-
.withShouldSkipBlockingWait(false);
512-
513-
if (additionalTimeToWait == 0) {
514-
this.acquireLockOptionsBuilder.withShouldSkipBlockingWait(true);
515-
}
508+
this.acquireLockOptionsBuilder.withAdditionalTimeToWaitForLock(additionalTimeToWait);
516509

517510
boolean acquired = false;
518511
try {

src/test/java/org/springframework/integration/aws/lock/DynamoDbLockRegistryTests.java

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2018-2020 the original author or authors.
2+
* Copyright 2018-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,9 @@
1818

1919
import static org.assertj.core.api.Assertions.assertThat;
2020

21+
22+
import java.lang.reflect.Method;
23+
2124
import java.util.Map;
2225
import java.util.concurrent.CountDownLatch;
2326
import java.util.concurrent.Future;
@@ -41,10 +44,15 @@
4144
import org.springframework.integration.test.util.TestUtils;
4245
import org.springframework.test.annotation.DirtiesContext;
4346
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
47+
import org.springframework.util.ReflectionUtils;
4448

4549
import cloud.localstack.docker.LocalstackDockerExtension;
4650
import cloud.localstack.docker.annotation.LocalstackDockerProperties;
51+
import com.amazonaws.services.dynamodbv2.AcquireLockOptions;
4752
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBAsync;
53+
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBLockClient;
54+
import com.amazonaws.services.dynamodbv2.AmazonDynamoDBLockClientOptions;
55+
import com.amazonaws.services.dynamodbv2.LockItem;
4856
import com.amazonaws.services.dynamodbv2.model.DescribeTableRequest;
4957
import com.amazonaws.waiters.FixedDelayStrategy;
5058
import com.amazonaws.waiters.MaxAttemptsRetryStrategy;
@@ -328,6 +336,42 @@ void testTwoThreadsWrongOneUnlocks() throws Exception {
328336
assertThat(((Exception) imse).getMessage()).contains("You do not own");
329337
}
330338

339+
@Test
340+
void abandonedLock() throws Exception {
341+
Method awaitForActiveMethod = ReflectionUtils.findMethod(DynamoDbLockRegistry.class, "awaitForActive");
342+
ReflectionUtils.makeAccessible(awaitForActiveMethod);
343+
ReflectionUtils.invokeMethod(awaitForActiveMethod, this.dynamoDbLockRegistry);
344+
345+
AmazonDynamoDBLockClientOptions lockClientOptions =
346+
AmazonDynamoDBLockClientOptions.builder(DYNAMO_DB, DynamoDbLockRegistry.DEFAULT_TABLE_NAME)
347+
.withPartitionKeyName(DynamoDbLockRegistry.DEFAULT_PARTITION_KEY_NAME)
348+
.withSortKeyName(DynamoDbLockRegistry.DEFAULT_SORT_KEY_NAME)
349+
.withCreateHeartbeatBackgroundThread(false)
350+
.withLeaseDuration(2L)
351+
.build();
352+
AmazonDynamoDBLockClient lockClient = new AmazonDynamoDBLockClient(lockClientOptions);
353+
354+
AcquireLockOptions lockOptions =
355+
AcquireLockOptions.builder("foo")
356+
.withReplaceData(false)
357+
.withSortKey(DynamoDbLockRegistry.DEFAULT_SORT_KEY)
358+
.build();
359+
360+
LockItem lockItem = lockClient.acquireLock(lockOptions);
361+
assertThat(lockItem).isNotNull();
362+
363+
lockClient.close();
364+
365+
Lock lock = this.dynamoDbLockRegistry.obtain("foo");
366+
int n = 0;
367+
while (!lock.tryLock() && n++ < 100) {
368+
Thread.sleep(100);
369+
}
370+
371+
assertThat(n).isLessThan(100);
372+
lock.unlock();
373+
}
374+
331375
@Configuration
332376
public static class ContextConfiguration {
333377

0 commit comments

Comments
 (0)