Skip to content

Commit 41bfae1

Browse files
committed
feat!: rename tryAcquire to acquireImmediately + add runImmediately method
1 parent 6e5e864 commit 41bfae1

3 files changed

Lines changed: 60 additions & 10 deletions

File tree

docs/content/docs/api.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,34 @@ Acquire the lock, run the callback, and release the lock.
4343

4444
```ts
4545
const lock = verrou.createLock('key')
46-
await lock.run({ retry: { timeout: '1000ms' } }, async () => {
46+
await lock.run(() => {
47+
// do something
48+
})
49+
```
50+
51+
### `runImmediately`
52+
53+
Same as `run`, but try to acquire the lock immediately ( without retrying ). If the lock is already acquired, it will throws a `E_LOCK_ALREADY_ACQUIRED` error.
54+
55+
```ts
56+
const lock = verrou.createLock('key')
57+
await lock.runImmediately(async () => {
4758
// do something
4859
})
4960
```
5061

5162
Accept an optional object with the same properties as `acquire`.
5263

53-
### `tryAcquire`
64+
### `acquireImmediately`
5465

55-
Try to acquire the lock immediately. If the lock is already acquired, it will throws a `E_LOCK_ALREADY_ACQUIRED` error.
66+
Try to acquire the lock immediately ( without retrying ). If the lock is already acquired, it will throws a `E_LOCK_ALREADY_ACQUIRED` error.
5667

5768
```ts
5869
import { errors } from '@verrou/core'
5970

6071
const lock = verrou.createLock('key')
6172
try {
62-
await lock.tryAcquire()
73+
await lock.acquireImmediately()
6374
} catch (err) {
6475
if (err instanceof E_LOCK_ALREADY_ACQUIRED) {
6576

packages/verrou/src/lock.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,12 @@ export class Lock {
108108
/**
109109
* Try to acquire the lock immediately or throw an error
110110
*/
111-
async tryAcquire() {
111+
async acquireImmediately() {
112112
const result = await this.#lockStore.save(this.#key, this.#owner, this.#ttl)
113113
if (!result) throw new E_LOCK_ALREADY_ACQUIRED()
114114
this.#expirationTime = this.#ttl ? Date.now() + this.#ttl : null
115115

116-
this.#config.logger.debug({ key: this.#key }, 'Lock acquired with tryAcquire()')
116+
this.#config.logger.debug({ key: this.#key }, 'Lock acquired with acquireImmediately()')
117117
}
118118

119119
/**
@@ -130,6 +130,19 @@ export class Lock {
130130
}
131131
}
132132

133+
/**
134+
* Same as `run` but try to acquire the lock immediately
135+
* Or throw an error if the lock is already acquired
136+
*/
137+
async runImmediately<T>(callback: () => Promise<T>): Promise<T> {
138+
try {
139+
await this.acquireImmediately()
140+
return await callback()
141+
} finally {
142+
await this.release()
143+
}
144+
}
145+
133146
/**
134147
* Force release the lock
135148
*/

packages/verrou/tests/lock.spec.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -335,20 +335,20 @@ test.group('Lock', () => {
335335
assert.isAbove(elapsed, 500)
336336
})
337337

338-
test('tryAcquire works', async ({ assert }) => {
338+
test('acquireImmediately works', async ({ assert }) => {
339339
const store = new MemoryStore()
340340
const lock = new Lock('foo', store, defaultOptions, undefined, 1000)
341341

342342
assert.deepEqual(await lock.isLocked(), false)
343343

344-
await lock.tryAcquire()
344+
await lock.acquireImmediately()
345345

346346
assert.deepEqual(await lock.isLocked(), true)
347347
assert.deepEqual(lock.getRemainingTime(), 1000)
348348
assert.deepEqual(lock.isExpired(), false)
349349
})
350350

351-
test('tryAcquires throws timeout error when lock is not available', async ({ assert }) => {
351+
test('acquireImmediately throws timeout error when lock is not available', async ({ assert }) => {
352352
class FakeStore extends NullStore {
353353
async save(_key: string) {
354354
return false
@@ -358,6 +358,32 @@ test.group('Lock', () => {
358358
const lock = new Lock('foo', new FakeStore(), defaultOptions)
359359

360360
// @ts-ignore
361-
await assert.rejects(() => lock.tryAcquire(), E_LOCK_ALREADY_ACQUIRED.message)
361+
await assert.rejects(() => lock.acquireImmediately(), E_LOCK_ALREADY_ACQUIRED.message)
362+
})
363+
364+
test('runImmediately should acquire and release lock', async ({ assert }) => {
365+
assert.plan(3)
366+
367+
const store = new MemoryStore()
368+
const lock = new Lock('foo', store, defaultOptions)
369+
370+
assert.deepEqual(await lock.isLocked(), false)
371+
372+
await lock.runImmediately(async () => {
373+
assert.deepEqual(await lock.isLocked(), true)
374+
})
375+
376+
assert.deepEqual(await lock.isLocked(), false)
377+
})
378+
379+
test('runImmediately throws if lock is not available', async ({ assert }) => {
380+
const store = new MemoryStore()
381+
const lock = new Lock('foo', store, defaultOptions)
382+
const lock2 = new Lock('foo', store, defaultOptions)
383+
384+
await lock2.acquire()
385+
386+
// @ts-expect-error
387+
await assert.rejects(() => lock.acquireImmediately(), E_LOCK_ALREADY_ACQUIRED.message)
362388
})
363389
})

0 commit comments

Comments
 (0)