Reset DynamoDb lockItem when HeartBeat fails

Related to https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis/issues/148

If a `DynamoDbLock` has been locked before,
it contains a `lockItem` indicating that we can send a heart-beat
the next tine when we would like to re-lock again instead of calling
regular lock and fail because the lock record exists already.
On the other hand the heart-beat can fail by itself for many reasons
including the case when record in DB was removed somehow.

* Change the `DynamoDbLock.doLock()` logic to catch `sendHeartBeat()`
exception and reset local state to let it to try to lock again with
the regular `tryAcquireLock()` API
This commit is contained in:
Artem Bilan
2021-01-06 17:15:10 -05:00
parent 526353c9d8
commit 6b0933c7b7

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2018-2020 the original author or authors.
* Copyright 2018-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -526,12 +526,19 @@ public class DynamoDbLockRegistry implements ExpirableLockRegistry, Initializing
}
private boolean doLock() throws InterruptedException {
boolean acquired;
boolean acquired = false;
if (this.lockItem != null) {
this.lockItem.sendHeartBeat();
acquired = true;
try {
this.lockItem.sendHeartBeat();
acquired = true;
}
catch (Exception e) {
// May be no lock record in the DB - discard local holder and try to lock again
this.lockItem = null;
}
}
else {
if (this.lockItem == null) {
this.lockItem = DynamoDbLockRegistry.this.dynamoDBLockClient
.tryAcquireLock(this.acquireLockOptionsBuilder.build()).orElse(null);