@prairielearn/named-locks 1.5.11 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +0 -32
- package/dist/index.d.ts +0 -40
- package/dist/index.js +16 -65
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +15 -70
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -45,35 +45,3 @@ await doWithLock(
|
|
|
45
45
|
},
|
|
46
46
|
);
|
|
47
47
|
```
|
|
48
|
-
|
|
49
|
-
### Advanced usage
|
|
50
|
-
|
|
51
|
-
Normally, it's preferable to use `doWithLock`, as it will automatically release the lock in case of failure. However, for advanced usage, you can manually acquire and release a lock.
|
|
52
|
-
|
|
53
|
-
```ts
|
|
54
|
-
import { waitLockAsync, releaseLockAsync } from '@prairielearn/named-locks';
|
|
55
|
-
|
|
56
|
-
const lock = await waitLockAsync('name', {});
|
|
57
|
-
try {
|
|
58
|
-
console.log('Doing some work');
|
|
59
|
-
} finally {
|
|
60
|
-
await releaseLockAsync(lock);
|
|
61
|
-
}
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
If you only want to acquire a lock if it's immediately available, you can use `tryLockAsync` instead:
|
|
65
|
-
|
|
66
|
-
```ts
|
|
67
|
-
import { tryLockAsync, releaseLockAsync } from '@prairielearn/named-locks';
|
|
68
|
-
|
|
69
|
-
const lock = await waitLockAsync('name', {});
|
|
70
|
-
if (lock) {
|
|
71
|
-
try {
|
|
72
|
-
console.log('Doing some work');
|
|
73
|
-
} finally {
|
|
74
|
-
await releaseLockAsync(lock);
|
|
75
|
-
}
|
|
76
|
-
} else {
|
|
77
|
-
console.log('Lock not acquired');
|
|
78
|
-
}
|
|
79
|
-
```
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
1
|
import { PostgresPool, PoolClient } from '@prairielearn/postgres';
|
|
4
2
|
import { PoolConfig } from 'pg';
|
|
5
3
|
interface NamedLocksConfig {
|
|
@@ -10,10 +8,6 @@ interface NamedLocksConfig {
|
|
|
10
8
|
*/
|
|
11
9
|
renewIntervalMs?: number;
|
|
12
10
|
}
|
|
13
|
-
interface Lock {
|
|
14
|
-
client: PoolClient;
|
|
15
|
-
intervalId: NodeJS.Timeout | null;
|
|
16
|
-
}
|
|
17
11
|
interface LockOptions {
|
|
18
12
|
/** How many milliseconds to wait (anything other than a positive number means forever) */
|
|
19
13
|
timeout?: number;
|
|
@@ -39,31 +33,6 @@ export declare function init(pgConfig: PoolConfig, idleErrorHandler: (error: Err
|
|
|
39
33
|
* Shuts down the database connection pool that was used to acquire locks.
|
|
40
34
|
*/
|
|
41
35
|
export declare function close(): Promise<void>;
|
|
42
|
-
/**
|
|
43
|
-
* Try to acquire a lock and either succeed if it's available or
|
|
44
|
-
* return immediately if not. If a lock is acquired then it must
|
|
45
|
-
* must later be released by releaseLock(). If a lock is not acquired
|
|
46
|
-
* (it is null) then releaseLock() should not be called.
|
|
47
|
-
*
|
|
48
|
-
* @param name The name of the lock to acquire.
|
|
49
|
-
*/
|
|
50
|
-
export declare function tryLockAsync(name: string, options?: LockOptions): Promise<Lock | null>;
|
|
51
|
-
export declare const tryLock: (arg1: string, callback: (err: NodeJS.ErrnoException, result: Lock | null) => void) => void;
|
|
52
|
-
/**
|
|
53
|
-
* Wait until a lock can be successfully acquired.
|
|
54
|
-
*
|
|
55
|
-
* @param name The name of the lock to acquire.
|
|
56
|
-
* @param options
|
|
57
|
-
*/
|
|
58
|
-
export declare function waitLockAsync(name: string, options: LockOptions): Promise<Lock>;
|
|
59
|
-
export declare const waitLock: (arg1: string, arg2: LockOptions, callback: (err: NodeJS.ErrnoException | null, result: Lock) => void) => void;
|
|
60
|
-
/**
|
|
61
|
-
* Release a lock.
|
|
62
|
-
*
|
|
63
|
-
* @param lock A previously-acquired lock.
|
|
64
|
-
*/
|
|
65
|
-
export declare function releaseLockAsync(lock: Lock): Promise<void>;
|
|
66
|
-
export declare const releaseLock: (arg1: Lock, callback: (err: NodeJS.ErrnoException) => void) => void;
|
|
67
36
|
/**
|
|
68
37
|
* Acquires the given lock, executes the provided function with the lock held,
|
|
69
38
|
* and releases the lock once the function has executed.
|
|
@@ -73,13 +42,4 @@ export declare const releaseLock: (arg1: Lock, callback: (err: NodeJS.ErrnoExcep
|
|
|
73
42
|
* Otherwise, an error is thrown to indicate that the lock could not be acquired.
|
|
74
43
|
*/
|
|
75
44
|
export declare function doWithLock<T, U = never>(name: string, options: WithLockOptions<U>, func: () => Promise<T>): Promise<T | U>;
|
|
76
|
-
/**
|
|
77
|
-
* Tries to acquire the given lock, executes the provided function with the lock held,
|
|
78
|
-
* and releases the lock once the function has executed.
|
|
79
|
-
*
|
|
80
|
-
* If the lock cannot be acquired, the function is not executed. If an `onNotAcquired`
|
|
81
|
-
* function was provided, this function is called and its return value is returned.
|
|
82
|
-
* Otherwise, `null` is returned.
|
|
83
|
-
*/
|
|
84
|
-
export declare function tryWithLock<T, U = null>(name: string, options: WithLockOptions<U>, func: () => Promise<T>): Promise<T | U>;
|
|
85
45
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
7
|
-
const util_1 = __importDefault(require("util"));
|
|
3
|
+
exports.doWithLock = exports.close = exports.init = exports.pool = void 0;
|
|
8
4
|
const postgres_1 = require("@prairielearn/postgres");
|
|
9
5
|
/*
|
|
10
6
|
* The functions here all identify locks by "name", which is a plain
|
|
@@ -66,46 +62,6 @@ async function close() {
|
|
|
66
62
|
await exports.pool.closeAsync();
|
|
67
63
|
}
|
|
68
64
|
exports.close = close;
|
|
69
|
-
/**
|
|
70
|
-
* Try to acquire a lock and either succeed if it's available or
|
|
71
|
-
* return immediately if not. If a lock is acquired then it must
|
|
72
|
-
* must later be released by releaseLock(). If a lock is not acquired
|
|
73
|
-
* (it is null) then releaseLock() should not be called.
|
|
74
|
-
*
|
|
75
|
-
* @param name The name of the lock to acquire.
|
|
76
|
-
*/
|
|
77
|
-
async function tryLockAsync(name, options = {}) {
|
|
78
|
-
return getLock(name, { timeout: 0, ...options });
|
|
79
|
-
}
|
|
80
|
-
exports.tryLockAsync = tryLockAsync;
|
|
81
|
-
exports.tryLock = util_1.default.callbackify(tryLockAsync);
|
|
82
|
-
/**
|
|
83
|
-
* Wait until a lock can be successfully acquired.
|
|
84
|
-
*
|
|
85
|
-
* @param name The name of the lock to acquire.
|
|
86
|
-
* @param options
|
|
87
|
-
*/
|
|
88
|
-
async function waitLockAsync(name, options) {
|
|
89
|
-
const lock = await getLock(name, options);
|
|
90
|
-
if (lock == null)
|
|
91
|
-
throw new Error(`failed to acquire lock: ${name}`);
|
|
92
|
-
return lock;
|
|
93
|
-
}
|
|
94
|
-
exports.waitLockAsync = waitLockAsync;
|
|
95
|
-
exports.waitLock = util_1.default.callbackify(waitLockAsync);
|
|
96
|
-
/**
|
|
97
|
-
* Release a lock.
|
|
98
|
-
*
|
|
99
|
-
* @param lock A previously-acquired lock.
|
|
100
|
-
*/
|
|
101
|
-
async function releaseLockAsync(lock) {
|
|
102
|
-
if (lock == null)
|
|
103
|
-
throw new Error('lock is null');
|
|
104
|
-
clearInterval(lock.intervalId ?? undefined);
|
|
105
|
-
await exports.pool.endTransactionAsync(lock.client, null);
|
|
106
|
-
}
|
|
107
|
-
exports.releaseLockAsync = releaseLockAsync;
|
|
108
|
-
exports.releaseLock = util_1.default.callbackify(releaseLockAsync);
|
|
109
65
|
/**
|
|
110
66
|
* Acquires the given lock, executes the provided function with the lock held,
|
|
111
67
|
* and releases the lock once the function has executed.
|
|
@@ -115,7 +71,7 @@ exports.releaseLock = util_1.default.callbackify(releaseLockAsync);
|
|
|
115
71
|
* Otherwise, an error is thrown to indicate that the lock could not be acquired.
|
|
116
72
|
*/
|
|
117
73
|
async function doWithLock(name, options, func) {
|
|
118
|
-
const lock = await
|
|
74
|
+
const lock = await getLock(name, { timeout: 0, ...options });
|
|
119
75
|
if (!lock) {
|
|
120
76
|
if (options.onNotAcquired) {
|
|
121
77
|
return await options.onNotAcquired();
|
|
@@ -128,29 +84,13 @@ async function doWithLock(name, options, func) {
|
|
|
128
84
|
return await func();
|
|
129
85
|
}
|
|
130
86
|
finally {
|
|
131
|
-
await
|
|
87
|
+
await releaseLock(lock);
|
|
132
88
|
}
|
|
133
89
|
}
|
|
134
90
|
exports.doWithLock = doWithLock;
|
|
135
91
|
/**
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
* If the lock cannot be acquired, the function is not executed. If an `onNotAcquired`
|
|
140
|
-
* function was provided, this function is called and its return value is returned.
|
|
141
|
-
* Otherwise, `null` is returned.
|
|
142
|
-
*/
|
|
143
|
-
async function tryWithLock(name, options, func) {
|
|
144
|
-
return await doWithLock(name, {
|
|
145
|
-
onNotAcquired: () => null,
|
|
146
|
-
...options,
|
|
147
|
-
}, func);
|
|
148
|
-
}
|
|
149
|
-
exports.tryWithLock = tryWithLock;
|
|
150
|
-
/**
|
|
151
|
-
* Internal helper function to get a lock with optional
|
|
152
|
-
* waiting. Do not call directly, but use tryLock() or waitLock()
|
|
153
|
-
* instead.
|
|
92
|
+
* Internal helper function to get a lock with optional waiting.
|
|
93
|
+
* Do not call directly; use `doWithLock()` instead.
|
|
154
94
|
*
|
|
155
95
|
* @param name The name of the lock to acquire.
|
|
156
96
|
* @param options Optional parameters.
|
|
@@ -202,4 +142,15 @@ async function getLock(name, options) {
|
|
|
202
142
|
// ending the transaction.
|
|
203
143
|
return { client, intervalId };
|
|
204
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Release a lock.
|
|
147
|
+
*
|
|
148
|
+
* @param lock A previously-acquired lock.
|
|
149
|
+
*/
|
|
150
|
+
async function releaseLock(lock) {
|
|
151
|
+
if (lock == null)
|
|
152
|
+
throw new Error('lock is null');
|
|
153
|
+
clearInterval(lock.intervalId ?? undefined);
|
|
154
|
+
await exports.pool.endTransactionAsync(lock.client, null);
|
|
155
|
+
}
|
|
205
156
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import util from 'util';
|
|
2
1
|
import { PostgresPool, PoolClient } from '@prairielearn/postgres';
|
|
3
2
|
import { PoolConfig } from 'pg';
|
|
4
3
|
|
|
@@ -104,47 +103,6 @@ export async function close() {
|
|
|
104
103
|
await pool.closeAsync();
|
|
105
104
|
}
|
|
106
105
|
|
|
107
|
-
/**
|
|
108
|
-
* Try to acquire a lock and either succeed if it's available or
|
|
109
|
-
* return immediately if not. If a lock is acquired then it must
|
|
110
|
-
* must later be released by releaseLock(). If a lock is not acquired
|
|
111
|
-
* (it is null) then releaseLock() should not be called.
|
|
112
|
-
*
|
|
113
|
-
* @param name The name of the lock to acquire.
|
|
114
|
-
*/
|
|
115
|
-
export async function tryLockAsync(name: string, options: LockOptions = {}): Promise<Lock | null> {
|
|
116
|
-
return getLock(name, { timeout: 0, ...options });
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export const tryLock = util.callbackify(tryLockAsync);
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Wait until a lock can be successfully acquired.
|
|
123
|
-
*
|
|
124
|
-
* @param name The name of the lock to acquire.
|
|
125
|
-
* @param options
|
|
126
|
-
*/
|
|
127
|
-
export async function waitLockAsync(name: string, options: LockOptions): Promise<Lock> {
|
|
128
|
-
const lock = await getLock(name, options);
|
|
129
|
-
if (lock == null) throw new Error(`failed to acquire lock: ${name}`);
|
|
130
|
-
return lock;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
export const waitLock = util.callbackify(waitLockAsync);
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Release a lock.
|
|
137
|
-
*
|
|
138
|
-
* @param lock A previously-acquired lock.
|
|
139
|
-
*/
|
|
140
|
-
export async function releaseLockAsync(lock: Lock) {
|
|
141
|
-
if (lock == null) throw new Error('lock is null');
|
|
142
|
-
clearInterval(lock.intervalId ?? undefined);
|
|
143
|
-
await pool.endTransactionAsync(lock.client, null);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
export const releaseLock = util.callbackify(releaseLockAsync);
|
|
147
|
-
|
|
148
106
|
/**
|
|
149
107
|
* Acquires the given lock, executes the provided function with the lock held,
|
|
150
108
|
* and releases the lock once the function has executed.
|
|
@@ -158,7 +116,7 @@ export async function doWithLock<T, U = never>(
|
|
|
158
116
|
options: WithLockOptions<U>,
|
|
159
117
|
func: () => Promise<T>,
|
|
160
118
|
): Promise<T | U> {
|
|
161
|
-
const lock = await
|
|
119
|
+
const lock = await getLock(name, { timeout: 0, ...options });
|
|
162
120
|
|
|
163
121
|
if (!lock) {
|
|
164
122
|
if (options.onNotAcquired) {
|
|
@@ -171,37 +129,13 @@ export async function doWithLock<T, U = never>(
|
|
|
171
129
|
try {
|
|
172
130
|
return await func();
|
|
173
131
|
} finally {
|
|
174
|
-
await
|
|
132
|
+
await releaseLock(lock);
|
|
175
133
|
}
|
|
176
134
|
}
|
|
177
135
|
|
|
178
136
|
/**
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
* If the lock cannot be acquired, the function is not executed. If an `onNotAcquired`
|
|
183
|
-
* function was provided, this function is called and its return value is returned.
|
|
184
|
-
* Otherwise, `null` is returned.
|
|
185
|
-
*/
|
|
186
|
-
export async function tryWithLock<T, U = null>(
|
|
187
|
-
name: string,
|
|
188
|
-
options: WithLockOptions<U>,
|
|
189
|
-
func: () => Promise<T>,
|
|
190
|
-
): Promise<T | U> {
|
|
191
|
-
return await doWithLock<T, U>(
|
|
192
|
-
name,
|
|
193
|
-
{
|
|
194
|
-
onNotAcquired: () => null as U,
|
|
195
|
-
...options,
|
|
196
|
-
},
|
|
197
|
-
func,
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Internal helper function to get a lock with optional
|
|
203
|
-
* waiting. Do not call directly, but use tryLock() or waitLock()
|
|
204
|
-
* instead.
|
|
137
|
+
* Internal helper function to get a lock with optional waiting.
|
|
138
|
+
* Do not call directly; use `doWithLock()` instead.
|
|
205
139
|
*
|
|
206
140
|
* @param name The name of the lock to acquire.
|
|
207
141
|
* @param options Optional parameters.
|
|
@@ -265,3 +199,14 @@ async function getLock(name: string, options: LockOptions) {
|
|
|
265
199
|
// ending the transaction.
|
|
266
200
|
return { client, intervalId };
|
|
267
201
|
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Release a lock.
|
|
205
|
+
*
|
|
206
|
+
* @param lock A previously-acquired lock.
|
|
207
|
+
*/
|
|
208
|
+
async function releaseLock(lock: Lock) {
|
|
209
|
+
if (lock == null) throw new Error('lock is null');
|
|
210
|
+
clearInterval(lock.intervalId ?? undefined);
|
|
211
|
+
await pool.endTransactionAsync(lock.client, null);
|
|
212
|
+
}
|