omnigateway 0.12.3 → 0.12.5
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 +62 -11
- package/gateway.js +145 -31
- 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,
|
|
@@ -27707,12 +27741,29 @@ function closingTurn(contents, note2) {
|
|
|
27707
27741
|
var hasCacheControl = (block) => ("cacheControl" in block) && block.cacheControl !== undefined;
|
|
27708
27742
|
var PRUNED = "antigravity:tool-schema-pruned";
|
|
27709
27743
|
var AGENT_PREAMBLE_DROPPED = "antigravity:agent-preamble-dropped";
|
|
27710
|
-
|
|
27744
|
+
var BILLING_HEADER_DROPPED = "antigravity:billing-header-dropped";
|
|
27745
|
+
function dropFingerprints(system, note2) {
|
|
27711
27746
|
const paragraphs = system.split(/(?:\r?\n){2,}/);
|
|
27712
|
-
|
|
27747
|
+
let preamble = false;
|
|
27748
|
+
let billing = false;
|
|
27749
|
+
const kept = paragraphs.filter((p) => {
|
|
27750
|
+
const trimmed = p.trim();
|
|
27751
|
+
if (trimmed === AGENT_PREAMBLE) {
|
|
27752
|
+
preamble = true;
|
|
27753
|
+
return false;
|
|
27754
|
+
}
|
|
27755
|
+
if (trimmed.startsWith(BILLING_PREFIX)) {
|
|
27756
|
+
billing = true;
|
|
27757
|
+
return false;
|
|
27758
|
+
}
|
|
27759
|
+
return true;
|
|
27760
|
+
});
|
|
27713
27761
|
if (kept.length === paragraphs.length)
|
|
27714
27762
|
return system;
|
|
27715
|
-
|
|
27763
|
+
if (preamble)
|
|
27764
|
+
note2(AGENT_PREAMBLE_DROPPED);
|
|
27765
|
+
if (billing)
|
|
27766
|
+
note2(BILLING_HEADER_DROPPED);
|
|
27716
27767
|
return kept.join(`
|
|
27717
27768
|
|
|
27718
27769
|
`);
|
|
@@ -28010,7 +28061,7 @@ function toAntigravityWire(req, model, identity) {
|
|
|
28010
28061
|
contents: closingTurn(openingTurn(mergeSameRole(contents), note2), note2)
|
|
28011
28062
|
};
|
|
28012
28063
|
const joined = systemText(req.system, "antigravity", note2);
|
|
28013
|
-
const system = joined === undefined ? undefined :
|
|
28064
|
+
const system = joined === undefined ? undefined : dropFingerprints(joined, note2);
|
|
28014
28065
|
if (system !== undefined && system.trim().length > 0) {
|
|
28015
28066
|
request2.systemInstruction = { parts: [{ text: system }] };
|
|
28016
28067
|
}
|
|
@@ -37474,7 +37525,7 @@ function createServiceDeps(input2) {
|
|
|
37474
37525
|
}
|
|
37475
37526
|
|
|
37476
37527
|
// apps/cli/src/version.ts
|
|
37477
|
-
var VERSION = "0.12.
|
|
37528
|
+
var VERSION = "0.12.5";
|
|
37478
37529
|
|
|
37479
37530
|
// apps/cli/src/commands/service.ts
|
|
37480
37531
|
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);
|
|
24857
24873
|
const held = liveSlots(key);
|
|
24858
|
-
held.
|
|
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);
|
|
24883
|
+
const held = liveSlots(key);
|
|
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,
|
|
@@ -33269,12 +33303,29 @@ function closingTurn(contents, note) {
|
|
|
33269
33303
|
var hasCacheControl = (block) => ("cacheControl" in block) && block.cacheControl !== undefined;
|
|
33270
33304
|
var PRUNED = "antigravity:tool-schema-pruned";
|
|
33271
33305
|
var AGENT_PREAMBLE_DROPPED = "antigravity:agent-preamble-dropped";
|
|
33272
|
-
|
|
33306
|
+
var BILLING_HEADER_DROPPED = "antigravity:billing-header-dropped";
|
|
33307
|
+
function dropFingerprints(system, note) {
|
|
33273
33308
|
const paragraphs = system.split(/(?:\r?\n){2,}/);
|
|
33274
|
-
|
|
33309
|
+
let preamble = false;
|
|
33310
|
+
let billing = false;
|
|
33311
|
+
const kept = paragraphs.filter((p) => {
|
|
33312
|
+
const trimmed = p.trim();
|
|
33313
|
+
if (trimmed === AGENT_PREAMBLE) {
|
|
33314
|
+
preamble = true;
|
|
33315
|
+
return false;
|
|
33316
|
+
}
|
|
33317
|
+
if (trimmed.startsWith(BILLING_PREFIX)) {
|
|
33318
|
+
billing = true;
|
|
33319
|
+
return false;
|
|
33320
|
+
}
|
|
33321
|
+
return true;
|
|
33322
|
+
});
|
|
33275
33323
|
if (kept.length === paragraphs.length)
|
|
33276
33324
|
return system;
|
|
33277
|
-
|
|
33325
|
+
if (preamble)
|
|
33326
|
+
note(AGENT_PREAMBLE_DROPPED);
|
|
33327
|
+
if (billing)
|
|
33328
|
+
note(BILLING_HEADER_DROPPED);
|
|
33278
33329
|
return kept.join(`
|
|
33279
33330
|
|
|
33280
33331
|
`);
|
|
@@ -33572,7 +33623,7 @@ function toAntigravityWire(req, model, identity) {
|
|
|
33572
33623
|
contents: closingTurn(openingTurn(mergeSameRole(contents), note), note)
|
|
33573
33624
|
};
|
|
33574
33625
|
const joined = systemText(req.system, "antigravity", note);
|
|
33575
|
-
const system = joined === undefined ? undefined :
|
|
33626
|
+
const system = joined === undefined ? undefined : dropFingerprints(joined, note);
|
|
33576
33627
|
if (system !== undefined && system.trim().length > 0) {
|
|
33577
33628
|
request2.systemInstruction = { parts: [{ text: system }] };
|
|
33578
33629
|
}
|
|
@@ -54861,6 +54912,8 @@ var LONG_WINDOWS = ["5h", "1w"];
|
|
|
54861
54912
|
var GRAIN_MS = { "5h": 60000, "1w": 3600000 };
|
|
54862
54913
|
var SEED_LOCK_MS = 5000;
|
|
54863
54914
|
var GAUGE_TTL_MS = 300000;
|
|
54915
|
+
var RENEW_INTERVAL_MS = 1e5;
|
|
54916
|
+
var MAX_RENEWED_MS = 86400000;
|
|
54864
54917
|
function bucketKey(keyId, window2) {
|
|
54865
54918
|
return `lim:${keyId}:${window2}`;
|
|
54866
54919
|
}
|
|
@@ -54919,10 +54972,11 @@ class ApiKeyRateLimiter {
|
|
|
54919
54972
|
}
|
|
54920
54973
|
async admit(keyId, limits, requestId) {
|
|
54921
54974
|
if (!anyLimit(limits))
|
|
54922
|
-
return { release: () => {}, headroom: {} };
|
|
54975
|
+
return { release: () => {}, renew: async () => {}, headroom: {} };
|
|
54923
54976
|
const now = this.now();
|
|
54924
54977
|
this.limits.set(keyId, limits);
|
|
54925
|
-
const
|
|
54978
|
+
const holder = configured(limits.concurrency) ? crypto.randomUUID() : undefined;
|
|
54979
|
+
const claim2 = await this.claim(keyId, now, true, holder);
|
|
54926
54980
|
let admitted = false;
|
|
54927
54981
|
try {
|
|
54928
54982
|
const counters = await this.counters(keyId, limits, claim2, now, requestId);
|
|
@@ -54930,13 +54984,29 @@ class ApiKeyRateLimiter {
|
|
|
54930
54984
|
await this.refuse(keyId, decision, now, requestId);
|
|
54931
54985
|
admitted = true;
|
|
54932
54986
|
let released = false;
|
|
54987
|
+
const renewUntil = now + MAX_RENEWED_MS;
|
|
54988
|
+
const renew = async () => {
|
|
54989
|
+
if (released || holder === undefined)
|
|
54990
|
+
return;
|
|
54991
|
+
await this.coord.gauge.renew(keyId, holder, GAUGE_TTL_MS);
|
|
54992
|
+
};
|
|
54993
|
+
const renewal = holder === undefined ? null : setInterval(() => {
|
|
54994
|
+
if (this.now() >= renewUntil) {
|
|
54995
|
+
clearInterval(renewal ?? undefined);
|
|
54996
|
+
return;
|
|
54997
|
+
}
|
|
54998
|
+
renew();
|
|
54999
|
+
}, RENEW_INTERVAL_MS);
|
|
55000
|
+
renewal?.unref?.();
|
|
54933
55001
|
const release = () => {
|
|
54934
55002
|
if (released)
|
|
54935
55003
|
return;
|
|
54936
55004
|
released = true;
|
|
54937
|
-
|
|
55005
|
+
if (renewal !== null)
|
|
55006
|
+
clearInterval(renewal);
|
|
55007
|
+
this.coord.gauge.release(keyId, holder);
|
|
54938
55008
|
};
|
|
54939
|
-
return { release, headroom: decision.headroom };
|
|
55009
|
+
return { release, renew, headroom: decision.headroom };
|
|
54940
55010
|
} finally {
|
|
54941
55011
|
if (!admitted)
|
|
54942
55012
|
await this.rollback(keyId, claim2);
|
|
@@ -54959,15 +55029,15 @@ class ApiKeyRateLimiter {
|
|
|
54959
55029
|
await this.rollback(keyId, claim2);
|
|
54960
55030
|
}
|
|
54961
55031
|
}
|
|
54962
|
-
async claim(keyId, now, gauge) {
|
|
55032
|
+
async claim(keyId, now, gauge, holder) {
|
|
54963
55033
|
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 } };
|
|
55034
|
+
const concurrency = gauge ? await this.coord.gauge.acquire(keyId, GAUGE_TTL_MS, holder) : await this.coord.gauge.read(keyId);
|
|
55035
|
+
return { stamp: ring.stamp, gauge, holder, before: { requests: ring.before, concurrency } };
|
|
54966
55036
|
}
|
|
54967
55037
|
async rollback(keyId, claim2) {
|
|
54968
55038
|
await this.coord.window.rollback(keyId, claim2.stamp);
|
|
54969
55039
|
if (claim2.gauge)
|
|
54970
|
-
await this.coord.gauge.release(keyId);
|
|
55040
|
+
await this.coord.gauge.release(keyId, claim2.holder);
|
|
54971
55041
|
}
|
|
54972
55042
|
debit(keyId, usage) {
|
|
54973
55043
|
const limits = this.limits.get(keyId);
|
|
@@ -55094,6 +55164,8 @@ function withReset(headroom, window2, resetAt) {
|
|
|
55094
55164
|
// apps/gateway/src/dispatch/loadRegistry.ts
|
|
55095
55165
|
var PREFIX6 = "load:";
|
|
55096
55166
|
var SLOT_TTL_MS = 300000;
|
|
55167
|
+
var RENEW_INTERVAL_MS2 = 1e5;
|
|
55168
|
+
var MAX_RENEWED_MS2 = 86400000;
|
|
55097
55169
|
var EWMA_ALPHA = 0.3;
|
|
55098
55170
|
function createLoadRegistry(coord = memoryCoord(), now = Date.now) {
|
|
55099
55171
|
const local = new Map;
|
|
@@ -55106,12 +55178,23 @@ function createLoadRegistry(coord = memoryCoord(), now = Date.now) {
|
|
|
55106
55178
|
local.set(key, (local.get(key) ?? 0) + 1);
|
|
55107
55179
|
if (provider !== undefined)
|
|
55108
55180
|
providers.set(provider, (providers.get(provider) ?? 0) + 1);
|
|
55109
|
-
|
|
55181
|
+
const holder = crypto.randomUUID();
|
|
55182
|
+
coord.gauge.acquire(PREFIX6 + key, SLOT_TTL_MS, holder);
|
|
55183
|
+
const renewUntil = now() + MAX_RENEWED_MS2;
|
|
55184
|
+
const renewal = setInterval(() => {
|
|
55185
|
+
if (now() >= renewUntil) {
|
|
55186
|
+
clearInterval(renewal);
|
|
55187
|
+
return;
|
|
55188
|
+
}
|
|
55189
|
+
coord.gauge.renew(PREFIX6 + key, holder, SLOT_TTL_MS);
|
|
55190
|
+
}, RENEW_INTERVAL_MS2);
|
|
55191
|
+
renewal.unref?.();
|
|
55110
55192
|
let released = false;
|
|
55111
55193
|
return (ttftMs) => {
|
|
55112
55194
|
if (released)
|
|
55113
55195
|
return;
|
|
55114
55196
|
released = true;
|
|
55197
|
+
clearInterval(renewal);
|
|
55115
55198
|
const prior = history.get(key)?.ewmaTtftMs ?? null;
|
|
55116
55199
|
history.set(key, {
|
|
55117
55200
|
lastReleasedAt: now(),
|
|
@@ -55129,7 +55212,7 @@ function createLoadRegistry(coord = memoryCoord(), now = Date.now) {
|
|
|
55129
55212
|
else
|
|
55130
55213
|
providers.delete(provider);
|
|
55131
55214
|
}
|
|
55132
|
-
coord.gauge.release(PREFIX6 + key);
|
|
55215
|
+
coord.gauge.release(PREFIX6 + key, holder);
|
|
55133
55216
|
};
|
|
55134
55217
|
},
|
|
55135
55218
|
counts() {
|
|
@@ -62302,7 +62385,7 @@ function createRing(limits = DEFAULT_RING_LIMITS) {
|
|
|
62302
62385
|
}
|
|
62303
62386
|
|
|
62304
62387
|
// apps/gateway/src/version.ts
|
|
62305
|
-
var VERSION = "0.12.
|
|
62388
|
+
var VERSION = "0.12.5";
|
|
62306
62389
|
|
|
62307
62390
|
// apps/gateway/src/app.ts
|
|
62308
62391
|
var ADMIN_SESSION_TTL_MS = 12 * 60 * 60 * 1000;
|
|
@@ -62580,19 +62663,35 @@ var WINDOW_ROLLBACK = `
|
|
|
62580
62663
|
`;
|
|
62581
62664
|
var GAUGE_ACQUIRE = `
|
|
62582
62665
|
redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', ARGV[1])
|
|
62666
|
+
local mine = redis.call('ZSCORE', KEYS[1], ARGV[3])
|
|
62583
62667
|
local before = redis.call('ZCARD', KEYS[1])
|
|
62668
|
+
if mine then before = before - 1 end
|
|
62584
62669
|
redis.call('ZADD', KEYS[1], tonumber(ARGV[1]) + tonumber(ARGV[2]), ARGV[3])
|
|
62585
|
-
redis.call('
|
|
62670
|
+
if redis.call('PTTL', KEYS[1]) < tonumber(ARGV[2]) then
|
|
62671
|
+
redis.call('PEXPIRE', KEYS[1], ARGV[2])
|
|
62672
|
+
end
|
|
62586
62673
|
redis.call('SADD', KEYS[2], KEYS[1])
|
|
62587
62674
|
return before
|
|
62588
62675
|
`;
|
|
62676
|
+
var GAUGE_RENEW = `
|
|
62677
|
+
redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', ARGV[1])
|
|
62678
|
+
redis.call('ZADD', KEYS[1], 'XX', tonumber(ARGV[1]) + tonumber(ARGV[2]), ARGV[3])
|
|
62679
|
+
if redis.call('PTTL', KEYS[1]) < tonumber(ARGV[2]) then
|
|
62680
|
+
redis.call('PEXPIRE', KEYS[1], ARGV[2])
|
|
62681
|
+
end
|
|
62682
|
+
return 0
|
|
62683
|
+
`;
|
|
62589
62684
|
var GAUGE_READ = `
|
|
62590
62685
|
redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', ARGV[1])
|
|
62591
62686
|
return redis.call('ZCARD', KEYS[1])
|
|
62592
62687
|
`;
|
|
62593
62688
|
var GAUGE_RELEASE = `
|
|
62594
62689
|
redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', ARGV[1])
|
|
62595
|
-
|
|
62690
|
+
if ARGV[2] == '' then
|
|
62691
|
+
redis.call('ZPOPMIN', KEYS[1])
|
|
62692
|
+
else
|
|
62693
|
+
redis.call('ZREM', KEYS[1], ARGV[2])
|
|
62694
|
+
end
|
|
62596
62695
|
return 0
|
|
62597
62696
|
`;
|
|
62598
62697
|
var GAUGE_SNAPSHOT = `
|
|
@@ -62601,8 +62700,10 @@ var GAUGE_SNAPSHOT = `
|
|
|
62601
62700
|
redis.call('ZREMRANGEBYSCORE', key, '-inf', ARGV[1])
|
|
62602
62701
|
local count = redis.call('ZCARD', key)
|
|
62603
62702
|
if count > 0 then
|
|
62604
|
-
|
|
62605
|
-
|
|
62703
|
+
if string.sub(key, 1, string.len(ARGV[2])) == ARGV[2] then
|
|
62704
|
+
out[#out + 1] = key
|
|
62705
|
+
out[#out + 1] = count
|
|
62706
|
+
end
|
|
62606
62707
|
else
|
|
62607
62708
|
redis.call('SREM', KEYS[1], key)
|
|
62608
62709
|
end
|
|
@@ -62667,6 +62768,7 @@ var SCRIPTS = [
|
|
|
62667
62768
|
WINDOW_CLAIM,
|
|
62668
62769
|
WINDOW_ROLLBACK,
|
|
62669
62770
|
GAUGE_ACQUIRE,
|
|
62771
|
+
GAUGE_RENEW,
|
|
62670
62772
|
GAUGE_READ,
|
|
62671
62773
|
GAUGE_RELEASE,
|
|
62672
62774
|
GAUGE_SNAPSHOT,
|
|
@@ -62701,6 +62803,10 @@ function redisCoord(deps) {
|
|
|
62701
62803
|
const colon = name.indexOf(":");
|
|
62702
62804
|
return `${NS}gidx:${colon === -1 ? name : name.slice(0, colon + 1)}`;
|
|
62703
62805
|
};
|
|
62806
|
+
const blankHolder = (holder) => {
|
|
62807
|
+
if (holder === "")
|
|
62808
|
+
throw new TypeError("gauge holder must be a non-empty string");
|
|
62809
|
+
};
|
|
62704
62810
|
let faults = 0;
|
|
62705
62811
|
const fault = (error62) => {
|
|
62706
62812
|
healthy = false;
|
|
@@ -62836,20 +62942,28 @@ function redisCoord(deps) {
|
|
|
62836
62942
|
}
|
|
62837
62943
|
},
|
|
62838
62944
|
gauge: {
|
|
62839
|
-
acquire(name, ttlMs) {
|
|
62840
|
-
|
|
62945
|
+
acquire(name, ttlMs, holder) {
|
|
62946
|
+
blankHolder(holder);
|
|
62947
|
+
return attempt2(async () => await evalScript(GAUGE_ACQUIRE, [key("g", name), indexOf2(name)], [now(), ttlMs, holder ?? crypto.randomUUID()]), () => fallback.gauge.acquire(name, ttlMs, holder));
|
|
62948
|
+
},
|
|
62949
|
+
renew(name, holder, ttlMs) {
|
|
62950
|
+
blankHolder(holder);
|
|
62951
|
+
return attempt2(async () => {
|
|
62952
|
+
await evalScript(GAUGE_RENEW, [key("g", name)], [now(), ttlMs, holder]);
|
|
62953
|
+
}, () => fallback.gauge.renew(name, holder, ttlMs));
|
|
62841
62954
|
},
|
|
62842
|
-
release(name) {
|
|
62955
|
+
release(name, holder) {
|
|
62956
|
+
blankHolder(holder);
|
|
62843
62957
|
return attempt2(async () => {
|
|
62844
|
-
await evalScript(GAUGE_RELEASE, [key("g", name)], [now()]);
|
|
62845
|
-
}, () => fallback.gauge.release(name));
|
|
62958
|
+
await evalScript(GAUGE_RELEASE, [key("g", name)], [now(), holder ?? ""]);
|
|
62959
|
+
}, () => fallback.gauge.release(name, holder));
|
|
62846
62960
|
},
|
|
62847
62961
|
read(name) {
|
|
62848
62962
|
return attempt2(async () => await evalScript(GAUGE_READ, [key("g", name)], [now()]), () => fallback.gauge.read(name));
|
|
62849
62963
|
},
|
|
62850
62964
|
snapshot(prefix2) {
|
|
62851
62965
|
return attempt2(async () => {
|
|
62852
|
-
const flat = await evalScript(GAUGE_SNAPSHOT, [indexOf2(prefix2)], [now()]);
|
|
62966
|
+
const flat = await evalScript(GAUGE_SNAPSHOT, [indexOf2(prefix2)], [now(), key("g", prefix2)]);
|
|
62853
62967
|
const out = new Map;
|
|
62854
62968
|
for (let i = 0;i + 1 < flat.length; i += 2) {
|
|
62855
62969
|
out.set(String(flat[i]).slice(key("g", "").length), Number(flat[i + 1]));
|
package/package.json
CHANGED