File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -130,6 +130,13 @@ export class DatabaseStore implements LockStore {
130130 await this . #connection. table ( this . #tableName) . where ( 'key' , key ) . where ( 'owner' , owner ) . delete ( )
131131 }
132132
133+ /**
134+ * Force delete a lock
135+ */
136+ async forceRelease ( key : string ) {
137+ await this . #connection. table ( this . #tableName) . where ( 'key' , key ) . delete ( )
138+ }
139+
133140 /**
134141 * Check if a lock exists
135142 */
Original file line number Diff line number Diff line change @@ -114,9 +114,25 @@ export class DynamoDBStore implements LockStore {
114114 * Delete a lock
115115 */
116116 async delete ( key : string , owner : string ) {
117- const currentOwner = await this . #getCurrentOwner( key )
118- if ( currentOwner !== owner ) throw new E_RELEASE_NOT_OWNED ( )
117+ const command = new DeleteItemCommand ( {
118+ TableName : this . #tableName,
119+ Key : { key : { S : key } } ,
120+ ConditionExpression : '#owner = :owner' ,
121+ ExpressionAttributeNames : { '#owner' : 'owner' } ,
122+ ExpressionAttributeValues : { ':owner' : { S : owner } } ,
123+ } )
124+
125+ try {
126+ await this . #client. send ( command )
127+ } catch ( err ) {
128+ throw new E_RELEASE_NOT_OWNED ( )
129+ }
130+ }
119131
132+ /**
133+ * Force delete a lock
134+ */
135+ async forceRelease ( key : string ) {
120136 const command = new DeleteItemCommand ( {
121137 TableName : this . #tableName,
122138 Key : { key : { S : key } } ,
Original file line number Diff line number Diff line change @@ -80,6 +80,16 @@ export class MemoryStore implements LockStore {
8080 mutex . releaser ( )
8181 }
8282
83+ /**
84+ * Force delete a lock
85+ */
86+ async forceRelease ( key : string ) {
87+ const lock = this . #locks. get ( key )
88+ if ( ! lock ) return
89+
90+ lock . releaser ?.( )
91+ }
92+
8393 /**
8494 * Check if a lock exists
8595 */
Original file line number Diff line number Diff line change @@ -44,6 +44,13 @@ export class RedisStore implements LockStore {
4444 if ( result === 0 ) throw new E_RELEASE_NOT_OWNED ( )
4545 }
4646
47+ /**
48+ * Force delete a lock
49+ */
50+ async forceRelease ( key : string ) {
51+ await this . #connection. del ( key )
52+ }
53+
4754 /**
4855 * Check if a lock exists
4956 */
Original file line number Diff line number Diff line change @@ -75,13 +75,27 @@ export class Lock {
7575 }
7676 }
7777
78+ /**
79+ * Force release the lock
80+ */
81+ async forceRelease ( ) {
82+ await this . lockStore . forceRelease ( this . key )
83+ }
84+
7885 /**
7986 * Release the lock
8087 */
8188 async release ( ) {
8289 await this . lockStore . delete ( this . key , this . #owner)
8390 }
8491
92+ /**
93+ * Returns true if the lock is expired
94+ */
95+ async isExpired ( ) {
96+ return false
97+ }
98+
8599 /**
86100 * Returns true if the lock is currently locked
87101 */
Original file line number Diff line number Diff line change @@ -59,6 +59,11 @@ export interface LockStore {
5959 */
6060 delete ( key : string , owner : string ) : Promise < void >
6161
62+ /**
63+ * Force delete the lock from the store
64+ */
65+ forceRelease ( key : string ) : Promise < void >
66+
6267 /**
6368 * Check if the lock exists
6469 */
Original file line number Diff line number Diff line change @@ -292,4 +292,16 @@ export function registerStoreTestSuite<T extends { new (options: any): LockStore
292292
293293 assert . isTrue ( await lock . isLocked ( ) )
294294 } )
295+
296+ test ( 'forceRelease allows to release a lock that is not acquired by you' , async ( { assert } ) => {
297+ const provider = new LockFactory ( new store ( config ) )
298+ const lock = provider . createLock ( 'foo' )
299+ const lock2 = provider . createLock ( 'foo' )
300+
301+ await lock . acquire ( )
302+
303+ await lock2 . forceRelease ( )
304+
305+ assert . isFalse ( await lock . isLocked ( ) )
306+ } )
295307}
Original file line number Diff line number Diff line change @@ -13,6 +13,10 @@ export class NullStore implements LockStore {
1313 return true
1414 }
1515
16+ async forceRelease ( _key : string ) : Promise < void > {
17+ return
18+ }
19+
1620 async extend ( _key : string , _duration : Duration ) : Promise < void > {
1721 return
1822 }
You can’t perform that action at this time.
0 commit comments