Skip to content

AWS DynamoDB distributed locking client with fencing tokens and FIFO acquisition queuing. Written in TypeScript.

License

Notifications You must be signed in to change notification settings

johnsabath/dynamodb-fifo-lock-client

Repository files navigation

dynamodb-fifo-lock-client

codecov

AWS DynamoDB distributed locking client with fencing tokens and FIFO acquisition queuing.

Inspired by:

Why does this exist?

It all started when I began experimenting with AWS CloudFormation custom resources provisioned by lambda functions. One of those custom resources was wanting to reserve a unique name, which introduced a possible race condition as multiple resources could attempt to reserve the same name at the same time.

This library resolves those race conditions by writing atomically incremented fencing tokens into DynamoDB. In the event of a race condition, locks will be acquired in FIFO order.

Usage

Setup

import { DynamoDbLockClient } from "dynamodb-fifo-lock-client";
import * as DynamoDbClient from "aws-sdk/clients/dynamodb";

const dynamo = new DynamoDbClient();
const dynamoLockClient = new DynamoDbLockClient(dynamo, "my-dynamo-table-name");

Options

const lockOptions = {
  // Arbitrary string identifier
  lockId: "my-lock-identifier",

  // If we acquire the lock, how long does the lease last before expiring?
  // Leases are automatically extended by heartbeats.
  leaseDurationMs: 30000,

  // If we haven't acquired the lock by this point, raise LockAcquisitionTimeout.
  // Optional: defaults to leaseDurationMs
  acquireTimeoutMs: 30000,

  // How often we should reattempt a lock acquisition if it's being held by someone else
  // Optional: defaults to leaseDurationMs / 2
  acquireRetryIntervalMs: 15000,

  // How often heartbeats should be sent to extend the lease on the lock once its been acquired
  // Optional: defaults to leaseDurationMs / 4
  heartbeatIntervalMs: 7500, 
}

Synchronous Lock Holding

Lock will be held until the doWork method returns.

function doWork(): void {
  syncWork();
}

await dynamoLockClient.executeWithLock(lockOptions, doWork);

Asynchronous Lock Holding

Lock will be held until the Promise returned by doAsyncWork resolves or rejects.

async function doAsyncWork(): Promise<void> {
  await asyncWork();
}

await dynamoLockClient.executeWithLock(lockOptions, doAsyncWork);

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

Apache

About

AWS DynamoDB distributed locking client with fencing tokens and FIFO acquisition queuing. Written in TypeScript.

Topics

Resources

License

Stars

Watchers

Forks