omnigateway 0.12.3 → 0.12.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 +4 -1
- package/bin/omni.js +41 -7
- package/gateway.js +124 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -332,7 +332,10 @@ changed without a restart: the six routing weights, `maxAttempts`,
|
|
|
332
332
|
`ponytailMode` (`off` | `lite` | `full` | `ultra`),
|
|
333
333
|
and the two body-capture switches. Edit them with `omni settings set` or in the
|
|
334
334
|
console. `quotaPollIntervalMs` is the one exception: the poller reads it once at
|
|
335
|
-
boot, so a change to it takes a restart.
|
|
335
|
+
boot, so a change to it takes a restart. `requestDeadlineMs` defaults to `0`,
|
|
336
|
+
which imposes no deadline at all; what that means for whatever sits in front of
|
|
337
|
+
the gateway is
|
|
338
|
+
[Behind a reverse proxy](docs/deploying.md#behind-a-reverse-proxy). Snapshot retention —
|
|
336
339
|
`snapshotKeepLatest` and `snapshotMaxAgeDays` — is stored alongside them but
|
|
337
340
|
deliberately edited on the Database screen instead; see
|
|
338
341
|
[Snapshots and restore](docs/operations.md#snapshots-and-restore) for why.
|
package/bin/omni.js
CHANGED
|
@@ -19590,9 +19590,16 @@ function memoryCoord(options = {}) {
|
|
|
19590
19590
|
const now = options.now ?? (() => Date.now());
|
|
19591
19591
|
const windows = new Map;
|
|
19592
19592
|
const gauges = new Map;
|
|
19593
|
+
const named = (holder) => {
|
|
19594
|
+
if (holder === undefined)
|
|
19595
|
+
return;
|
|
19596
|
+
if (holder === "")
|
|
19597
|
+
throw new TypeError("gauge holder must be a non-empty string");
|
|
19598
|
+
return holder;
|
|
19599
|
+
};
|
|
19593
19600
|
const liveSlots = (key) => {
|
|
19594
19601
|
const at = now();
|
|
19595
|
-
const held = (gauges.get(key) ?? []).filter((
|
|
19602
|
+
const held = (gauges.get(key) ?? []).filter((slot) => slot.expiresAt > at);
|
|
19596
19603
|
if (held.length === 0)
|
|
19597
19604
|
gauges.delete(key);
|
|
19598
19605
|
else
|
|
@@ -19647,18 +19654,45 @@ function memoryCoord(options = {}) {
|
|
|
19647
19654
|
}
|
|
19648
19655
|
},
|
|
19649
19656
|
gauge: {
|
|
19650
|
-
acquire(key, ttlMs) {
|
|
19657
|
+
acquire(key, ttlMs, rawHolder) {
|
|
19658
|
+
const holder = named(rawHolder);
|
|
19651
19659
|
const held = liveSlots(key);
|
|
19660
|
+
const expiresAt = now() + ttlMs;
|
|
19661
|
+
const mine = holder === undefined ? -1 : held.findIndex((s) => s.holder === holder);
|
|
19662
|
+
if (mine !== -1 && holder !== undefined) {
|
|
19663
|
+
held[mine] = { expiresAt, holder };
|
|
19664
|
+
gauges.set(key, held);
|
|
19665
|
+
return Promise.resolve(held.length - 1);
|
|
19666
|
+
}
|
|
19652
19667
|
const before = held.length;
|
|
19653
|
-
held.push(
|
|
19668
|
+
held.push(holder === undefined ? { expiresAt } : { expiresAt, holder });
|
|
19654
19669
|
gauges.set(key, held);
|
|
19655
19670
|
return Promise.resolve(before);
|
|
19656
19671
|
},
|
|
19657
|
-
|
|
19672
|
+
renew(key, holder, ttlMs) {
|
|
19673
|
+
named(holder);
|
|
19674
|
+
const held = liveSlots(key);
|
|
19675
|
+
const mine = held.findIndex((slot) => slot.holder === holder);
|
|
19676
|
+
if (mine !== -1) {
|
|
19677
|
+
held[mine] = { expiresAt: now() + ttlMs, holder };
|
|
19678
|
+
gauges.set(key, held);
|
|
19679
|
+
}
|
|
19680
|
+
return Promise.resolve();
|
|
19681
|
+
},
|
|
19682
|
+
release(key, holder) {
|
|
19683
|
+
named(holder);
|
|
19658
19684
|
const held = liveSlots(key);
|
|
19659
|
-
|
|
19685
|
+
if (holder === undefined) {
|
|
19686
|
+
held.sort((x, y) => x.expiresAt - y.expiresAt).shift();
|
|
19687
|
+
} else {
|
|
19688
|
+
const mine = held.findIndex((slot) => slot.holder === holder);
|
|
19689
|
+
if (mine !== -1)
|
|
19690
|
+
held.splice(mine, 1);
|
|
19691
|
+
}
|
|
19660
19692
|
if (held.length === 0)
|
|
19661
19693
|
gauges.delete(key);
|
|
19694
|
+
else
|
|
19695
|
+
gauges.set(key, held);
|
|
19662
19696
|
return Promise.resolve();
|
|
19663
19697
|
},
|
|
19664
19698
|
read(key) {
|
|
@@ -21194,7 +21228,7 @@ var NODE_GRACE_MS = 60000;
|
|
|
21194
21228
|
var DEFAULT_SETTINGS = {
|
|
21195
21229
|
weights: { tier: 10, health: 3, quota: 2, load: 2, cost: 1, latency: 1 },
|
|
21196
21230
|
maxAttempts: 3,
|
|
21197
|
-
requestDeadlineMs:
|
|
21231
|
+
requestDeadlineMs: 0,
|
|
21198
21232
|
breakerThreshold: 3,
|
|
21199
21233
|
breakerCooldownMs: 30000,
|
|
21200
21234
|
logRetentionDays: 30,
|
|
@@ -37474,7 +37508,7 @@ function createServiceDeps(input2) {
|
|
|
37474
37508
|
}
|
|
37475
37509
|
|
|
37476
37510
|
// apps/cli/src/version.ts
|
|
37477
|
-
var VERSION = "0.12.
|
|
37511
|
+
var VERSION = "0.12.4";
|
|
37478
37512
|
|
|
37479
37513
|
// apps/cli/src/commands/service.ts
|
|
37480
37514
|
function gatewayArgv(root) {
|
package/gateway.js
CHANGED
|
@@ -24789,9 +24789,16 @@ function memoryCoord(options = {}) {
|
|
|
24789
24789
|
const now = options.now ?? (() => Date.now());
|
|
24790
24790
|
const windows = new Map;
|
|
24791
24791
|
const gauges = new Map;
|
|
24792
|
+
const named = (holder) => {
|
|
24793
|
+
if (holder === undefined)
|
|
24794
|
+
return;
|
|
24795
|
+
if (holder === "")
|
|
24796
|
+
throw new TypeError("gauge holder must be a non-empty string");
|
|
24797
|
+
return holder;
|
|
24798
|
+
};
|
|
24792
24799
|
const liveSlots = (key) => {
|
|
24793
24800
|
const at = now();
|
|
24794
|
-
const held = (gauges.get(key) ?? []).filter((
|
|
24801
|
+
const held = (gauges.get(key) ?? []).filter((slot) => slot.expiresAt > at);
|
|
24795
24802
|
if (held.length === 0)
|
|
24796
24803
|
gauges.delete(key);
|
|
24797
24804
|
else
|
|
@@ -24846,18 +24853,45 @@ function memoryCoord(options = {}) {
|
|
|
24846
24853
|
}
|
|
24847
24854
|
},
|
|
24848
24855
|
gauge: {
|
|
24849
|
-
acquire(key, ttlMs) {
|
|
24856
|
+
acquire(key, ttlMs, rawHolder) {
|
|
24857
|
+
const holder = named(rawHolder);
|
|
24850
24858
|
const held = liveSlots(key);
|
|
24859
|
+
const expiresAt = now() + ttlMs;
|
|
24860
|
+
const mine = holder === undefined ? -1 : held.findIndex((s) => s.holder === holder);
|
|
24861
|
+
if (mine !== -1 && holder !== undefined) {
|
|
24862
|
+
held[mine] = { expiresAt, holder };
|
|
24863
|
+
gauges.set(key, held);
|
|
24864
|
+
return Promise.resolve(held.length - 1);
|
|
24865
|
+
}
|
|
24851
24866
|
const before = held.length;
|
|
24852
|
-
held.push(
|
|
24867
|
+
held.push(holder === undefined ? { expiresAt } : { expiresAt, holder });
|
|
24853
24868
|
gauges.set(key, held);
|
|
24854
24869
|
return Promise.resolve(before);
|
|
24855
24870
|
},
|
|
24856
|
-
|
|
24871
|
+
renew(key, holder, ttlMs) {
|
|
24872
|
+
named(holder);
|
|
24873
|
+
const held = liveSlots(key);
|
|
24874
|
+
const mine = held.findIndex((slot) => slot.holder === holder);
|
|
24875
|
+
if (mine !== -1) {
|
|
24876
|
+
held[mine] = { expiresAt: now() + ttlMs, holder };
|
|
24877
|
+
gauges.set(key, held);
|
|
24878
|
+
}
|
|
24879
|
+
return Promise.resolve();
|
|
24880
|
+
},
|
|
24881
|
+
release(key, holder) {
|
|
24882
|
+
named(holder);
|
|
24857
24883
|
const held = liveSlots(key);
|
|
24858
|
-
|
|
24884
|
+
if (holder === undefined) {
|
|
24885
|
+
held.sort((x, y) => x.expiresAt - y.expiresAt).shift();
|
|
24886
|
+
} else {
|
|
24887
|
+
const mine = held.findIndex((slot) => slot.holder === holder);
|
|
24888
|
+
if (mine !== -1)
|
|
24889
|
+
held.splice(mine, 1);
|
|
24890
|
+
}
|
|
24859
24891
|
if (held.length === 0)
|
|
24860
24892
|
gauges.delete(key);
|
|
24893
|
+
else
|
|
24894
|
+
gauges.set(key, held);
|
|
24861
24895
|
return Promise.resolve();
|
|
24862
24896
|
},
|
|
24863
24897
|
read(key) {
|
|
@@ -26626,7 +26660,7 @@ var NODE_GRACE_MS = 60000;
|
|
|
26626
26660
|
var DEFAULT_SETTINGS = {
|
|
26627
26661
|
weights: { tier: 10, health: 3, quota: 2, load: 2, cost: 1, latency: 1 },
|
|
26628
26662
|
maxAttempts: 3,
|
|
26629
|
-
requestDeadlineMs:
|
|
26663
|
+
requestDeadlineMs: 0,
|
|
26630
26664
|
breakerThreshold: 3,
|
|
26631
26665
|
breakerCooldownMs: 30000,
|
|
26632
26666
|
logRetentionDays: 30,
|
|
@@ -54861,6 +54895,8 @@ var LONG_WINDOWS = ["5h", "1w"];
|
|
|
54861
54895
|
var GRAIN_MS = { "5h": 60000, "1w": 3600000 };
|
|
54862
54896
|
var SEED_LOCK_MS = 5000;
|
|
54863
54897
|
var GAUGE_TTL_MS = 300000;
|
|
54898
|
+
var RENEW_INTERVAL_MS = 1e5;
|
|
54899
|
+
var MAX_RENEWED_MS = 86400000;
|
|
54864
54900
|
function bucketKey(keyId, window2) {
|
|
54865
54901
|
return `lim:${keyId}:${window2}`;
|
|
54866
54902
|
}
|
|
@@ -54919,10 +54955,11 @@ class ApiKeyRateLimiter {
|
|
|
54919
54955
|
}
|
|
54920
54956
|
async admit(keyId, limits, requestId) {
|
|
54921
54957
|
if (!anyLimit(limits))
|
|
54922
|
-
return { release: () => {}, headroom: {} };
|
|
54958
|
+
return { release: () => {}, renew: async () => {}, headroom: {} };
|
|
54923
54959
|
const now = this.now();
|
|
54924
54960
|
this.limits.set(keyId, limits);
|
|
54925
|
-
const
|
|
54961
|
+
const holder = configured(limits.concurrency) ? crypto.randomUUID() : undefined;
|
|
54962
|
+
const claim2 = await this.claim(keyId, now, true, holder);
|
|
54926
54963
|
let admitted = false;
|
|
54927
54964
|
try {
|
|
54928
54965
|
const counters = await this.counters(keyId, limits, claim2, now, requestId);
|
|
@@ -54930,13 +54967,29 @@ class ApiKeyRateLimiter {
|
|
|
54930
54967
|
await this.refuse(keyId, decision, now, requestId);
|
|
54931
54968
|
admitted = true;
|
|
54932
54969
|
let released = false;
|
|
54970
|
+
const renewUntil = now + MAX_RENEWED_MS;
|
|
54971
|
+
const renew = async () => {
|
|
54972
|
+
if (released || holder === undefined)
|
|
54973
|
+
return;
|
|
54974
|
+
await this.coord.gauge.renew(keyId, holder, GAUGE_TTL_MS);
|
|
54975
|
+
};
|
|
54976
|
+
const renewal = holder === undefined ? null : setInterval(() => {
|
|
54977
|
+
if (this.now() >= renewUntil) {
|
|
54978
|
+
clearInterval(renewal ?? undefined);
|
|
54979
|
+
return;
|
|
54980
|
+
}
|
|
54981
|
+
renew();
|
|
54982
|
+
}, RENEW_INTERVAL_MS);
|
|
54983
|
+
renewal?.unref?.();
|
|
54933
54984
|
const release = () => {
|
|
54934
54985
|
if (released)
|
|
54935
54986
|
return;
|
|
54936
54987
|
released = true;
|
|
54937
|
-
|
|
54988
|
+
if (renewal !== null)
|
|
54989
|
+
clearInterval(renewal);
|
|
54990
|
+
this.coord.gauge.release(keyId, holder);
|
|
54938
54991
|
};
|
|
54939
|
-
return { release, headroom: decision.headroom };
|
|
54992
|
+
return { release, renew, headroom: decision.headroom };
|
|
54940
54993
|
} finally {
|
|
54941
54994
|
if (!admitted)
|
|
54942
54995
|
await this.rollback(keyId, claim2);
|
|
@@ -54959,15 +55012,15 @@ class ApiKeyRateLimiter {
|
|
|
54959
55012
|
await this.rollback(keyId, claim2);
|
|
54960
55013
|
}
|
|
54961
55014
|
}
|
|
54962
|
-
async claim(keyId, now, gauge) {
|
|
55015
|
+
async claim(keyId, now, gauge, holder) {
|
|
54963
55016
|
const ring = await this.coord.window.claim(keyId, WINDOW_MS["1m"], now);
|
|
54964
|
-
const concurrency = gauge ? await this.coord.gauge.acquire(keyId, GAUGE_TTL_MS) : await this.coord.gauge.read(keyId);
|
|
54965
|
-
return { stamp: ring.stamp, gauge, before: { requests: ring.before, concurrency } };
|
|
55017
|
+
const concurrency = gauge ? await this.coord.gauge.acquire(keyId, GAUGE_TTL_MS, holder) : await this.coord.gauge.read(keyId);
|
|
55018
|
+
return { stamp: ring.stamp, gauge, holder, before: { requests: ring.before, concurrency } };
|
|
54966
55019
|
}
|
|
54967
55020
|
async rollback(keyId, claim2) {
|
|
54968
55021
|
await this.coord.window.rollback(keyId, claim2.stamp);
|
|
54969
55022
|
if (claim2.gauge)
|
|
54970
|
-
await this.coord.gauge.release(keyId);
|
|
55023
|
+
await this.coord.gauge.release(keyId, claim2.holder);
|
|
54971
55024
|
}
|
|
54972
55025
|
debit(keyId, usage) {
|
|
54973
55026
|
const limits = this.limits.get(keyId);
|
|
@@ -55094,6 +55147,8 @@ function withReset(headroom, window2, resetAt) {
|
|
|
55094
55147
|
// apps/gateway/src/dispatch/loadRegistry.ts
|
|
55095
55148
|
var PREFIX6 = "load:";
|
|
55096
55149
|
var SLOT_TTL_MS = 300000;
|
|
55150
|
+
var RENEW_INTERVAL_MS2 = 1e5;
|
|
55151
|
+
var MAX_RENEWED_MS2 = 86400000;
|
|
55097
55152
|
var EWMA_ALPHA = 0.3;
|
|
55098
55153
|
function createLoadRegistry(coord = memoryCoord(), now = Date.now) {
|
|
55099
55154
|
const local = new Map;
|
|
@@ -55106,12 +55161,23 @@ function createLoadRegistry(coord = memoryCoord(), now = Date.now) {
|
|
|
55106
55161
|
local.set(key, (local.get(key) ?? 0) + 1);
|
|
55107
55162
|
if (provider !== undefined)
|
|
55108
55163
|
providers.set(provider, (providers.get(provider) ?? 0) + 1);
|
|
55109
|
-
|
|
55164
|
+
const holder = crypto.randomUUID();
|
|
55165
|
+
coord.gauge.acquire(PREFIX6 + key, SLOT_TTL_MS, holder);
|
|
55166
|
+
const renewUntil = now() + MAX_RENEWED_MS2;
|
|
55167
|
+
const renewal = setInterval(() => {
|
|
55168
|
+
if (now() >= renewUntil) {
|
|
55169
|
+
clearInterval(renewal);
|
|
55170
|
+
return;
|
|
55171
|
+
}
|
|
55172
|
+
coord.gauge.renew(PREFIX6 + key, holder, SLOT_TTL_MS);
|
|
55173
|
+
}, RENEW_INTERVAL_MS2);
|
|
55174
|
+
renewal.unref?.();
|
|
55110
55175
|
let released = false;
|
|
55111
55176
|
return (ttftMs) => {
|
|
55112
55177
|
if (released)
|
|
55113
55178
|
return;
|
|
55114
55179
|
released = true;
|
|
55180
|
+
clearInterval(renewal);
|
|
55115
55181
|
const prior = history.get(key)?.ewmaTtftMs ?? null;
|
|
55116
55182
|
history.set(key, {
|
|
55117
55183
|
lastReleasedAt: now(),
|
|
@@ -55129,7 +55195,7 @@ function createLoadRegistry(coord = memoryCoord(), now = Date.now) {
|
|
|
55129
55195
|
else
|
|
55130
55196
|
providers.delete(provider);
|
|
55131
55197
|
}
|
|
55132
|
-
coord.gauge.release(PREFIX6 + key);
|
|
55198
|
+
coord.gauge.release(PREFIX6 + key, holder);
|
|
55133
55199
|
};
|
|
55134
55200
|
},
|
|
55135
55201
|
counts() {
|
|
@@ -62302,7 +62368,7 @@ function createRing(limits = DEFAULT_RING_LIMITS) {
|
|
|
62302
62368
|
}
|
|
62303
62369
|
|
|
62304
62370
|
// apps/gateway/src/version.ts
|
|
62305
|
-
var VERSION = "0.12.
|
|
62371
|
+
var VERSION = "0.12.4";
|
|
62306
62372
|
|
|
62307
62373
|
// apps/gateway/src/app.ts
|
|
62308
62374
|
var ADMIN_SESSION_TTL_MS = 12 * 60 * 60 * 1000;
|
|
@@ -62580,19 +62646,35 @@ var WINDOW_ROLLBACK = `
|
|
|
62580
62646
|
`;
|
|
62581
62647
|
var GAUGE_ACQUIRE = `
|
|
62582
62648
|
redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', ARGV[1])
|
|
62649
|
+
local mine = redis.call('ZSCORE', KEYS[1], ARGV[3])
|
|
62583
62650
|
local before = redis.call('ZCARD', KEYS[1])
|
|
62651
|
+
if mine then before = before - 1 end
|
|
62584
62652
|
redis.call('ZADD', KEYS[1], tonumber(ARGV[1]) + tonumber(ARGV[2]), ARGV[3])
|
|
62585
|
-
redis.call('
|
|
62653
|
+
if redis.call('PTTL', KEYS[1]) < tonumber(ARGV[2]) then
|
|
62654
|
+
redis.call('PEXPIRE', KEYS[1], ARGV[2])
|
|
62655
|
+
end
|
|
62586
62656
|
redis.call('SADD', KEYS[2], KEYS[1])
|
|
62587
62657
|
return before
|
|
62588
62658
|
`;
|
|
62659
|
+
var GAUGE_RENEW = `
|
|
62660
|
+
redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', ARGV[1])
|
|
62661
|
+
redis.call('ZADD', KEYS[1], 'XX', tonumber(ARGV[1]) + tonumber(ARGV[2]), ARGV[3])
|
|
62662
|
+
if redis.call('PTTL', KEYS[1]) < tonumber(ARGV[2]) then
|
|
62663
|
+
redis.call('PEXPIRE', KEYS[1], ARGV[2])
|
|
62664
|
+
end
|
|
62665
|
+
return 0
|
|
62666
|
+
`;
|
|
62589
62667
|
var GAUGE_READ = `
|
|
62590
62668
|
redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', ARGV[1])
|
|
62591
62669
|
return redis.call('ZCARD', KEYS[1])
|
|
62592
62670
|
`;
|
|
62593
62671
|
var GAUGE_RELEASE = `
|
|
62594
62672
|
redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', ARGV[1])
|
|
62595
|
-
|
|
62673
|
+
if ARGV[2] == '' then
|
|
62674
|
+
redis.call('ZPOPMIN', KEYS[1])
|
|
62675
|
+
else
|
|
62676
|
+
redis.call('ZREM', KEYS[1], ARGV[2])
|
|
62677
|
+
end
|
|
62596
62678
|
return 0
|
|
62597
62679
|
`;
|
|
62598
62680
|
var GAUGE_SNAPSHOT = `
|
|
@@ -62601,8 +62683,10 @@ var GAUGE_SNAPSHOT = `
|
|
|
62601
62683
|
redis.call('ZREMRANGEBYSCORE', key, '-inf', ARGV[1])
|
|
62602
62684
|
local count = redis.call('ZCARD', key)
|
|
62603
62685
|
if count > 0 then
|
|
62604
|
-
|
|
62605
|
-
|
|
62686
|
+
if string.sub(key, 1, string.len(ARGV[2])) == ARGV[2] then
|
|
62687
|
+
out[#out + 1] = key
|
|
62688
|
+
out[#out + 1] = count
|
|
62689
|
+
end
|
|
62606
62690
|
else
|
|
62607
62691
|
redis.call('SREM', KEYS[1], key)
|
|
62608
62692
|
end
|
|
@@ -62667,6 +62751,7 @@ var SCRIPTS = [
|
|
|
62667
62751
|
WINDOW_CLAIM,
|
|
62668
62752
|
WINDOW_ROLLBACK,
|
|
62669
62753
|
GAUGE_ACQUIRE,
|
|
62754
|
+
GAUGE_RENEW,
|
|
62670
62755
|
GAUGE_READ,
|
|
62671
62756
|
GAUGE_RELEASE,
|
|
62672
62757
|
GAUGE_SNAPSHOT,
|
|
@@ -62701,6 +62786,10 @@ function redisCoord(deps) {
|
|
|
62701
62786
|
const colon = name.indexOf(":");
|
|
62702
62787
|
return `${NS}gidx:${colon === -1 ? name : name.slice(0, colon + 1)}`;
|
|
62703
62788
|
};
|
|
62789
|
+
const blankHolder = (holder) => {
|
|
62790
|
+
if (holder === "")
|
|
62791
|
+
throw new TypeError("gauge holder must be a non-empty string");
|
|
62792
|
+
};
|
|
62704
62793
|
let faults = 0;
|
|
62705
62794
|
const fault = (error62) => {
|
|
62706
62795
|
healthy = false;
|
|
@@ -62836,20 +62925,28 @@ function redisCoord(deps) {
|
|
|
62836
62925
|
}
|
|
62837
62926
|
},
|
|
62838
62927
|
gauge: {
|
|
62839
|
-
acquire(name, ttlMs) {
|
|
62840
|
-
|
|
62928
|
+
acquire(name, ttlMs, holder) {
|
|
62929
|
+
blankHolder(holder);
|
|
62930
|
+
return attempt2(async () => await evalScript(GAUGE_ACQUIRE, [key("g", name), indexOf2(name)], [now(), ttlMs, holder ?? crypto.randomUUID()]), () => fallback.gauge.acquire(name, ttlMs, holder));
|
|
62931
|
+
},
|
|
62932
|
+
renew(name, holder, ttlMs) {
|
|
62933
|
+
blankHolder(holder);
|
|
62934
|
+
return attempt2(async () => {
|
|
62935
|
+
await evalScript(GAUGE_RENEW, [key("g", name)], [now(), ttlMs, holder]);
|
|
62936
|
+
}, () => fallback.gauge.renew(name, holder, ttlMs));
|
|
62841
62937
|
},
|
|
62842
|
-
release(name) {
|
|
62938
|
+
release(name, holder) {
|
|
62939
|
+
blankHolder(holder);
|
|
62843
62940
|
return attempt2(async () => {
|
|
62844
|
-
await evalScript(GAUGE_RELEASE, [key("g", name)], [now()]);
|
|
62845
|
-
}, () => fallback.gauge.release(name));
|
|
62941
|
+
await evalScript(GAUGE_RELEASE, [key("g", name)], [now(), holder ?? ""]);
|
|
62942
|
+
}, () => fallback.gauge.release(name, holder));
|
|
62846
62943
|
},
|
|
62847
62944
|
read(name) {
|
|
62848
62945
|
return attempt2(async () => await evalScript(GAUGE_READ, [key("g", name)], [now()]), () => fallback.gauge.read(name));
|
|
62849
62946
|
},
|
|
62850
62947
|
snapshot(prefix2) {
|
|
62851
62948
|
return attempt2(async () => {
|
|
62852
|
-
const flat = await evalScript(GAUGE_SNAPSHOT, [indexOf2(prefix2)], [now()]);
|
|
62949
|
+
const flat = await evalScript(GAUGE_SNAPSHOT, [indexOf2(prefix2)], [now(), key("g", prefix2)]);
|
|
62853
62950
|
const out = new Map;
|
|
62854
62951
|
for (let i = 0;i + 1 < flat.length; i += 2) {
|
|
62855
62952
|
out.set(String(flat[i]).slice(key("g", "").length), Number(flat[i + 1]));
|
package/package.json
CHANGED