@prairielearn/named-locks 1.0.0 → 1.1.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 +12 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +12 -12
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +1 -1
package/CHANGELOG.md
ADDED
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { PoolClient } from '@prairielearn/postgres';
|
|
2
|
+
import { PostgresPool, PoolClient } from '@prairielearn/postgres';
|
|
3
3
|
import { PoolConfig } from 'pg';
|
|
4
4
|
interface Lock {
|
|
5
5
|
client: PoolClient;
|
|
@@ -8,6 +8,7 @@ interface LockOptions {
|
|
|
8
8
|
/** How many milliseconds to wait (anything other than a positive number means forever) */
|
|
9
9
|
timeout?: number;
|
|
10
10
|
}
|
|
11
|
+
export declare const pool: PostgresPool;
|
|
11
12
|
/**
|
|
12
13
|
* Initializes a new {@link PostgresPool} that will be used to acquire named locks.
|
|
13
14
|
*/
|
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 = void 0;
|
|
6
|
+
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
|
/*
|
|
@@ -48,20 +48,20 @@ const postgres_1 = require("@prairielearn/postgres");
|
|
|
48
48
|
* lock already held. Since there are a finite pool of locks available, this
|
|
49
49
|
* can lead to deadlocks.
|
|
50
50
|
*/
|
|
51
|
-
|
|
51
|
+
exports.pool = new postgres_1.PostgresPool();
|
|
52
52
|
/**
|
|
53
53
|
* Initializes a new {@link PostgresPool} that will be used to acquire named locks.
|
|
54
54
|
*/
|
|
55
55
|
async function init(pgConfig, idleErrorHandler) {
|
|
56
|
-
await pool.initAsync(pgConfig, idleErrorHandler);
|
|
57
|
-
await pool.queryAsync('CREATE TABLE IF NOT EXISTS named_locks (id bigserial PRIMARY KEY, name text NOT NULL UNIQUE);', {});
|
|
56
|
+
await exports.pool.initAsync(pgConfig, idleErrorHandler);
|
|
57
|
+
await exports.pool.queryAsync('CREATE TABLE IF NOT EXISTS named_locks (id bigserial PRIMARY KEY, name text NOT NULL UNIQUE);', {});
|
|
58
58
|
}
|
|
59
59
|
exports.init = init;
|
|
60
60
|
/**
|
|
61
61
|
* Shuts down the database connection pool that was used to acquire locks.
|
|
62
62
|
*/
|
|
63
63
|
async function close() {
|
|
64
|
-
await pool.closeAsync();
|
|
64
|
+
await exports.pool.closeAsync();
|
|
65
65
|
}
|
|
66
66
|
exports.close = close;
|
|
67
67
|
/**
|
|
@@ -103,7 +103,7 @@ exports.waitLock = util_1.default.callbackify(waitLockAsync);
|
|
|
103
103
|
async function releaseLockAsync(lock) {
|
|
104
104
|
if (lock == null)
|
|
105
105
|
throw new Error('lock is null');
|
|
106
|
-
await pool.endTransactionAsync(lock.client, null);
|
|
106
|
+
await exports.pool.endTransactionAsync(lock.client, null);
|
|
107
107
|
}
|
|
108
108
|
exports.releaseLockAsync = releaseLockAsync;
|
|
109
109
|
exports.releaseLock = util_1.default.callbackify(releaseLockAsync);
|
|
@@ -130,15 +130,15 @@ exports.doWithLock = doWithLock;
|
|
|
130
130
|
* @param options Optional parameters.
|
|
131
131
|
*/
|
|
132
132
|
async function getLock(name, options) {
|
|
133
|
-
await pool.queryAsync('INSERT INTO named_locks (name) VALUES ($name) ON CONFLICT (name) DO NOTHING;', { name });
|
|
134
|
-
const client = await pool.beginTransactionAsync();
|
|
133
|
+
await exports.pool.queryAsync('INSERT INTO named_locks (name) VALUES ($name) ON CONFLICT (name) DO NOTHING;', { name });
|
|
134
|
+
const client = await exports.pool.beginTransactionAsync();
|
|
135
135
|
let acquiredLock = false;
|
|
136
136
|
try {
|
|
137
137
|
if (options.wait && options.timeout > 0) {
|
|
138
138
|
// SQL doesn't like us trying to use a parameterized query with
|
|
139
139
|
// `SET LOCAL ...`. So, in this very specific case, we do the
|
|
140
140
|
// parameterization ourselves using `escapeLiteral`.
|
|
141
|
-
await pool.queryWithClientAsync(client, `SET LOCAL lock_timeout = ${client.escapeLiteral(options.timeout.toString())}`, {});
|
|
141
|
+
await exports.pool.queryWithClientAsync(client, `SET LOCAL lock_timeout = ${client.escapeLiteral(options.timeout.toString())}`, {});
|
|
142
142
|
}
|
|
143
143
|
// A stuck lock is a critical issue. To make them easier to debug, we'll
|
|
144
144
|
// include the literal lock name in the query instead of using a
|
|
@@ -149,19 +149,19 @@ async function getLock(name, options) {
|
|
|
149
149
|
const lock_sql = options.wait
|
|
150
150
|
? `SELECT * FROM named_locks WHERE name = ${lockNameLiteral} FOR UPDATE;`
|
|
151
151
|
: `SELECT * FROM named_locks WHERE name = ${lockNameLiteral} FOR UPDATE SKIP LOCKED;`;
|
|
152
|
-
const result = await pool.queryWithClientAsync(client, lock_sql, { name });
|
|
152
|
+
const result = await exports.pool.queryWithClientAsync(client, lock_sql, { name });
|
|
153
153
|
acquiredLock = result.rowCount === 1;
|
|
154
154
|
}
|
|
155
155
|
catch (err) {
|
|
156
156
|
// Something went wrong, so we end the transaction and re-throw the
|
|
157
157
|
// error.
|
|
158
|
-
await pool.endTransactionAsync(client, err);
|
|
158
|
+
await exports.pool.endTransactionAsync(client, err);
|
|
159
159
|
throw err;
|
|
160
160
|
}
|
|
161
161
|
if (!acquiredLock) {
|
|
162
162
|
// We didn't acquire the lock so our parent caller will never
|
|
163
163
|
// release it, so we have to end the transaction now.
|
|
164
|
-
await pool.endTransactionAsync(client, null);
|
|
164
|
+
await exports.pool.endTransactionAsync(client, null);
|
|
165
165
|
return null;
|
|
166
166
|
}
|
|
167
167
|
// We successfully acquired the lock, so we return with the transaction
|
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;AAqBlE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwB;AACxB,qDAAkE;AAqBlE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEU,QAAA,IAAI,GAAG,IAAI,uBAAY,EAAE,CAAC;AAEvC;;GAEG;AACI,KAAK,UAAU,IAAI,CACxB,QAAoB,EACpB,gBAA4D;IAE5D,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;AATD,oBASC;AAED;;GAEG;AACI,KAAK,UAAU,KAAK;IACzB,MAAM,YAAI,CAAC,UAAU,EAAE,CAAC;AAC1B,CAAC;AAFD,sBAEC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,YAAY,CAAC,IAAY;IAC7C,OAAO,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACxC,CAAC;AAFD,oCAEC;AAEY,QAAA,OAAO,GAAG,cAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;AAEtD;;;;;GAKG;AACI,KAAK,UAAU,aAAa,CAAC,IAAY,EAAE,OAAoB;IACpE,MAAM,eAAe,GAAG;QACtB,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,CAAC;KAC9B,CAAC;IAEF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IAClD,IAAI,IAAI,IAAI,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;IACrE,OAAO,IAAI,CAAC;AACd,CAAC;AATD,sCASC;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,MAAM,YAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACpD,CAAC;AAHD,4CAGC;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;;;;;;;GAOG;AACH,KAAK,UAAU,OAAO,CAAC,IAAY,EAAE,OAA4B;IAC/D,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,IAAI,IAAI,OAAO,CAAC,OAAO,GAAG,CAAC,EAAE;YACvC,+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,IAAI;YAC3B,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,uEAAuE;IACvE,uEAAuE;IACvE,0BAA0B;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prairielearn/named-locks",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "tsc",
|
|
@@ -12,6 +12,6 @@
|
|
|
12
12
|
"typescript": "^4.9.4"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@prairielearn/postgres": "^1.
|
|
15
|
+
"@prairielearn/postgres": "^1.3.0"
|
|
16
16
|
}
|
|
17
17
|
}
|
package/src/index.ts
CHANGED