Skip to content
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

Records in dynamo table not deleted #3

Open
weare8 opened this issue Apr 26, 2021 · 0 comments
Open

Records in dynamo table not deleted #3

weare8 opened this issue Apr 26, 2021 · 0 comments

Comments

@weare8
Copy link

weare8 commented Apr 26, 2021

Thank you for this lib!

I am using this in AWS Lambda Function and I noticed that records in dynamodb are not deleted. I tried to run the job that processes records and using the lock couple of times but not clear eventually. Shouldn't the lib check the leaseDuration for example the next time a process tries to lock a resource key and if expired to delete and create a new record with new recordVersionNumber GUID?

Wouldn't leaseDuration help to make it a TTL attribute so that the record will be deleted by dynamodb automatically when the expiration timestamp reached?

Trying to understand better how to use the library, check below the code I am using when a caller is trying to acquire a resource lock key.

A DynamoDbLockClientDistributedLockService concrete implementation service used by the caller.

public class DynamoDbLockClientDistributedLockService : IDistributedLockService
    {
        private readonly IAmazonDynamoDBLockClient _dynamoDbLockClient;

        public DynamoDbLockClientDistributedLockService(IAmazonDynamoDBLockClient dynamoDbLockClient)
        {
            _dynamoDbLockClient = dynamoDbLockClient;
        }
        
        public async Task<IDistributedLock> CreateLockAsync(string resource, TimeSpan expiration)
        {
            try
            {
                var lockItem = await _dynamoDbLockClient.TryAcquireLockAsync(new AcquireLockOptions(resource)
                {
                    DeleteLockOnRelease = true,
                    ShouldSkipBlockingWait = true
                });
            
                return lockItem.IsNotNull()
                    ? (IDistributedLock) new DynamoDbLockClientDistributedLock(
                        lockItem,
                        () => _dynamoDbLockClient.ReleaseLock(lockItem))
                    : (IDistributedLock) new DynamoDbEmptyDistributedLock(resource);
            }
            catch (LockCurrentlyUnavailableException)
            {
                return (IDistributedLock) new DynamoDbEmptyDistributedLock(resource);
            }
        }

        public void Dispose()
        {
            _dynamoDbLockClient.Close();
        }
    }

The DynamoDbLockClientDistributedLock. I still have a a bit of problem trying to figure out if IsAcquired flag is properly assigned based on !_lockItem.IsReleased(), thoughts?

public class DynamoDbLockClientDistributedLock : IDistributedLock
    {
        private readonly LockItem _lockItem;
        private readonly Action _disposeAction;

        public string Resource { get; }
        public string LockId { get; }
        public bool IsAcquired { get; }
        
        public DynamoDbLockClientDistributedLock(
                LockItem lockItem,
                Action disposeAction)
        {
            _lockItem = lockItem;
            _disposeAction = disposeAction;
            Resource = lockItem.PartitionKey;
            LockId = lockItem.RecordVersionNumber;
            IsAcquired = true;
        }
        
        public void Dispose()
        {
            _disposeAction?.Invoke();
            _lockItem.Close();
        }
    }

DI helper extension method.

public static IServiceCollection AddDynamoDbLockClientDistributedLockService(
            this IServiceCollection services,
            string tableName,
            bool createHeartbeatBackgroundThread = true,
            TimeUnit timeUnit = null,
            long leaseDuration = 10,
            long heartbeatPeriod = 5)
        {
            services.AddTransient<IAmazonDynamoDBLockClient>(provider =>
                new AmazonDynamoDBLockClient(
                    new AmazonDynamoDBLockClientOptions(
                        provider.GetRequiredService<IAmazonDynamoDB>(),
                        tableName)
                    {
                        TimeUnit = timeUnit ?? TimeUnit.SECONDS,
                        LeaseDuration = leaseDuration,
                        HeartbeatPeriod = heartbeatPeriod,
                        CreateHeartbeatBackgroundThread = createHeartbeatBackgroundThread
                    }));
            
            services.AddTransient<IDistributedLockService>(sp =>
                new DynamoDbLockClientDistributedLockService(sp.GetRequiredService<IAmazonDynamoDBLockClient>()));

            return services;
        }


In lambda API function usage.
services.AddDynamoDbLockClientDistributedLockService(appSettings.DistributedLockDynamodbTable);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant