@bitblit/ratchet-aws
Version:
Common tools for use with AWS browser and node
71 lines • 2.85 kB
JavaScript
import { RequireRatchet } from '@bitblit/ratchet-common/lang/require-ratchet';
import { Logger } from '@bitblit/ratchet-common/logger/logger';
import { StringRatchet } from '@bitblit/ratchet-common/lang/string-ratchet';
import { PutCommand } from '@aws-sdk/lib-dynamodb';
import { ConditionalCheckFailedException, ReturnConsumedCapacity } from '@aws-sdk/client-dynamodb';
export class DynamoDbSyncLock {
ratchet;
tableName;
constructor(ratchet, tableName) {
this.ratchet = ratchet;
this.tableName = tableName;
RequireRatchet.notNullOrUndefined(ratchet, 'ratchet');
RequireRatchet.notNullOrUndefined(StringRatchet.trimToNull(this.tableName), 'tableName');
}
async acquireLock(lockKey, expirationSeconds = 30) {
let rval = false;
if (!!lockKey && !!expirationSeconds) {
const nowSeconds = Math.floor(new Date().getTime() / 1000);
const row = {
lockingKey: lockKey,
timestamp: nowSeconds,
expires: nowSeconds + expirationSeconds,
};
const params = {
Item: row,
ReturnConsumedCapacity: ReturnConsumedCapacity.TOTAL,
TableName: this.tableName,
ConditionExpression: 'attribute_not_exists(lockingKey)',
};
try {
const _pio = await this.ratchet.getDDB().send(new PutCommand(params));
rval = true;
}
catch (err) {
if (err instanceof ConditionalCheckFailedException) {
Logger.silly('Unable to acquire lock on %s', lockKey);
}
}
}
return rval;
}
async releaseLock(lockKey) {
if (StringRatchet.trimToNull(lockKey)) {
try {
const dio = await this.ratchet.simpleDelete(this.tableName, { lockingKey: lockKey });
Logger.silly('Released lock %s : %s', lockKey, dio);
}
catch (err) {
Logger.warn('Failed to release lock key : %s : %s', lockKey, err, err);
}
}
}
async clearExpiredSyncLocks() {
const nowSeconds = Math.floor(new Date().getTime() / 1000);
const scan = {
TableName: this.tableName,
FilterExpression: 'expires < :now',
ExpressionAttributeValues: {
':now': nowSeconds,
},
};
const vals = await this.ratchet.fullyExecuteScan(scan);
const keysOnly = vals.map((v) => {
const next = { lockingKey: v['lockingKey'] };
return next;
});
const removed = await this.ratchet.deleteAllInBatches(this.tableName, keysOnly, 25);
return removed;
}
}
//# sourceMappingURL=dynamo-db-sync-lock.js.map