mini-semaphore 1.1.0 → 1.3.4
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/README.md +1 -1
- package/cjs/class.js +1 -0
- package/cjs/core.js +5 -2
- package/cjs/deque.js +1 -12
- package/cjs/extras.js +3 -1
- package/cjs/flow-restrictor.js +61 -15
- package/cjs/index.d.ts +13 -5
- package/cjs/index.js +5 -4
- package/cjs/object.js +3 -1
- package/esm/class.js +1 -1
- package/esm/core.js +1 -1
- package/esm/deque.js +1 -13
- package/esm/extras.js +1 -1
- package/esm/flow-restrictor.js +61 -16
- package/esm/index.d.ts +13 -5
- package/esm/index.js +1 -1
- package/esm/object.js +1 -1
- package/index.d.ts +13 -5
- package/package.json +7 -34
- package/umd/index.d.ts +13 -5
- package/umd/index.js +85 -100
- package/umd/index.js.map +1 -1
- package/webpack/index.d.ts +13 -5
- package/webpack/index.js +86 -101
- package/webpack/index.js.map +1 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-

|
|
1
|
+
[](https://travis-ci.com/jeffy-g/mini-semaphore) 
|
|
2
2
|
|
|
3
3
|
# Mini Semaphore (mini-semaphore
|
|
4
4
|
|
package/cjs/class.js
CHANGED
package/cjs/core.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.release = exports.acquire = void 0;
|
|
3
4
|
const extras_1 = require("./extras");
|
|
4
5
|
const box = (z, r) => {
|
|
5
6
|
if (z.capacity > 0) {
|
|
@@ -9,7 +10,7 @@ const box = (z, r) => {
|
|
|
9
10
|
z.q.push(r);
|
|
10
11
|
}
|
|
11
12
|
};
|
|
12
|
-
|
|
13
|
+
const acquire = (dis, lazy = true) => {
|
|
13
14
|
return new Promise(r => {
|
|
14
15
|
if (!lazy) {
|
|
15
16
|
box(dis, r);
|
|
@@ -19,7 +20,8 @@ exports.acquire = (dis, lazy = true) => {
|
|
|
19
20
|
}
|
|
20
21
|
});
|
|
21
22
|
};
|
|
22
|
-
exports.
|
|
23
|
+
exports.acquire = acquire;
|
|
24
|
+
const release = (dis) => {
|
|
23
25
|
dis.capacity++;
|
|
24
26
|
if (dis.q.length) {
|
|
25
27
|
dis.capacity -= 1, (dis.q.shift() || extras_1.THROW)();
|
|
@@ -29,3 +31,4 @@ exports.release = (dis) => {
|
|
|
29
31
|
dis.capacity = dis.limit;
|
|
30
32
|
}
|
|
31
33
|
};
|
|
34
|
+
exports.release = release;
|
package/cjs/deque.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Deque = void 0;
|
|
3
4
|
const am = (src, si, dst, di, len) => {
|
|
4
5
|
for (let j = 0; j < len; ++j) {
|
|
5
6
|
dst[j + di] = src[j + si];
|
|
@@ -34,7 +35,6 @@ class Deque {
|
|
|
34
35
|
const i = (this._f + l) & (this._c - 1);
|
|
35
36
|
this._a[i] = s;
|
|
36
37
|
this._l = l + 1;
|
|
37
|
-
return l + 1;
|
|
38
38
|
}
|
|
39
39
|
shift() {
|
|
40
40
|
const l = this._l;
|
|
@@ -48,17 +48,6 @@ class Deque {
|
|
|
48
48
|
this._l = l - 1;
|
|
49
49
|
return r;
|
|
50
50
|
}
|
|
51
|
-
clear() {
|
|
52
|
-
const l = this._l;
|
|
53
|
-
const f = this._f;
|
|
54
|
-
const c = this._c;
|
|
55
|
-
const a = this._a;
|
|
56
|
-
for (let j = 0; j < l; ++j) {
|
|
57
|
-
a[(f + j) & (c - 1)] = void 0;
|
|
58
|
-
}
|
|
59
|
-
this._l = 0;
|
|
60
|
-
this._f = 0;
|
|
61
|
-
}
|
|
62
51
|
get length() {
|
|
63
52
|
return this._l;
|
|
64
53
|
}
|
package/cjs/extras.js
CHANGED
package/cjs/flow-restrictor.js
CHANGED
|
@@ -1,27 +1,73 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.restrictor = void 0;
|
|
3
4
|
const c = require("./class");
|
|
4
|
-
const { MiniSemaphore: MS } = c;
|
|
5
|
-
const locks = {};
|
|
6
|
-
const get = (key, restriction) => {
|
|
7
|
-
let lock = locks[key];
|
|
8
|
-
if (!lock) {
|
|
9
|
-
locks[key] = lock = new MS(restriction);
|
|
10
|
-
}
|
|
11
|
-
if (lock.limit !== restriction) {
|
|
12
|
-
throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);
|
|
13
|
-
}
|
|
14
|
-
return lock;
|
|
15
|
-
};
|
|
16
5
|
var restrictor;
|
|
17
6
|
(function (restrictor) {
|
|
18
|
-
|
|
7
|
+
const { MiniSemaphore: MS } = c;
|
|
8
|
+
const internalLock = new MS(1);
|
|
9
|
+
let locks = Object.create(null);
|
|
10
|
+
const get = async (key, restriction) => {
|
|
11
|
+
await internalLock.acquire(false);
|
|
12
|
+
let lock = locks[key];
|
|
13
|
+
if (!lock) {
|
|
14
|
+
locks[key] = lock = new MS(restriction);
|
|
15
|
+
}
|
|
16
|
+
if (lock.limit !== restriction) {
|
|
17
|
+
internalLock.release();
|
|
18
|
+
throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);
|
|
19
|
+
}
|
|
20
|
+
internalLock.release();
|
|
21
|
+
return lock;
|
|
22
|
+
};
|
|
23
|
+
restrictor.getLockByKey = async (key) => {
|
|
24
|
+
await internalLock.acquire(false);
|
|
25
|
+
const l = locks[key];
|
|
26
|
+
internalLock.release();
|
|
27
|
+
return l;
|
|
28
|
+
};
|
|
29
|
+
restrictor.cleanup = async (timeSpan, debug) => {
|
|
30
|
+
await internalLock.acquire(false);
|
|
31
|
+
const currentLocks = locks;
|
|
32
|
+
const newLocks = Object.create(null);
|
|
33
|
+
const keys = Object.keys(currentLocks);
|
|
34
|
+
let eliminatedCount = 0;
|
|
35
|
+
let eliminatedKeys;
|
|
36
|
+
!timeSpan && (timeSpan = 1);
|
|
37
|
+
timeSpan *= 1000;
|
|
38
|
+
if (debug) {
|
|
39
|
+
eliminatedKeys = [];
|
|
40
|
+
}
|
|
41
|
+
for (let i = 0, end = keys.length; i < end;) {
|
|
42
|
+
const key = keys[i++];
|
|
43
|
+
const s = currentLocks[key];
|
|
44
|
+
if (s.last && Date.now() - s.last >= timeSpan) {
|
|
45
|
+
eliminatedCount++;
|
|
46
|
+
if (debug) {
|
|
47
|
+
eliminatedKeys.push(key);
|
|
48
|
+
}
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
newLocks[key] = s;
|
|
52
|
+
}
|
|
53
|
+
locks = newLocks;
|
|
54
|
+
internalLock.release();
|
|
55
|
+
if (debug) {
|
|
56
|
+
console.log(`eliminated: [\n${eliminatedKeys.join(",\n")}\n]` +
|
|
57
|
+
"\n" +
|
|
58
|
+
`lived: [\n${Object.keys(newLocks).join(",\n")}\n]`);
|
|
59
|
+
}
|
|
60
|
+
return eliminatedCount;
|
|
61
|
+
};
|
|
19
62
|
async function multi(key, restriction, pb) {
|
|
20
|
-
|
|
63
|
+
const s = await get(key, restriction);
|
|
64
|
+
const result = s.flow(pb);
|
|
65
|
+
s.last = Date.now();
|
|
66
|
+
return result;
|
|
21
67
|
}
|
|
22
68
|
restrictor.multi = multi;
|
|
23
69
|
async function one(key, pb) {
|
|
24
|
-
return
|
|
70
|
+
return multi(key, 1, pb);
|
|
25
71
|
}
|
|
26
72
|
restrictor.one = one;
|
|
27
73
|
})(restrictor = exports.restrictor || (exports.restrictor = {}));
|
package/cjs/index.d.ts
CHANGED
|
@@ -32,8 +32,8 @@ export declare class Deque<T extends any> {
|
|
|
32
32
|
/**
|
|
33
33
|
* @param s subject
|
|
34
34
|
*/
|
|
35
|
-
push(s: T):
|
|
36
|
-
shift(): T | undefined;
|
|
35
|
+
push(s: T): void;
|
|
36
|
+
// shift(): T | undefined;
|
|
37
37
|
clear(): void;
|
|
38
38
|
get length(): number;
|
|
39
39
|
}
|
|
@@ -94,8 +94,8 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
|
|
|
94
94
|
readonly q: Deque<T>;
|
|
95
95
|
};
|
|
96
96
|
export declare type TVoidFunction = () => void;
|
|
97
|
-
export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
-
export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
97
|
+
// export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
+
// export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
/**
|
|
@@ -173,6 +173,14 @@ export declare class MiniSemaphore implements TFlowableLock {
|
|
|
173
173
|
export declare const create: (capacity: number) => IFlowableLock;
|
|
174
174
|
|
|
175
175
|
declare namespace fr {
|
|
176
|
+
/**
|
|
177
|
+
* Eliminate unused instances for the `timeSpan` seconds
|
|
178
|
+
*
|
|
179
|
+
* @param timeSpan specify unit as seconds
|
|
180
|
+
* @returns {Promise<number>} eliminated count
|
|
181
|
+
* @date 2020/6/19
|
|
182
|
+
*/
|
|
183
|
+
const cleanup: (timeSpan: number, debug?: true | undefined) => Promise<number>;
|
|
176
184
|
/**
|
|
177
185
|
* get the semaphore associated with the value of `key`
|
|
178
186
|
*
|
|
@@ -181,7 +189,7 @@ declare namespace fr {
|
|
|
181
189
|
* @param key
|
|
182
190
|
* @returns `IFlowableLock` instance or `undefined`
|
|
183
191
|
*/
|
|
184
|
-
export const getLockByKey: (key: string | number) => IFlowableLock
|
|
192
|
+
export const getLockByKey: (key: string | number) => Promise<IFlowableLock>;
|
|
185
193
|
/**
|
|
186
194
|
* Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`
|
|
187
195
|
*
|
package/cjs/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.restrictor = exports.Deque = exports.create = exports.MiniSemaphore = void 0;
|
|
3
4
|
var class_1 = require("./class");
|
|
4
|
-
exports
|
|
5
|
+
Object.defineProperty(exports, "MiniSemaphore", { enumerable: true, get: function () { return class_1.MiniSemaphore; } });
|
|
5
6
|
var object_1 = require("./object");
|
|
6
|
-
exports
|
|
7
|
+
Object.defineProperty(exports, "create", { enumerable: true, get: function () { return object_1.create; } });
|
|
7
8
|
var deque_1 = require("./deque");
|
|
8
|
-
exports
|
|
9
|
+
Object.defineProperty(exports, "Deque", { enumerable: true, get: function () { return deque_1.Deque; } });
|
|
9
10
|
var flow_restrictor_1 = require("./flow-restrictor");
|
|
10
|
-
exports
|
|
11
|
+
Object.defineProperty(exports, "restrictor", { enumerable: true, get: function () { return flow_restrictor_1.restrictor; } });
|
package/cjs/object.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.create = void 0;
|
|
3
4
|
const core = require("./core");
|
|
4
5
|
const deque_1 = require("./deque");
|
|
5
6
|
const a = core.acquire;
|
|
6
7
|
const r = core.release;
|
|
7
|
-
|
|
8
|
+
const create = (capacity) => {
|
|
8
9
|
return {
|
|
9
10
|
capacity,
|
|
10
11
|
limit: capacity,
|
|
@@ -32,3 +33,4 @@ exports.create = (capacity) => {
|
|
|
32
33
|
}
|
|
33
34
|
};
|
|
34
35
|
};
|
|
36
|
+
exports.create = create;
|
package/esm/class.js
CHANGED
package/esm/core.js
CHANGED
package/esm/deque.js
CHANGED
|
@@ -32,7 +32,6 @@ export class Deque {
|
|
|
32
32
|
const i = (this._f + l) & (this._c - 1);
|
|
33
33
|
this._a[i] = s;
|
|
34
34
|
this._l = l + 1;
|
|
35
|
-
return l + 1;
|
|
36
35
|
}
|
|
37
36
|
shift() {
|
|
38
37
|
const l = this._l;
|
|
@@ -46,17 +45,6 @@ export class Deque {
|
|
|
46
45
|
this._l = l - 1;
|
|
47
46
|
return r;
|
|
48
47
|
}
|
|
49
|
-
clear() {
|
|
50
|
-
const l = this._l;
|
|
51
|
-
const f = this._f;
|
|
52
|
-
const c = this._c;
|
|
53
|
-
const a = this._a;
|
|
54
|
-
for (let j = 0; j < l; ++j) {
|
|
55
|
-
a[(f + j) & (c - 1)] = void 0;
|
|
56
|
-
}
|
|
57
|
-
this._l = 0;
|
|
58
|
-
this._f = 0;
|
|
59
|
-
}
|
|
60
48
|
get length() {
|
|
61
49
|
return this._l;
|
|
62
50
|
}
|
|
@@ -70,4 +58,4 @@ const rt = (dis, n) => {
|
|
|
70
58
|
const mc = (f + l) & (oc - 1);
|
|
71
59
|
am(dis._a, 0, dis._a, oc, mc);
|
|
72
60
|
}
|
|
73
|
-
};
|
|
61
|
+
};
|
package/esm/extras.js
CHANGED
package/esm/flow-restrictor.js
CHANGED
|
@@ -1,25 +1,70 @@
|
|
|
1
1
|
import * as c from "./class";
|
|
2
|
-
const { MiniSemaphore: MS } = c;
|
|
3
|
-
const locks = {};
|
|
4
|
-
const get = (key, restriction) => {
|
|
5
|
-
let lock = locks[key];
|
|
6
|
-
if (!lock) {
|
|
7
|
-
locks[key] = lock = new MS(restriction);
|
|
8
|
-
}
|
|
9
|
-
if (lock.limit !== restriction) {
|
|
10
|
-
throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);
|
|
11
|
-
}
|
|
12
|
-
return lock;
|
|
13
|
-
};
|
|
14
2
|
export var restrictor;
|
|
15
3
|
(function (restrictor) {
|
|
16
|
-
|
|
4
|
+
const { MiniSemaphore: MS } = c;
|
|
5
|
+
const internalLock = new MS(1);
|
|
6
|
+
let locks = Object.create(null);
|
|
7
|
+
const get = async (key, restriction) => {
|
|
8
|
+
await internalLock.acquire(false);
|
|
9
|
+
let lock = locks[key];
|
|
10
|
+
if (!lock) {
|
|
11
|
+
locks[key] = lock = new MS(restriction);
|
|
12
|
+
}
|
|
13
|
+
if (lock.limit !== restriction) {
|
|
14
|
+
internalLock.release();
|
|
15
|
+
throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);
|
|
16
|
+
}
|
|
17
|
+
internalLock.release();
|
|
18
|
+
return lock;
|
|
19
|
+
};
|
|
20
|
+
restrictor.getLockByKey = async (key) => {
|
|
21
|
+
await internalLock.acquire(false);
|
|
22
|
+
const l = locks[key];
|
|
23
|
+
internalLock.release();
|
|
24
|
+
return l;
|
|
25
|
+
};
|
|
26
|
+
restrictor.cleanup = async (timeSpan, debug) => {
|
|
27
|
+
await internalLock.acquire(false);
|
|
28
|
+
const currentLocks = locks;
|
|
29
|
+
const newLocks = Object.create(null);
|
|
30
|
+
const keys = Object.keys(currentLocks);
|
|
31
|
+
let eliminatedCount = 0;
|
|
32
|
+
let eliminatedKeys;
|
|
33
|
+
!timeSpan && (timeSpan = 1);
|
|
34
|
+
timeSpan *= 1000;
|
|
35
|
+
if (debug) {
|
|
36
|
+
eliminatedKeys = [];
|
|
37
|
+
}
|
|
38
|
+
for (let i = 0, end = keys.length; i < end;) {
|
|
39
|
+
const key = keys[i++];
|
|
40
|
+
const s = currentLocks[key];
|
|
41
|
+
if (s.last && Date.now() - s.last >= timeSpan) {
|
|
42
|
+
eliminatedCount++;
|
|
43
|
+
if (debug) {
|
|
44
|
+
eliminatedKeys.push(key);
|
|
45
|
+
}
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
newLocks[key] = s;
|
|
49
|
+
}
|
|
50
|
+
locks = newLocks;
|
|
51
|
+
internalLock.release();
|
|
52
|
+
if (debug) {
|
|
53
|
+
console.log(`eliminated: [\n${eliminatedKeys.join(",\n")}\n]` +
|
|
54
|
+
"\n" +
|
|
55
|
+
`lived: [\n${Object.keys(newLocks).join(",\n")}\n]`);
|
|
56
|
+
}
|
|
57
|
+
return eliminatedCount;
|
|
58
|
+
};
|
|
17
59
|
async function multi(key, restriction, pb) {
|
|
18
|
-
|
|
60
|
+
const s = await get(key, restriction);
|
|
61
|
+
const result = s.flow(pb);
|
|
62
|
+
s.last = Date.now();
|
|
63
|
+
return result;
|
|
19
64
|
}
|
|
20
65
|
restrictor.multi = multi;
|
|
21
66
|
async function one(key, pb) {
|
|
22
|
-
return
|
|
67
|
+
return multi(key, 1, pb);
|
|
23
68
|
}
|
|
24
69
|
restrictor.one = one;
|
|
25
|
-
})(restrictor || (restrictor = {}));
|
|
70
|
+
})(restrictor || (restrictor = {}));
|
package/esm/index.d.ts
CHANGED
|
@@ -32,8 +32,8 @@ export declare class Deque<T extends any> {
|
|
|
32
32
|
/**
|
|
33
33
|
* @param s subject
|
|
34
34
|
*/
|
|
35
|
-
push(s: T):
|
|
36
|
-
shift(): T | undefined;
|
|
35
|
+
push(s: T): void;
|
|
36
|
+
// shift(): T | undefined;
|
|
37
37
|
clear(): void;
|
|
38
38
|
get length(): number;
|
|
39
39
|
}
|
|
@@ -94,8 +94,8 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
|
|
|
94
94
|
readonly q: Deque<T>;
|
|
95
95
|
};
|
|
96
96
|
export declare type TVoidFunction = () => void;
|
|
97
|
-
export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
-
export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
97
|
+
// export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
+
// export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
/**
|
|
@@ -173,6 +173,14 @@ export declare class MiniSemaphore implements TFlowableLock {
|
|
|
173
173
|
export declare const create: (capacity: number) => IFlowableLock;
|
|
174
174
|
|
|
175
175
|
declare namespace fr {
|
|
176
|
+
/**
|
|
177
|
+
* Eliminate unused instances for the `timeSpan` seconds
|
|
178
|
+
*
|
|
179
|
+
* @param timeSpan specify unit as seconds
|
|
180
|
+
* @returns {Promise<number>} eliminated count
|
|
181
|
+
* @date 2020/6/19
|
|
182
|
+
*/
|
|
183
|
+
const cleanup: (timeSpan: number, debug?: true | undefined) => Promise<number>;
|
|
176
184
|
/**
|
|
177
185
|
* get the semaphore associated with the value of `key`
|
|
178
186
|
*
|
|
@@ -181,7 +189,7 @@ declare namespace fr {
|
|
|
181
189
|
* @param key
|
|
182
190
|
* @returns `IFlowableLock` instance or `undefined`
|
|
183
191
|
*/
|
|
184
|
-
export const getLockByKey: (key: string | number) => IFlowableLock
|
|
192
|
+
export const getLockByKey: (key: string | number) => Promise<IFlowableLock>;
|
|
185
193
|
/**
|
|
186
194
|
* Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`
|
|
187
195
|
*
|
package/esm/index.js
CHANGED
package/esm/object.js
CHANGED
package/index.d.ts
CHANGED
|
@@ -32,8 +32,8 @@ export declare class Deque<T extends any> {
|
|
|
32
32
|
/**
|
|
33
33
|
* @param s subject
|
|
34
34
|
*/
|
|
35
|
-
push(s: T):
|
|
36
|
-
shift(): T | undefined;
|
|
35
|
+
push(s: T): void;
|
|
36
|
+
// shift(): T | undefined;
|
|
37
37
|
clear(): void;
|
|
38
38
|
get length(): number;
|
|
39
39
|
}
|
|
@@ -94,8 +94,8 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
|
|
|
94
94
|
readonly q: Deque<T>;
|
|
95
95
|
};
|
|
96
96
|
export declare type TVoidFunction = () => void;
|
|
97
|
-
export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
-
export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
97
|
+
// export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
+
// export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
/**
|
|
@@ -173,6 +173,14 @@ export declare class MiniSemaphore implements TFlowableLock {
|
|
|
173
173
|
export declare const create: (capacity: number) => IFlowableLock;
|
|
174
174
|
|
|
175
175
|
declare namespace fr {
|
|
176
|
+
/**
|
|
177
|
+
* Eliminate unused instances for the `timeSpan` seconds
|
|
178
|
+
*
|
|
179
|
+
* @param timeSpan specify unit as seconds
|
|
180
|
+
* @returns {Promise<number>} eliminated count
|
|
181
|
+
* @date 2020/6/19
|
|
182
|
+
*/
|
|
183
|
+
const cleanup: (timeSpan: number, debug?: true | undefined) => Promise<number>;
|
|
176
184
|
/**
|
|
177
185
|
* get the semaphore associated with the value of `key`
|
|
178
186
|
*
|
|
@@ -181,7 +189,7 @@ declare namespace fr {
|
|
|
181
189
|
* @param key
|
|
182
190
|
* @returns `IFlowableLock` instance or `undefined`
|
|
183
191
|
*/
|
|
184
|
-
export const getLockByKey: (key: string | number) => IFlowableLock
|
|
192
|
+
export const getLockByKey: (key: string | number) => Promise<IFlowableLock>;
|
|
185
193
|
/**
|
|
186
194
|
* Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`
|
|
187
195
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mini-semaphore",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "A lightweight version of Semaphore",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "./cjs/index.js",
|
|
@@ -19,6 +19,10 @@
|
|
|
19
19
|
"type": "git",
|
|
20
20
|
"url": "git+https://github.com/jeffy-g/mini-semaphore.git"
|
|
21
21
|
},
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=10",
|
|
24
|
+
"yarn": "^1.22.4"
|
|
25
|
+
},
|
|
22
26
|
"files": [
|
|
23
27
|
"package.json",
|
|
24
28
|
"README.md",
|
|
@@ -37,36 +41,5 @@
|
|
|
37
41
|
"concurrency",
|
|
38
42
|
"javascript",
|
|
39
43
|
"typescript"
|
|
40
|
-
]
|
|
41
|
-
|
|
42
|
-
"all": "yarn clean && yarn lint && yarn dist && yarn webpack && yarn copy:types",
|
|
43
|
-
"build": "tsc",
|
|
44
|
-
"build:esm": "tsc -p src/tsconfig.json && node ./scripts/tools -cmd rmc -basePath ./build/esm -test \"/.js$/\"",
|
|
45
|
-
"clean": "rimraf build/* dist/* logs/*.tsbuildinfo",
|
|
46
|
-
"copy:types": "cpx src/index.d.ts dist -v && cpx src/index.d.ts dist/cjs -v && cpx src/index.d.ts dist/esm -v && cpx src/index.d.ts dist/umd -v && cpx src/index.d.ts dist/webpack -v",
|
|
47
|
-
"dist": "rimraf dist/!(webpack) && yarn build && yarn build:esm && cpx ./{package.json,README.md,LICENSE} dist -v && cpx \"./build/**/*.js\" dist -v",
|
|
48
|
-
"inst:clean": "rimraf yarn.lock node_modules && yarn install",
|
|
49
|
-
"lint": "eslint src/**/*.ts",
|
|
50
|
-
"test": "jest --coverage --silent=false -c=jest.config.js",
|
|
51
|
-
"update:packages": "yarn upgrade-interactive --latest",
|
|
52
|
-
"webpack": "rimraf ./dist/webpack/* ./dist/umd/* && npx webpack && cpx ./dist/*.d.ts ./dist/webpack/ -v"
|
|
53
|
-
},
|
|
54
|
-
"devDependencies": {
|
|
55
|
-
"@types/jest": "^25.1.4",
|
|
56
|
-
"@types/webpack": "^4.41.6",
|
|
57
|
-
"@typescript-eslint/eslint-plugin": "^2.23.0",
|
|
58
|
-
"@typescript-eslint/eslint-plugin-tslint": "^2.23.0",
|
|
59
|
-
"@typescript-eslint/parser": "^2.23.0",
|
|
60
|
-
"cpx": "latest",
|
|
61
|
-
"eslint": "^6.8.0",
|
|
62
|
-
"jest": "^25.1.0",
|
|
63
|
-
"rimraf": "^3.0.2",
|
|
64
|
-
"rm-cstyle-cmts": "latest",
|
|
65
|
-
"terser-webpack-plugin": "^2.3.5",
|
|
66
|
-
"ts-jest": "^25.2.1",
|
|
67
|
-
"ts-loader": "^6.2.1",
|
|
68
|
-
"typescript": "^3.8.3",
|
|
69
|
-
"webpack": "^4.42.0",
|
|
70
|
-
"webpack-cli": "^3.3.11"
|
|
71
|
-
}
|
|
72
|
-
}
|
|
44
|
+
]
|
|
45
|
+
}
|
package/umd/index.d.ts
CHANGED
|
@@ -32,8 +32,8 @@ export declare class Deque<T extends any> {
|
|
|
32
32
|
/**
|
|
33
33
|
* @param s subject
|
|
34
34
|
*/
|
|
35
|
-
push(s: T):
|
|
36
|
-
shift(): T | undefined;
|
|
35
|
+
push(s: T): void;
|
|
36
|
+
// shift(): T | undefined;
|
|
37
37
|
clear(): void;
|
|
38
38
|
get length(): number;
|
|
39
39
|
}
|
|
@@ -94,8 +94,8 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
|
|
|
94
94
|
readonly q: Deque<T>;
|
|
95
95
|
};
|
|
96
96
|
export declare type TVoidFunction = () => void;
|
|
97
|
-
export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
-
export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
97
|
+
// export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
+
// export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
/**
|
|
@@ -173,6 +173,14 @@ export declare class MiniSemaphore implements TFlowableLock {
|
|
|
173
173
|
export declare const create: (capacity: number) => IFlowableLock;
|
|
174
174
|
|
|
175
175
|
declare namespace fr {
|
|
176
|
+
/**
|
|
177
|
+
* Eliminate unused instances for the `timeSpan` seconds
|
|
178
|
+
*
|
|
179
|
+
* @param timeSpan specify unit as seconds
|
|
180
|
+
* @returns {Promise<number>} eliminated count
|
|
181
|
+
* @date 2020/6/19
|
|
182
|
+
*/
|
|
183
|
+
const cleanup: (timeSpan: number, debug?: true | undefined) => Promise<number>;
|
|
176
184
|
/**
|
|
177
185
|
* get the semaphore associated with the value of `key`
|
|
178
186
|
*
|
|
@@ -181,7 +189,7 @@ declare namespace fr {
|
|
|
181
189
|
* @param key
|
|
182
190
|
* @returns `IFlowableLock` instance or `undefined`
|
|
183
191
|
*/
|
|
184
|
-
export const getLockByKey: (key: string | number) => IFlowableLock
|
|
192
|
+
export const getLockByKey: (key: string | number) => Promise<IFlowableLock>;
|
|
185
193
|
/**
|
|
186
194
|
* Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`
|
|
187
195
|
*
|
package/umd/index.js
CHANGED
|
@@ -1,84 +1,54 @@
|
|
|
1
1
|
!function(t, e) {
|
|
2
2
|
'object' == typeof exports && 'object' == typeof module ? module.exports = e() : 'function' == typeof define && define.amd ? define([], e) : 'object' == typeof exports ? exports.MiniSema = e() : t.MiniSema = e();
|
|
3
|
-
}(
|
|
4
|
-
return
|
|
5
|
-
var e = {};
|
|
6
|
-
function i(n) {
|
|
7
|
-
if (e[n]) return e[n].exports;
|
|
8
|
-
var r = e[n] = {
|
|
9
|
-
i: n,
|
|
10
|
-
l: !1,
|
|
11
|
-
exports: {}
|
|
12
|
-
};
|
|
13
|
-
return t[n].call(r.exports, r, r.exports, i), r.l = !0, r.exports;
|
|
14
|
-
}
|
|
15
|
-
return i.m = t, i.c = e, i.d = function(t, e, n) {
|
|
16
|
-
i.o(t, e) || Object.defineProperty(t, e, {
|
|
17
|
-
enumerable: !0,
|
|
18
|
-
get: n
|
|
19
|
-
});
|
|
20
|
-
}, i.r = function(t) {
|
|
21
|
-
'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {
|
|
22
|
-
value: 'Module'
|
|
23
|
-
}), Object.defineProperty(t, '__esModule', {
|
|
24
|
-
value: !0
|
|
25
|
-
});
|
|
26
|
-
}, i.t = function(t, e) {
|
|
27
|
-
if (1 & e && (t = i(t)), 8 & e) return t;
|
|
28
|
-
if (4 & e && 'object' == typeof t && t && t.__esModule) return t;
|
|
29
|
-
var n = Object.create(null);
|
|
30
|
-
if (i.r(n), Object.defineProperty(n, 'default', {
|
|
31
|
-
enumerable: !0,
|
|
32
|
-
value: t
|
|
33
|
-
}), 2 & e && 'string' != typeof t) for (var r in t) i.d(n, r, function(e) {
|
|
34
|
-
return t[e];
|
|
35
|
-
}.bind(null, r));
|
|
36
|
-
return n;
|
|
37
|
-
}, i.n = function(t) {
|
|
38
|
-
var e = t && t.__esModule ? function() {
|
|
39
|
-
return t.default;
|
|
40
|
-
} : function() {
|
|
41
|
-
return t;
|
|
42
|
-
};
|
|
43
|
-
return i.d(e, 'a', e), e;
|
|
44
|
-
}, i.o = function(t, e) {
|
|
45
|
-
return Object.prototype.hasOwnProperty.call(t, e);
|
|
46
|
-
}, i.p = "", i(i.s = 0);
|
|
47
|
-
}([ function(t, e, i) {
|
|
3
|
+
}(self, (function() {
|
|
4
|
+
return (() => {
|
|
48
5
|
"use strict";
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
6
|
+
var t = {
|
|
7
|
+
d: (e, i) => {
|
|
8
|
+
for (var n in i) t.o(i, n) && !t.o(e, n) && Object.defineProperty(e, n, {
|
|
9
|
+
enumerable: !0,
|
|
10
|
+
get: i[n]
|
|
11
|
+
});
|
|
12
|
+
},
|
|
13
|
+
o: (t, e) => Object.prototype.hasOwnProperty.call(t, e),
|
|
14
|
+
r: t => {
|
|
15
|
+
'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {
|
|
16
|
+
value: 'Module'
|
|
17
|
+
}), Object.defineProperty(t, '__esModule', {
|
|
18
|
+
value: !0
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}, e = {};
|
|
22
|
+
t.r(e), t.d(e, {
|
|
23
|
+
Deque: () => o,
|
|
24
|
+
MiniSemaphore: () => f,
|
|
25
|
+
create: () => m,
|
|
26
|
+
restrictor: () => _
|
|
27
|
+
});
|
|
28
|
+
var i = {};
|
|
29
|
+
t.r(i), t.d(i, {
|
|
30
|
+
MiniSemaphore: () => f
|
|
31
|
+
});
|
|
32
|
+
const n = () => {
|
|
63
33
|
throw new Error("mini-semaphore: inconsistent occurred");
|
|
64
|
-
},
|
|
34
|
+
}, r = (t, e) => {
|
|
65
35
|
t.capacity > 0 ? (t.capacity--, e()) : t.q.push(e);
|
|
66
|
-
},
|
|
67
|
-
e ? setTimeout(() =>
|
|
68
|
-
}),
|
|
69
|
-
t.capacity++, t.q.length && (t.capacity -= 1, (t.q.shift() ||
|
|
36
|
+
}, s = (t, e = !0) => new Promise((i => {
|
|
37
|
+
e ? setTimeout((() => r(t, i)), 4) : r(t, i);
|
|
38
|
+
})), a = t => {
|
|
39
|
+
t.capacity++, t.q.length && (t.capacity -= 1, (t.q.shift() || n)()), t.capacity > t.limit && (console.warn("inconsistent release!"),
|
|
70
40
|
t.capacity = t.limit);
|
|
71
|
-
},
|
|
72
|
-
(t |= t >> 16)
|
|
73
|
-
class
|
|
41
|
+
}, c = t => (t => (t >>>= 0, t -= 1, t |= t >> 1, t |= t >> 2, t |= t >> 4, t |= t >> 8,
|
|
42
|
+
1 + (t |= t >> 16)))(Math.min(Math.max(16, 0 | t), 1073741824));
|
|
43
|
+
class o {
|
|
74
44
|
constructor(t) {
|
|
75
|
-
this._c =
|
|
45
|
+
this._c = c(t), this._l = 0, this._f = 0, this._a = [];
|
|
76
46
|
}
|
|
77
47
|
push(t) {
|
|
78
48
|
const e = this._l;
|
|
79
|
-
this._c < e + 1 && l(this,
|
|
49
|
+
this._c < e + 1 && l(this, c(1.5 * this._c + 16));
|
|
80
50
|
const i = this._f + e & this._c - 1;
|
|
81
|
-
|
|
51
|
+
this._a[i] = t, this._l = e + 1;
|
|
82
52
|
}
|
|
83
53
|
shift() {
|
|
84
54
|
const t = this._l;
|
|
@@ -86,11 +56,6 @@
|
|
|
86
56
|
const e = this._f, i = this._a[e];
|
|
87
57
|
return this._a[e] = void 0, this._f = e + 1 & this._c - 1, this._l = t - 1, i;
|
|
88
58
|
}
|
|
89
|
-
clear() {
|
|
90
|
-
const t = this._l, e = this._f, i = this._c, n = this._a;
|
|
91
|
-
for (let r = 0; r < t; ++r) n[e + r & i - 1] = void 0;
|
|
92
|
-
this._l = 0, this._f = 0;
|
|
93
|
-
}
|
|
94
59
|
get length() {
|
|
95
60
|
return this._l;
|
|
96
61
|
}
|
|
@@ -102,19 +67,19 @@
|
|
|
102
67
|
if (n + r > i) {
|
|
103
68
|
const e = n + r & i - 1;
|
|
104
69
|
((t, e, i, n, r) => {
|
|
105
|
-
for (let
|
|
70
|
+
for (let s = 0; s < r; ++s) i[s + n] = t[s + e], t[s + e] = void 0;
|
|
106
71
|
})(t._a, 0, t._a, i, e);
|
|
107
72
|
}
|
|
108
|
-
},
|
|
109
|
-
class
|
|
73
|
+
}, h = s, u = a;
|
|
74
|
+
class f {
|
|
110
75
|
constructor(t) {
|
|
111
|
-
this.limit = this.capacity = t, this.q = new
|
|
76
|
+
this.limit = this.capacity = t, this.q = new o(t);
|
|
112
77
|
}
|
|
113
78
|
acquire(t) {
|
|
114
|
-
return
|
|
79
|
+
return h(this, t);
|
|
115
80
|
}
|
|
116
81
|
release() {
|
|
117
|
-
|
|
82
|
+
u(this);
|
|
118
83
|
}
|
|
119
84
|
setRestriction(t) {
|
|
120
85
|
this.limit = this.capacity = t;
|
|
@@ -123,23 +88,23 @@
|
|
|
123
88
|
return this.q.length;
|
|
124
89
|
}
|
|
125
90
|
async flow(t, e) {
|
|
126
|
-
await
|
|
91
|
+
await h(this, e);
|
|
127
92
|
try {
|
|
128
93
|
return await t();
|
|
129
94
|
} finally {
|
|
130
|
-
|
|
95
|
+
u(this);
|
|
131
96
|
}
|
|
132
97
|
}
|
|
133
98
|
}
|
|
134
|
-
const y =
|
|
99
|
+
const y = s, p = a, m = t => ({
|
|
135
100
|
capacity: t,
|
|
136
101
|
limit: t,
|
|
137
|
-
q: new
|
|
102
|
+
q: new o(t),
|
|
138
103
|
acquire(t) {
|
|
139
104
|
return y(this, t);
|
|
140
105
|
},
|
|
141
106
|
release() {
|
|
142
|
-
|
|
107
|
+
p(this);
|
|
143
108
|
},
|
|
144
109
|
setRestriction(t) {
|
|
145
110
|
this.limit = this.capacity = t;
|
|
@@ -152,22 +117,42 @@
|
|
|
152
117
|
try {
|
|
153
118
|
return await t();
|
|
154
119
|
} finally {
|
|
155
|
-
|
|
120
|
+
p(this);
|
|
156
121
|
}
|
|
157
122
|
}
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
123
|
+
});
|
|
124
|
+
var _;
|
|
125
|
+
return function(t) {
|
|
126
|
+
const {MiniSemaphore: e} = i, n = new e(1);
|
|
127
|
+
let r = Object.create(null);
|
|
128
|
+
async function s(t, i, s) {
|
|
129
|
+
const a = await (async (t, i) => {
|
|
130
|
+
await n.acquire(!1);
|
|
131
|
+
let s = r[t];
|
|
132
|
+
if (s || (r[t] = s = new e(i)), s.limit !== i) throw n.release(), new ReferenceError(`Cannot get object with different restriction: key: '${t}', lock.limit: ${s.limit} <-> restriction: ${i},`);
|
|
133
|
+
return n.release(), s;
|
|
134
|
+
})(t, i), c = a.flow(s);
|
|
135
|
+
return a.last = Date.now(), c;
|
|
136
|
+
}
|
|
137
|
+
t.getLockByKey = async t => {
|
|
138
|
+
await n.acquire(!1);
|
|
139
|
+
const e = r[t];
|
|
140
|
+
return n.release(), e;
|
|
141
|
+
}, t.cleanup = async (t, e) => {
|
|
142
|
+
await n.acquire(!1);
|
|
143
|
+
const i = r, s = Object.create(null), a = Object.keys(i);
|
|
144
|
+
let c, o = 0;
|
|
145
|
+
!t && (t = 1), t *= 1e3, e && (c = []);
|
|
146
|
+
for (let n = 0, r = a.length; n < r; ) {
|
|
147
|
+
const r = a[n++], l = i[r];
|
|
148
|
+
l.last && Date.now() - l.last >= t ? (o++, e && c.push(r)) : s[r] = l;
|
|
149
|
+
}
|
|
150
|
+
return r = s, n.release(), e && console.log(`eliminated: [\n${c.join(",\n")}\n]\nlived: [\n${Object.keys(s).join(",\n")}\n]`),
|
|
151
|
+
o;
|
|
152
|
+
}, t.multi = s, t.one = async function(t, e) {
|
|
153
|
+
return s(t, 1, e);
|
|
169
154
|
};
|
|
170
|
-
}(
|
|
171
|
-
}
|
|
155
|
+
}(_ || (_ = {})), e;
|
|
156
|
+
})();
|
|
172
157
|
}));
|
|
173
158
|
//# sourceMappingURL=index.js.map
|
package/umd/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["webpack://MiniSema/
|
|
1
|
+
{"version":3,"file":"index.js","mappings":"AAAA;AACA;AADA;AAUA;;ACTA;ACAA;AACA;AAEA;AAAA;;;ACJA;ACCA;AACA;AACA;AAEA;AAAA;;;;;;;;;;;;;;ACLA;AACA;ACAA;AACA;AAOA;AAEA;AAQA;AACA;AAMA;ACVA;AAFA;AAKA;AACA;AACA;;AAKA;AACA;AACA;AAGA;AACA;;AAGA;AACA;AACA;AAGA;AAKA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AAEA;AACA;AAzDA;AACA;AAyDA;;ACxDA;AAEA;AACA;AACA;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;ACzBA;AAIA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;AC1BA;;AAEA;AAEA;AAqDA;AACA;AApDA;AACA;AAIA;AAKA;AA0CA;AAGA;;AA3CA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AAEA;AAKA;AACA;AAEA;;AAgBA;AAAA;AAQA;AAEA;;AAhEA;AVQA","sources":["webpack://MiniSema/webpack/universalModuleDefinition","webpack://MiniSema/webpack/bootstrap","webpack://MiniSema/webpack/runtime/define property getters","webpack://MiniSema/webpack/runtime/hasOwnProperty shorthand","webpack://MiniSema/webpack/runtime/make namespace object","webpack://MiniSema/./src/extras.ts","webpack://MiniSema/./src/core.ts","webpack://MiniSema/./src/deque.ts","webpack://MiniSema/./src/class.ts","webpack://MiniSema/./src/object.ts","webpack://MiniSema/./src/flow-restrictor.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"MiniSema\"] = factory();\n\telse\n\t\troot[\"MiniSema\"] = factory();\n})(self, function() {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export const THROW = () => {\r\n throw new Error(\"mini-semaphore: inconsistent occurred\");\r\n};\r\n","import { THROW } from \"./extras\";\r\nconst box = (z, r) => {\r\n if (z.capacity > 0) {\r\n z.capacity--, r();\r\n }\r\n else {\r\n z.q.push(r);\r\n }\r\n};\r\nexport const acquire = (dis, lazy = true) => {\r\n return new Promise(r => {\r\n if (!lazy) {\r\n box(dis, r);\r\n }\r\n else {\r\n setTimeout(() => box(dis, r), 4);\r\n }\r\n });\r\n};\r\nexport const release = (dis) => {\r\n dis.capacity++;\r\n if (dis.q.length) {\r\n dis.capacity -= 1, (dis.q.shift() || THROW)();\r\n }\r\n if (dis.capacity > dis.limit) {\r\n console.warn(\"inconsistent release!\");\r\n dis.capacity = dis.limit;\r\n }\r\n};\r\n","const am = (src, si, dst, di, len) => {\r\n for (let j = 0; j < len; ++j) {\r\n dst[j + di] = src[j + si];\r\n src[j + si] = void 0;\r\n }\r\n};\r\nconst p2l = (n) => {\r\n n = n >>> 0;\r\n n = n - 1;\r\n n = n | (n >> 1);\r\n n = n | (n >> 2);\r\n n = n | (n >> 4);\r\n n = n | (n >> 8);\r\n n = n | (n >> 16);\r\n return n + 1;\r\n};\r\nconst gc = (n) => {\r\n return p2l(Math.min(Math.max(16, n | 0), 1073741824));\r\n};\r\nexport class Deque {\r\n constructor(ic) {\r\n this._c = gc(ic);\r\n this._l = 0;\r\n this._f = 0;\r\n this._a = [];\r\n }\r\n push(s) {\r\n const l = this._l;\r\n if (this._c < l + 1) {\r\n rt(this, gc(this._c * 1.5 + 16));\r\n }\r\n const i = (this._f + l) & (this._c - 1);\r\n this._a[i] = s;\r\n this._l = l + 1;\r\n }\r\n shift() {\r\n const l = this._l;\r\n if (l === 0) {\r\n return void 0;\r\n }\r\n const f = this._f;\r\n const r = this._a[f];\r\n this._a[f] = void 0;\r\n this._f = (f + 1) & (this._c - 1);\r\n this._l = l - 1;\r\n return r;\r\n }\r\n get length() {\r\n return this._l;\r\n }\r\n}\r\nconst rt = (dis, n) => {\r\n const oc = dis._c;\r\n dis._c = n;\r\n const f = dis._f;\r\n const l = dis._l;\r\n if (f + l > oc) {\r\n const mc = (f + l) & (oc - 1);\r\n am(dis._a, 0, dis._a, oc, mc);\r\n }\r\n};\r\n","import * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\nconst a = core.acquire;\r\nconst r = core.release;\r\nexport class MiniSemaphore {\r\n constructor(capacity) {\r\n this.limit = this.capacity = capacity;\r\n this.q = new Deque(capacity);\r\n }\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n }\r\n release() {\r\n r(this);\r\n }\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n }\r\n get pending() {\r\n return this.q.length;\r\n }\r\n async flow(process, lazy) {\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n }\r\n}\r\n","import * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\nconst a = core.acquire;\r\nconst r = core.release;\r\nexport const create = (capacity) => {\r\n return {\r\n capacity,\r\n limit: capacity,\r\n q: new Deque(capacity),\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n },\r\n release() {\r\n r(this);\r\n },\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n },\r\n get pending() {\r\n return this.q.length;\r\n },\r\n async flow(process, lazy) {\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n }\r\n };\r\n};\r\n","import * as c from \"./class\";\r\nexport var restrictor;\r\n(function (restrictor) {\r\n const { MiniSemaphore: MS } = c;\r\n const internalLock = new MS(1);\r\n let locks = Object.create(null);\r\n const get = async (key, restriction) => {\r\n await internalLock.acquire(false);\r\n let lock = locks[key];\r\n if (!lock) {\r\n locks[key] = lock = new MS(restriction);\r\n }\r\n if (lock.limit !== restriction) {\r\n internalLock.release();\r\n throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);\r\n }\r\n internalLock.release();\r\n return lock;\r\n };\r\n restrictor.getLockByKey = async (key) => {\r\n await internalLock.acquire(false);\r\n const l = locks[key];\r\n internalLock.release();\r\n return l;\r\n };\r\n restrictor.cleanup = async (timeSpan, debug) => {\r\n await internalLock.acquire(false);\r\n const currentLocks = locks;\r\n const newLocks = Object.create(null);\r\n const keys = Object.keys(currentLocks);\r\n let eliminatedCount = 0;\r\n let eliminatedKeys;\r\n !timeSpan && (timeSpan = 1);\r\n timeSpan *= 1000;\r\n if (debug) {\r\n eliminatedKeys = [];\r\n }\r\n for (let i = 0, end = keys.length; i < end;) {\r\n const key = keys[i++];\r\n const s = currentLocks[key];\r\n if (s.last && Date.now() - s.last >= timeSpan) {\r\n eliminatedCount++;\r\n if (debug) {\r\n eliminatedKeys.push(key);\r\n }\r\n continue;\r\n }\r\n newLocks[key] = s;\r\n }\r\n locks = newLocks;\r\n internalLock.release();\r\n if (debug) {\r\n console.log(`eliminated: [\\n${eliminatedKeys.join(\",\\n\")}\\n]` +\r\n \"\\n\" +\r\n `lived: [\\n${Object.keys(newLocks).join(\",\\n\")}\\n]`);\r\n }\r\n return eliminatedCount;\r\n };\r\n async function multi(key, restriction, pb) {\r\n const s = await get(key, restriction);\r\n const result = s.flow(pb);\r\n s.last = Date.now();\r\n return result;\r\n }\r\n restrictor.multi = multi;\r\n async function one(key, pb) {\r\n return multi(key, 1, pb);\r\n }\r\n restrictor.one = one;\r\n})(restrictor || (restrictor = {}));\r\n"],"names":[],"sourceRoot":""}
|
package/webpack/index.d.ts
CHANGED
|
@@ -32,8 +32,8 @@ export declare class Deque<T extends any> {
|
|
|
32
32
|
/**
|
|
33
33
|
* @param s subject
|
|
34
34
|
*/
|
|
35
|
-
push(s: T):
|
|
36
|
-
shift(): T | undefined;
|
|
35
|
+
push(s: T): void;
|
|
36
|
+
// shift(): T | undefined;
|
|
37
37
|
clear(): void;
|
|
38
38
|
get length(): number;
|
|
39
39
|
}
|
|
@@ -94,8 +94,8 @@ export declare type TFlowableLock<T = TVoidFunction> = IFlowableLock & {
|
|
|
94
94
|
readonly q: Deque<T>;
|
|
95
95
|
};
|
|
96
96
|
export declare type TVoidFunction = () => void;
|
|
97
|
-
export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
-
export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
97
|
+
// export declare const acquire: (dis: TFlowableLock<TVoidFunction>, lazy?: boolean) => Promise<void>;
|
|
98
|
+
// export declare const release: (dis: TFlowableLock<TVoidFunction>) => void;
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
/**
|
|
@@ -173,6 +173,14 @@ export declare class MiniSemaphore implements TFlowableLock {
|
|
|
173
173
|
export declare const create: (capacity: number) => IFlowableLock;
|
|
174
174
|
|
|
175
175
|
declare namespace fr {
|
|
176
|
+
/**
|
|
177
|
+
* Eliminate unused instances for the `timeSpan` seconds
|
|
178
|
+
*
|
|
179
|
+
* @param timeSpan specify unit as seconds
|
|
180
|
+
* @returns {Promise<number>} eliminated count
|
|
181
|
+
* @date 2020/6/19
|
|
182
|
+
*/
|
|
183
|
+
const cleanup: (timeSpan: number, debug?: true | undefined) => Promise<number>;
|
|
176
184
|
/**
|
|
177
185
|
* get the semaphore associated with the value of `key`
|
|
178
186
|
*
|
|
@@ -181,7 +189,7 @@ declare namespace fr {
|
|
|
181
189
|
* @param key
|
|
182
190
|
* @returns `IFlowableLock` instance or `undefined`
|
|
183
191
|
*/
|
|
184
|
-
export const getLockByKey: (key: string | number) => IFlowableLock
|
|
192
|
+
export const getLockByKey: (key: string | number) => Promise<IFlowableLock>;
|
|
185
193
|
/**
|
|
186
194
|
* Allocate a semaphore for each `key`, and limit the number of shares with the value of `restriction`
|
|
187
195
|
*
|
package/webpack/index.js
CHANGED
|
@@ -1,81 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
var e = {};
|
|
3
|
-
function i(n) {
|
|
4
|
-
if (e[n]) return e[n].exports;
|
|
5
|
-
var r = e[n] = {
|
|
6
|
-
i: n,
|
|
7
|
-
l: !1,
|
|
8
|
-
exports: {}
|
|
9
|
-
};
|
|
10
|
-
return t[n].call(r.exports, r, r.exports, i), r.l = !0, r.exports;
|
|
11
|
-
}
|
|
12
|
-
return i.m = t, i.c = e, i.d = function(t, e, n) {
|
|
13
|
-
i.o(t, e) || Object.defineProperty(t, e, {
|
|
14
|
-
enumerable: !0,
|
|
15
|
-
get: n
|
|
16
|
-
});
|
|
17
|
-
}, i.r = function(t) {
|
|
18
|
-
'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {
|
|
19
|
-
value: 'Module'
|
|
20
|
-
}), Object.defineProperty(t, '__esModule', {
|
|
21
|
-
value: !0
|
|
22
|
-
});
|
|
23
|
-
}, i.t = function(t, e) {
|
|
24
|
-
if (1 & e && (t = i(t)), 8 & e) return t;
|
|
25
|
-
if (4 & e && 'object' == typeof t && t && t.__esModule) return t;
|
|
26
|
-
var n = Object.create(null);
|
|
27
|
-
if (i.r(n), Object.defineProperty(n, 'default', {
|
|
28
|
-
enumerable: !0,
|
|
29
|
-
value: t
|
|
30
|
-
}), 2 & e && 'string' != typeof t) for (var r in t) i.d(n, r, function(e) {
|
|
31
|
-
return t[e];
|
|
32
|
-
}.bind(null, r));
|
|
33
|
-
return n;
|
|
34
|
-
}, i.n = function(t) {
|
|
35
|
-
var e = t && t.__esModule ? function() {
|
|
36
|
-
return t.default;
|
|
37
|
-
} : function() {
|
|
38
|
-
return t;
|
|
39
|
-
};
|
|
40
|
-
return i.d(e, 'a', e), e;
|
|
41
|
-
}, i.o = function(t, e) {
|
|
42
|
-
return Object.prototype.hasOwnProperty.call(t, e);
|
|
43
|
-
}, i.p = "", i(i.s = 0);
|
|
44
|
-
}([ function(t, e, i) {
|
|
1
|
+
(() => {
|
|
45
2
|
"use strict";
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
3
|
+
var t = {
|
|
4
|
+
d: (e, i) => {
|
|
5
|
+
for (var n in i) t.o(i, n) && !t.o(e, n) && Object.defineProperty(e, n, {
|
|
6
|
+
enumerable: !0,
|
|
7
|
+
get: i[n]
|
|
8
|
+
});
|
|
9
|
+
},
|
|
10
|
+
o: (t, e) => Object.prototype.hasOwnProperty.call(t, e),
|
|
11
|
+
r: t => {
|
|
12
|
+
'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {
|
|
13
|
+
value: 'Module'
|
|
14
|
+
}), Object.defineProperty(t, '__esModule', {
|
|
15
|
+
value: !0
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}, e = {};
|
|
19
|
+
t.r(e), t.d(e, {
|
|
20
|
+
Deque: () => o,
|
|
21
|
+
MiniSemaphore: () => y,
|
|
22
|
+
create: () => _,
|
|
23
|
+
restrictor: () => m
|
|
24
|
+
});
|
|
25
|
+
var i = {};
|
|
26
|
+
t.r(i), t.d(i, {
|
|
27
|
+
MiniSemaphore: () => y
|
|
28
|
+
});
|
|
29
|
+
const n = () => {
|
|
60
30
|
throw new Error("mini-semaphore: inconsistent occurred");
|
|
61
31
|
}, s = (t, e) => {
|
|
62
32
|
t.capacity > 0 ? (t.capacity--, e()) : t.q.push(e);
|
|
63
|
-
},
|
|
64
|
-
e ? setTimeout(() => s(t, i), 4) : s(t, i);
|
|
65
|
-
}),
|
|
66
|
-
t.capacity++, t.q.length && (t.capacity -= 1, (t.q.shift() ||
|
|
33
|
+
}, r = (t, e = !0) => new Promise((i => {
|
|
34
|
+
e ? setTimeout((() => s(t, i)), 4) : s(t, i);
|
|
35
|
+
})), a = t => {
|
|
36
|
+
t.capacity++, t.q.length && (t.capacity -= 1, (t.q.shift() || n)()), t.capacity > t.limit && (console.warn("inconsistent release!"),
|
|
67
37
|
t.capacity = t.limit);
|
|
68
|
-
},
|
|
69
|
-
(t |= t >> 16)
|
|
70
|
-
class
|
|
38
|
+
}, c = t => (t => (t >>>= 0, t -= 1, t |= t >> 1, t |= t >> 2, t |= t >> 4, t |= t >> 8,
|
|
39
|
+
1 + (t |= t >> 16)))(Math.min(Math.max(16, 0 | t), 1073741824));
|
|
40
|
+
class o {
|
|
71
41
|
constructor(t) {
|
|
72
|
-
this._c =
|
|
42
|
+
this._c = c(t), this._l = 0, this._f = 0, this._a = [];
|
|
73
43
|
}
|
|
74
44
|
push(t) {
|
|
75
45
|
const e = this._l;
|
|
76
|
-
this._c < e + 1 && l(this,
|
|
46
|
+
this._c < e + 1 && l(this, c(1.5 * this._c + 16));
|
|
77
47
|
const i = this._f + e & this._c - 1;
|
|
78
|
-
|
|
48
|
+
this._a[i] = t, this._l = e + 1;
|
|
79
49
|
}
|
|
80
50
|
shift() {
|
|
81
51
|
const t = this._l;
|
|
@@ -83,11 +53,6 @@ module.exports = function(t) {
|
|
|
83
53
|
const e = this._f, i = this._a[e];
|
|
84
54
|
return this._a[e] = void 0, this._f = e + 1 & this._c - 1, this._l = t - 1, i;
|
|
85
55
|
}
|
|
86
|
-
clear() {
|
|
87
|
-
const t = this._l, e = this._f, i = this._c, n = this._a;
|
|
88
|
-
for (let r = 0; r < t; ++r) n[e + r & i - 1] = void 0;
|
|
89
|
-
this._l = 0, this._f = 0;
|
|
90
|
-
}
|
|
91
56
|
get length() {
|
|
92
57
|
return this._l;
|
|
93
58
|
}
|
|
@@ -95,23 +60,23 @@ module.exports = function(t) {
|
|
|
95
60
|
const l = (t, e) => {
|
|
96
61
|
const i = t._c;
|
|
97
62
|
t._c = e;
|
|
98
|
-
const n = t._f,
|
|
99
|
-
if (n +
|
|
100
|
-
const e = n +
|
|
101
|
-
((t, e, i, n,
|
|
102
|
-
for (let
|
|
63
|
+
const n = t._f, s = t._l;
|
|
64
|
+
if (n + s > i) {
|
|
65
|
+
const e = n + s & i - 1;
|
|
66
|
+
((t, e, i, n, s) => {
|
|
67
|
+
for (let r = 0; r < s; ++r) i[r + n] = t[r + e], t[r + e] = void 0;
|
|
103
68
|
})(t._a, 0, t._a, i, e);
|
|
104
69
|
}
|
|
105
|
-
}, h =
|
|
106
|
-
class
|
|
70
|
+
}, h = r, u = a;
|
|
71
|
+
class y {
|
|
107
72
|
constructor(t) {
|
|
108
|
-
this.limit = this.capacity = t, this.q = new
|
|
73
|
+
this.limit = this.capacity = t, this.q = new o(t);
|
|
109
74
|
}
|
|
110
75
|
acquire(t) {
|
|
111
76
|
return h(this, t);
|
|
112
77
|
}
|
|
113
78
|
release() {
|
|
114
|
-
|
|
79
|
+
u(this);
|
|
115
80
|
}
|
|
116
81
|
setRestriction(t) {
|
|
117
82
|
this.limit = this.capacity = t;
|
|
@@ -124,19 +89,19 @@ module.exports = function(t) {
|
|
|
124
89
|
try {
|
|
125
90
|
return await t();
|
|
126
91
|
} finally {
|
|
127
|
-
|
|
92
|
+
u(this);
|
|
128
93
|
}
|
|
129
94
|
}
|
|
130
95
|
}
|
|
131
|
-
const
|
|
96
|
+
const f = r, p = a, _ = t => ({
|
|
132
97
|
capacity: t,
|
|
133
98
|
limit: t,
|
|
134
|
-
q: new
|
|
99
|
+
q: new o(t),
|
|
135
100
|
acquire(t) {
|
|
136
|
-
return
|
|
101
|
+
return f(this, t);
|
|
137
102
|
},
|
|
138
103
|
release() {
|
|
139
|
-
|
|
104
|
+
p(this);
|
|
140
105
|
},
|
|
141
106
|
setRestriction(t) {
|
|
142
107
|
this.limit = this.capacity = t;
|
|
@@ -145,25 +110,45 @@ module.exports = function(t) {
|
|
|
145
110
|
return this.q.length;
|
|
146
111
|
},
|
|
147
112
|
async flow(t, e) {
|
|
148
|
-
await
|
|
113
|
+
await f(this, e);
|
|
149
114
|
try {
|
|
150
115
|
return await t();
|
|
151
116
|
} finally {
|
|
152
|
-
|
|
117
|
+
p(this);
|
|
153
118
|
}
|
|
154
119
|
}
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
if (i || (w[t] = i = new m(e)), i.limit !== e) throw new ReferenceError(`Cannot get object with different restriction: key: '${t}', lock.limit: ${i.limit} <-> restriction: ${e},`);
|
|
158
|
-
return i;
|
|
159
|
-
};
|
|
160
|
-
var b;
|
|
120
|
+
});
|
|
121
|
+
var m;
|
|
161
122
|
!function(t) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
123
|
+
const {MiniSemaphore: e} = i, n = new e(1);
|
|
124
|
+
let s = Object.create(null);
|
|
125
|
+
async function r(t, i, r) {
|
|
126
|
+
const a = await (async (t, i) => {
|
|
127
|
+
await n.acquire(!1);
|
|
128
|
+
let r = s[t];
|
|
129
|
+
if (r || (s[t] = r = new e(i)), r.limit !== i) throw n.release(), new ReferenceError(`Cannot get object with different restriction: key: '${t}', lock.limit: ${r.limit} <-> restriction: ${i},`);
|
|
130
|
+
return n.release(), r;
|
|
131
|
+
})(t, i), c = a.flow(r);
|
|
132
|
+
return a.last = Date.now(), c;
|
|
133
|
+
}
|
|
134
|
+
t.getLockByKey = async t => {
|
|
135
|
+
await n.acquire(!1);
|
|
136
|
+
const e = s[t];
|
|
137
|
+
return n.release(), e;
|
|
138
|
+
}, t.cleanup = async (t, e) => {
|
|
139
|
+
await n.acquire(!1);
|
|
140
|
+
const i = s, r = Object.create(null), a = Object.keys(i);
|
|
141
|
+
let c, o = 0;
|
|
142
|
+
!t && (t = 1), t *= 1e3, e && (c = []);
|
|
143
|
+
for (let n = 0, s = a.length; n < s; ) {
|
|
144
|
+
const s = a[n++], l = i[s];
|
|
145
|
+
l.last && Date.now() - l.last >= t ? (o++, e && c.push(s)) : r[s] = l;
|
|
146
|
+
}
|
|
147
|
+
return s = r, n.release(), e && console.log(`eliminated: [\n${c.join(",\n")}\n]\nlived: [\n${Object.keys(r).join(",\n")}\n]`),
|
|
148
|
+
o;
|
|
149
|
+
}, t.multi = r, t.one = async function(t, e) {
|
|
150
|
+
return r(t, 1, e);
|
|
166
151
|
};
|
|
167
|
-
}(
|
|
168
|
-
}
|
|
152
|
+
}(m || (m = {})), module.exports = e;
|
|
153
|
+
})();
|
|
169
154
|
//# sourceMappingURL=index.js.map
|
package/webpack/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["webpack
|
|
1
|
+
{"version":3,"file":"index.js","mappings":";;AACA;ACAA;AACA;AAEA;AAAA;;;ACJA;ACCA;AACA;AACA;AAEA;AAAA;;;;;;;;;;;;;;ACLA;AACA;ACAA;AACA;AAOA;AAEA;AAQA;AACA;AAMA;ACVA;AAFA;AAKA;AACA;AACA;;AAKA;AACA;AACA;AAGA;AACA;;AAGA;AACA;AACA;AAGA;AAKA;;AAEA;AACA;;;AAGA;AACA;AACA;AACA;AAEA;AACA;AAzDA;AACA;AAyDA;;ACxDA;AAEA;AACA;AACA;;AAGA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;ACzBA;AAIA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AAEA;AACA;;;;AC1BA;AACA;AACA;AAEA;AAqDA;AACA;AApDA;AACA;AAIA;AAKA;AA0CA;AAGA;;AA3CA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAGA;AAEA;AAKA;AACA;AAEA;;AAgBA;AAAA;AAQA;AAEA;;AAhEA","sources":["webpack://mini-semaphore/webpack/bootstrap","webpack://mini-semaphore/webpack/runtime/define property getters","webpack://mini-semaphore/webpack/runtime/hasOwnProperty shorthand","webpack://mini-semaphore/webpack/runtime/make namespace object","webpack://mini-semaphore/./src/extras.ts","webpack://mini-semaphore/./src/core.ts","webpack://mini-semaphore/./src/deque.ts","webpack://mini-semaphore/./src/class.ts","webpack://mini-semaphore/./src/object.ts","webpack://mini-semaphore/./src/flow-restrictor.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export const THROW = () => {\r\n throw new Error(\"mini-semaphore: inconsistent occurred\");\r\n};\r\n","import { THROW } from \"./extras\";\r\nconst box = (z, r) => {\r\n if (z.capacity > 0) {\r\n z.capacity--, r();\r\n }\r\n else {\r\n z.q.push(r);\r\n }\r\n};\r\nexport const acquire = (dis, lazy = true) => {\r\n return new Promise(r => {\r\n if (!lazy) {\r\n box(dis, r);\r\n }\r\n else {\r\n setTimeout(() => box(dis, r), 4);\r\n }\r\n });\r\n};\r\nexport const release = (dis) => {\r\n dis.capacity++;\r\n if (dis.q.length) {\r\n dis.capacity -= 1, (dis.q.shift() || THROW)();\r\n }\r\n if (dis.capacity > dis.limit) {\r\n console.warn(\"inconsistent release!\");\r\n dis.capacity = dis.limit;\r\n }\r\n};\r\n","const am = (src, si, dst, di, len) => {\r\n for (let j = 0; j < len; ++j) {\r\n dst[j + di] = src[j + si];\r\n src[j + si] = void 0;\r\n }\r\n};\r\nconst p2l = (n) => {\r\n n = n >>> 0;\r\n n = n - 1;\r\n n = n | (n >> 1);\r\n n = n | (n >> 2);\r\n n = n | (n >> 4);\r\n n = n | (n >> 8);\r\n n = n | (n >> 16);\r\n return n + 1;\r\n};\r\nconst gc = (n) => {\r\n return p2l(Math.min(Math.max(16, n | 0), 1073741824));\r\n};\r\nexport class Deque {\r\n constructor(ic) {\r\n this._c = gc(ic);\r\n this._l = 0;\r\n this._f = 0;\r\n this._a = [];\r\n }\r\n push(s) {\r\n const l = this._l;\r\n if (this._c < l + 1) {\r\n rt(this, gc(this._c * 1.5 + 16));\r\n }\r\n const i = (this._f + l) & (this._c - 1);\r\n this._a[i] = s;\r\n this._l = l + 1;\r\n }\r\n shift() {\r\n const l = this._l;\r\n if (l === 0) {\r\n return void 0;\r\n }\r\n const f = this._f;\r\n const r = this._a[f];\r\n this._a[f] = void 0;\r\n this._f = (f + 1) & (this._c - 1);\r\n this._l = l - 1;\r\n return r;\r\n }\r\n get length() {\r\n return this._l;\r\n }\r\n}\r\nconst rt = (dis, n) => {\r\n const oc = dis._c;\r\n dis._c = n;\r\n const f = dis._f;\r\n const l = dis._l;\r\n if (f + l > oc) {\r\n const mc = (f + l) & (oc - 1);\r\n am(dis._a, 0, dis._a, oc, mc);\r\n }\r\n};\r\n","import * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\nconst a = core.acquire;\r\nconst r = core.release;\r\nexport class MiniSemaphore {\r\n constructor(capacity) {\r\n this.limit = this.capacity = capacity;\r\n this.q = new Deque(capacity);\r\n }\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n }\r\n release() {\r\n r(this);\r\n }\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n }\r\n get pending() {\r\n return this.q.length;\r\n }\r\n async flow(process, lazy) {\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n }\r\n}\r\n","import * as core from \"./core\";\r\nimport { Deque } from \"./deque\";\r\nconst a = core.acquire;\r\nconst r = core.release;\r\nexport const create = (capacity) => {\r\n return {\r\n capacity,\r\n limit: capacity,\r\n q: new Deque(capacity),\r\n acquire(lazy) {\r\n return a(this, lazy);\r\n },\r\n release() {\r\n r(this);\r\n },\r\n setRestriction(restriction) {\r\n this.limit = this.capacity = restriction;\r\n },\r\n get pending() {\r\n return this.q.length;\r\n },\r\n async flow(process, lazy) {\r\n await a(this, lazy);\r\n try {\r\n return await process();\r\n }\r\n finally {\r\n r(this);\r\n }\r\n }\r\n };\r\n};\r\n","import * as c from \"./class\";\r\nexport var restrictor;\r\n(function (restrictor) {\r\n const { MiniSemaphore: MS } = c;\r\n const internalLock = new MS(1);\r\n let locks = Object.create(null);\r\n const get = async (key, restriction) => {\r\n await internalLock.acquire(false);\r\n let lock = locks[key];\r\n if (!lock) {\r\n locks[key] = lock = new MS(restriction);\r\n }\r\n if (lock.limit !== restriction) {\r\n internalLock.release();\r\n throw new ReferenceError(`Cannot get object with different restriction: key: '${key}', lock.limit: ${lock.limit} <-> restriction: ${restriction},`);\r\n }\r\n internalLock.release();\r\n return lock;\r\n };\r\n restrictor.getLockByKey = async (key) => {\r\n await internalLock.acquire(false);\r\n const l = locks[key];\r\n internalLock.release();\r\n return l;\r\n };\r\n restrictor.cleanup = async (timeSpan, debug) => {\r\n await internalLock.acquire(false);\r\n const currentLocks = locks;\r\n const newLocks = Object.create(null);\r\n const keys = Object.keys(currentLocks);\r\n let eliminatedCount = 0;\r\n let eliminatedKeys;\r\n !timeSpan && (timeSpan = 1);\r\n timeSpan *= 1000;\r\n if (debug) {\r\n eliminatedKeys = [];\r\n }\r\n for (let i = 0, end = keys.length; i < end;) {\r\n const key = keys[i++];\r\n const s = currentLocks[key];\r\n if (s.last && Date.now() - s.last >= timeSpan) {\r\n eliminatedCount++;\r\n if (debug) {\r\n eliminatedKeys.push(key);\r\n }\r\n continue;\r\n }\r\n newLocks[key] = s;\r\n }\r\n locks = newLocks;\r\n internalLock.release();\r\n if (debug) {\r\n console.log(`eliminated: [\\n${eliminatedKeys.join(\",\\n\")}\\n]` +\r\n \"\\n\" +\r\n `lived: [\\n${Object.keys(newLocks).join(\",\\n\")}\\n]`);\r\n }\r\n return eliminatedCount;\r\n };\r\n async function multi(key, restriction, pb) {\r\n const s = await get(key, restriction);\r\n const result = s.flow(pb);\r\n s.last = Date.now();\r\n return result;\r\n }\r\n restrictor.multi = multi;\r\n async function one(key, pb) {\r\n return multi(key, 1, pb);\r\n }\r\n restrictor.one = one;\r\n})(restrictor || (restrictor = {}));\r\n"],"names":[],"sourceRoot":""}
|