@prairielearn/named-locks 1.2.0 → 1.3.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/dist/index.d.ts +8 -1
- package/dist/index.js +20 -3
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +26 -2
package/CHANGELOG.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ interface LockOptions {
|
|
|
27
27
|
*/
|
|
28
28
|
autoRenew?: boolean;
|
|
29
29
|
}
|
|
30
|
+
type TryLockOptions = Omit<LockOptions, 'timeout'>;
|
|
30
31
|
export declare const pool: PostgresPool;
|
|
31
32
|
/**
|
|
32
33
|
* Initializes a new {@link PostgresPool} that will be used to acquire named locks.
|
|
@@ -44,7 +45,7 @@ export declare function close(): Promise<void>;
|
|
|
44
45
|
*
|
|
45
46
|
* @param name The name of the lock to acquire.
|
|
46
47
|
*/
|
|
47
|
-
export declare function tryLockAsync(name: string): Promise<Lock | null>;
|
|
48
|
+
export declare function tryLockAsync(name: string, options?: TryLockOptions): Promise<Lock | null>;
|
|
48
49
|
export declare const tryLock: (arg1: string, callback: (err: NodeJS.ErrnoException, result: Lock | null) => void) => void;
|
|
49
50
|
/**
|
|
50
51
|
* Wait until a lock can be successfully acquired.
|
|
@@ -66,4 +67,10 @@ export declare const releaseLock: (arg1: Lock, callback: (err: NodeJS.ErrnoExcep
|
|
|
66
67
|
* and releases the lock once the function has executed.
|
|
67
68
|
*/
|
|
68
69
|
export declare function doWithLock<T>(name: string, options: LockOptions, func: () => Promise<T>): Promise<T>;
|
|
70
|
+
/**
|
|
71
|
+
* Tries to acquire the given lock, executes the provided function with the lock held,
|
|
72
|
+
* and releases the lock once the function has executed. If the lock cannot be acquired,
|
|
73
|
+
* the function is not executed and null is returned.
|
|
74
|
+
*/
|
|
75
|
+
export declare function tryWithLock<T>(name: string, options: TryLockOptions, func: () => Promise<T>): Promise<T | null>;
|
|
69
76
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.doWithLock = exports.releaseLock = exports.releaseLockAsync = exports.waitLock = exports.waitLockAsync = exports.tryLock = exports.tryLockAsync = exports.close = exports.init = exports.pool = void 0;
|
|
6
|
+
exports.tryWithLock = exports.doWithLock = exports.releaseLock = exports.releaseLockAsync = exports.waitLock = exports.waitLockAsync = exports.tryLock = exports.tryLockAsync = exports.close = exports.init = exports.pool = void 0;
|
|
7
7
|
const util_1 = __importDefault(require("util"));
|
|
8
8
|
const postgres_1 = require("@prairielearn/postgres");
|
|
9
9
|
/*
|
|
@@ -74,8 +74,8 @@ exports.close = close;
|
|
|
74
74
|
*
|
|
75
75
|
* @param name The name of the lock to acquire.
|
|
76
76
|
*/
|
|
77
|
-
async function tryLockAsync(name) {
|
|
78
|
-
return getLock(name, { timeout: 0 });
|
|
77
|
+
async function tryLockAsync(name, options = {}) {
|
|
78
|
+
return getLock(name, { timeout: 0, ...options });
|
|
79
79
|
}
|
|
80
80
|
exports.tryLockAsync = tryLockAsync;
|
|
81
81
|
exports.tryLock = util_1.default.callbackify(tryLockAsync);
|
|
@@ -120,6 +120,23 @@ async function doWithLock(name, options, func) {
|
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
exports.doWithLock = doWithLock;
|
|
123
|
+
/**
|
|
124
|
+
* Tries to acquire the given lock, executes the provided function with the lock held,
|
|
125
|
+
* and releases the lock once the function has executed. If the lock cannot be acquired,
|
|
126
|
+
* the function is not executed and null is returned.
|
|
127
|
+
*/
|
|
128
|
+
async function tryWithLock(name, options, func) {
|
|
129
|
+
const lock = await tryLockAsync(name, options);
|
|
130
|
+
if (lock == null)
|
|
131
|
+
return null;
|
|
132
|
+
try {
|
|
133
|
+
return await func();
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
await releaseLockAsync(lock);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
exports.tryWithLock = tryWithLock;
|
|
123
140
|
/**
|
|
124
141
|
* Internal helper function to get a lock with optional
|
|
125
142
|
* waiting. Do not call directly, but use tryLock() or waitLock()
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AACxB,qDAAkE;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AACxB,qDAAkE;AAiClE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEU,QAAA,IAAI,GAAG,IAAI,uBAAY,EAAE,CAAC;AACvC,IAAI,eAAe,GAAG,KAAM,CAAC;AAE7B;;GAEG;AACI,KAAK,UAAU,IAAI,CACxB,QAAoB,EACpB,gBAA4D,EAC5D,mBAAqC,EAAE;IAEvC,eAAe,GAAG,gBAAgB,CAAC,eAAe,IAAI,eAAe,CAAC;IACtE,MAAM,YAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IACjD,MAAM,YAAI,CAAC,UAAU,CACnB,+FAA+F,EAC/F,EAAE,CACH,CAAC;AACJ,CAAC;AAXD,oBAWC;AAED;;GAEG;AACI,KAAK,UAAU,KAAK;IACzB,MAAM,YAAI,CAAC,UAAU,EAAE,CAAC;AAC1B,CAAC;AAFD,sBAEC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,UAA0B,EAAE;IAE5B,OAAO,OAAO,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;AACnD,CAAC;AALD,oCAKC;AAEY,QAAA,OAAO,GAAG,cAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;AAEtD;;;;;GAKG;AACI,KAAK,UAAU,aAAa,CAAC,IAAY,EAAE,OAAoB;IACpE,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1C,IAAI,IAAI,IAAI,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;IACrE,OAAO,IAAI,CAAC;AACd,CAAC;AAJD,sCAIC;AAEY,QAAA,QAAQ,GAAG,cAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;AAExD;;;;GAIG;AACI,KAAK,UAAU,gBAAgB,CAAC,IAAU;IAC/C,IAAI,IAAI,IAAI,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;IAClD,aAAa,CAAC,IAAI,CAAC,UAAU,IAAI,SAAS,CAAC,CAAC;IAC5C,MAAM,YAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACpD,CAAC;AAJD,4CAIC;AAEY,QAAA,WAAW,GAAG,cAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;AAE9D;;;GAGG;AACI,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,OAAoB,EACpB,IAAsB;IAEtB,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAChD,IAAI;QACF,OAAO,MAAM,IAAI,EAAE,CAAC;KACrB;YAAS;QACR,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;KAC9B;AACH,CAAC;AAXD,gCAWC;AAED;;;;GAIG;AACI,KAAK,UAAU,WAAW,CAC/B,IAAY,EACZ,OAAuB,EACvB,IAAsB;IAEtB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/C,IAAI,IAAI,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAC9B,IAAI;QACF,OAAO,MAAM,IAAI,EAAE,CAAC;KACrB;YAAS;QACR,MAAM,gBAAgB,CAAC,IAAI,CAAC,CAAC;KAC9B;AACH,CAAC;AAZD,kCAYC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,OAAO,CAAC,IAAY,EAAE,OAAoB;IACvD,MAAM,YAAI,CAAC,UAAU,CACnB,8EAA8E,EAC9E,EAAE,IAAI,EAAE,CACT,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,YAAI,CAAC,qBAAqB,EAAE,CAAC;IAElD,IAAI,YAAY,GAAG,KAAK,CAAC;IACzB,IAAI;QACF,IAAI,OAAO,CAAC,OAAO,EAAE;YACnB,+DAA+D;YAC/D,6DAA6D;YAC7D,oDAAoD;YACpD,MAAM,YAAI,CAAC,oBAAoB,CAC7B,MAAM,EACN,4BAA4B,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAE,EAC9E,EAAE,CACH,CAAC;SACH;QAED,wEAAwE;QACxE,gEAAgE;QAChE,uEAAuE;QACvE,uEAAuE;QACvE,OAAO;QACP,MAAM,eAAe,GAAG,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO;YAC9B,CAAC,CAAC,0CAA0C,eAAe,cAAc;YACzE,CAAC,CAAC,0CAA0C,eAAe,0BAA0B,CAAC;QACxF,MAAM,MAAM,GAAG,MAAM,YAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E,YAAY,GAAG,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC;KACtC;IAAC,OAAO,GAAG,EAAE;QACZ,mEAAmE;QACnE,SAAS;QACT,MAAM,YAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,GAAY,CAAC,CAAC;QACrD,MAAM,GAAG,CAAC;KACX;IAED,IAAI,CAAC,YAAY,EAAE;QACjB,6DAA6D;QAC7D,qDAAqD;QACrD,MAAM,YAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC;KACb;IAED,IAAI,UAAU,GAAG,IAAI,CAAC;IACtB,IAAI,OAAO,CAAC,SAAS,EAAE;QACrB,mDAAmD;QACnD,UAAU,GAAG,WAAW,CAAC,GAAG,EAAE;YAC5B,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC5C,CAAC,EAAE,eAAe,CAAC,CAAC;KACrB;IAED,uEAAuE;IACvE,uEAAuE;IACvE,0BAA0B;IAC1B,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAChC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prairielearn/named-locks",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
"dev": "tsc --watch --preserveWatchOutput"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
|
15
|
-
"@prairielearn/tsconfig": "
|
|
15
|
+
"@prairielearn/tsconfig": "^0.0.0",
|
|
16
16
|
"@types/node": "^18.15.11",
|
|
17
17
|
"typescript": "^4.9.4"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@prairielearn/postgres": "^1.
|
|
20
|
+
"@prairielearn/postgres": "^1.6.0"
|
|
21
21
|
}
|
|
22
22
|
}
|
package/src/index.ts
CHANGED
|
@@ -30,6 +30,8 @@ interface LockOptions {
|
|
|
30
30
|
autoRenew?: boolean;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
type TryLockOptions = Omit<LockOptions, 'timeout'>;
|
|
34
|
+
|
|
33
35
|
/*
|
|
34
36
|
* The functions here all identify locks by "name", which is a plain
|
|
35
37
|
* string. The locks use the named_locks DB table. Each lock name
|
|
@@ -107,8 +109,11 @@ export async function close() {
|
|
|
107
109
|
*
|
|
108
110
|
* @param name The name of the lock to acquire.
|
|
109
111
|
*/
|
|
110
|
-
export async function tryLockAsync(
|
|
111
|
-
|
|
112
|
+
export async function tryLockAsync(
|
|
113
|
+
name: string,
|
|
114
|
+
options: TryLockOptions = {}
|
|
115
|
+
): Promise<Lock | null> {
|
|
116
|
+
return getLock(name, { timeout: 0, ...options });
|
|
112
117
|
}
|
|
113
118
|
|
|
114
119
|
export const tryLock = util.callbackify(tryLockAsync);
|
|
@@ -157,6 +162,25 @@ export async function doWithLock<T>(
|
|
|
157
162
|
}
|
|
158
163
|
}
|
|
159
164
|
|
|
165
|
+
/**
|
|
166
|
+
* Tries to acquire the given lock, executes the provided function with the lock held,
|
|
167
|
+
* and releases the lock once the function has executed. If the lock cannot be acquired,
|
|
168
|
+
* the function is not executed and null is returned.
|
|
169
|
+
*/
|
|
170
|
+
export async function tryWithLock<T>(
|
|
171
|
+
name: string,
|
|
172
|
+
options: TryLockOptions,
|
|
173
|
+
func: () => Promise<T>
|
|
174
|
+
): Promise<T | null> {
|
|
175
|
+
const lock = await tryLockAsync(name, options);
|
|
176
|
+
if (lock == null) return null;
|
|
177
|
+
try {
|
|
178
|
+
return await func();
|
|
179
|
+
} finally {
|
|
180
|
+
await releaseLockAsync(lock);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
160
184
|
/**
|
|
161
185
|
* Internal helper function to get a lock with optional
|
|
162
186
|
* waiting. Do not call directly, but use tryLock() or waitLock()
|