awslabs / amazon-dynamodb-lock-client

The AmazonDynamoDBLockClient is a general purpose distributed locking library built on top of DynamoDB. It supports both coarse-grained and fine-grained locking.
Other
472 stars 85 forks source link

Local lockItem does not get updated when sendHeartbeat sends new data #54

Closed lcabancla closed 3 years ago

lcabancla commented 3 years ago

When the client holds the lock and sendHeartbeat(options) is called with new data, the dynamodb record gets updated but the local lockItem does not. This is a problem when the local lockItem is retrieved via getLock(). Calling getData() on the lockItem will yield the old data.

See test case below:

    @Test
    public void testSendHeartbeatChangeData() throws IOException, LockNotGrantedException, InterruptedException {

        final String data1 = new String("testSendHeartbeatChangeData1" + SECURE_RANDOM.nextDouble());
        final String data2 = new String("testSendHeartbeatChangeData2" + SECURE_RANDOM.nextDouble());

        final LockItem item = this.lockClient
            .acquireLock(AcquireLockOptions.builder("testKey1").withData(ByteBuffer.wrap(data1.getBytes()))
                    .withDeleteLockOnRelease(true).withReplaceData(true).build());
        assertEquals(data1, new String(item.getData().get().array()));

        assertEquals(data1, byteBufferToString(this.lockClient.getLockFromDynamoDB(
                GetLockOptions.builder("testKey1").build()).get().getData().get()));
        this.lockClient.sendHeartbeat(SendHeartbeatOptions.builder(item).withData(ByteBuffer.wrap(data2.getBytes())).build());
        assertEquals(data2, byteBufferToString(this.lockClient.getLockFromDynamoDB(
                GetLockOptions.builder("testKey1").build()).get().getData().get()));

        // This will fail since the lockItem returned by getLock() is not updated.
        assertEquals(data2, byteBufferToString(this.lockClient.getLock(
            "testKey1", Optional.empty()).get().getData().get()));
        item.close();
    }