Skip to content

Commit

Permalink
feat: added "readLock" option to aquireLock
Browse files Browse the repository at this point in the history
  • Loading branch information
simlu committed Dec 6, 2018
1 parent 00f0e10 commit 7a66271
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 5 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,11 @@ Creates a "fail closed" client that acquires "fail closed" locks. If process cra

Creates a "fail open" client that acquires "fail open" locks. If process crashes and lock is not released, lock will eventually expire after `leaseDurationMs` from last heartbeat sent (if any). This means that if process acquires a lock, goes to sleep for more than `leaseDurationMs`, and then wakes up assuming it still has a lock, then it can perform an operation ignoring other processes that may assume they have a lock on the operation.

### client.acquireLock(id, callback)
### client.acquireLock(id, [opt], callback)

* `id`: _String\|Buffer\|Number_ Unique identifier for the lock. The type must correspond to lock table's partition key type.
* `opt`: _Object_ Options, optionally containing
* readLock: _Boolean_ Indicate if this is a read lock.
* `callback`: _Function_ `(error, lock) => {}`
* `error`: _Error_ Error, if any.
* `lock`: _DynamoDBLockClient.Lock_ Successfully acquired lock object. Lock object is an instance of `EventEmitter`. If the `lock` is acquired via a fail open `client` configured to heartbeat, then the returned `lock` may emit an `error` event if a `heartbeat` operation fails.
Expand Down
28 changes: 24 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,13 @@ FailClosed.schema =
config: require("./schema/failClosedConfig.js")
};

FailClosed.prototype.acquireLock = function(id, callback)
FailClosed.prototype.acquireLock = function(id, opts, callback)
{
if (callback === undefined)
{
callback = opts;
opts = {};
}
const self = this;
const workflow = new events.EventEmitter();
setImmediate(() => workflow.emit("start",
Expand All @@ -61,14 +66,19 @@ FailClosed.prototype.acquireLock = function(id, callback)
Item:
{
owner: dataBag.owner,
guid: dataBag.guid
guid: dataBag.guid,
readLock: opts.readLock === true ? '1' : '0'
},
ConditionExpression: "attribute_not_exists(#partitionKey)",
ExpressionAttributeNames:
{
"#partitionKey": self._partitionKey
}
};
if (opts.readLock === true) {
params.FilterExpression = 'readLock <> :true';
params.ExpressionAttributeNames['true'] = '1';
}
params.Item[self._partitionKey] = dataBag.id;
self._dynamodb.put(params, (error, data) =>
{
Expand Down Expand Up @@ -147,8 +157,13 @@ FailOpen.schema =
config: require("./schema/failOpenConfig.js")
};

FailOpen.prototype.acquireLock = function(id, callback)
FailOpen.prototype.acquireLock = function(id, opts, callback)
{
if (callback === undefined)
{
callback = opts;
opts = {};
}
const self = this;
const workflow = new events.EventEmitter();
setImmediate(() => workflow.emit("start",
Expand Down Expand Up @@ -212,14 +227,19 @@ FailOpen.prototype.acquireLock = function(id, callback)
fencingToken: dataBag.fencingToken,
leaseDurationMs: self._leaseDurationMs,
owner: dataBag.owner,
guid: dataBag.guid
guid: dataBag.guid,
readLock: opts.readLock === true ? '1' : '0'
},
ConditionExpression: "attribute_not_exists(#partitionKey)",
ExpressionAttributeNames:
{
"#partitionKey": self._partitionKey
}
};
if (opts.readLock === true) {
params.FilterExpression = 'readLock <> :true';
params.ExpressionAttributeNames['true'] = '1';
}
if (self._trustLocalTime)
{
params.Item.lockAcquiredTimeUnixMs = (new Date()).getTime();
Expand Down

0 comments on commit 7a66271

Please sign in to comment.