aweshare 0.6.8 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/apps/agent/dist/cli.js +3 -4
- package/apps/agent/dist/cli.js.map +1 -1
- package/apps/agent/dist/config.d.ts +4 -1
- package/apps/agent/dist/config.js +5 -0
- package/apps/agent/dist/config.js.map +1 -1
- package/apps/agent/dist/connection.js +4 -0
- package/apps/agent/dist/connection.js.map +1 -1
- package/apps/agent/dist/doctor.js +3 -1
- package/apps/agent/dist/doctor.js.map +1 -1
- package/apps/agent/dist/table.js +7 -7
- package/apps/agent/dist/table.js.map +1 -1
- package/apps/consumer/dist/cli.js +65 -8
- package/apps/consumer/dist/cli.js.map +1 -1
- package/apps/consumer/dist/table.js +2 -2
- package/apps/consumer/dist/table.js.map +1 -1
- package/apps/consumer/dist/watch.d.ts +18 -0
- package/apps/consumer/dist/watch.js +69 -0
- package/apps/consumer/dist/watch.js.map +1 -0
- package/apps/hub/dist/cli.js +3 -4
- package/apps/hub/dist/cli.js.map +1 -1
- package/apps/hub/dist/consumer.d.ts +1 -1
- package/apps/hub/dist/consumer.js +4 -4
- package/apps/hub/dist/consumer.js.map +1 -1
- package/apps/hub/dist/local.d.ts +1 -1
- package/apps/hub/dist/local.js +5 -1
- package/apps/hub/dist/local.js.map +1 -1
- package/apps/hub/dist/table.js +14 -8
- package/apps/hub/dist/table.js.map +1 -1
- package/apps/hub/dist/tunnel.d.ts +1 -1
- package/apps/hub/dist/tunnel.js +4 -1
- package/apps/hub/dist/tunnel.js.map +1 -1
- package/package.json +1 -1
- package/packages/producer-core/dist/catalog.d.ts +7 -0
- package/packages/producer-core/dist/catalog.js +5 -1
- package/packages/producer-core/dist/catalog.js.map +1 -1
- package/packages/producer-core/dist/health.d.ts +28 -8
- package/packages/producer-core/dist/health.js +63 -8
- package/packages/producer-core/dist/health.js.map +1 -1
- package/packages/protocol/dist/format.d.ts +6 -0
- package/packages/protocol/dist/format.js +9 -0
- package/packages/protocol/dist/format.js.map +1 -0
- package/packages/protocol/dist/index.d.ts +1 -0
- package/packages/protocol/dist/index.js +1 -0
- package/packages/protocol/dist/index.js.map +1 -1
- package/packages/protocol/dist/messages.d.ts +7 -3
- package/packages/protocol/dist/messages.js.map +1 -1
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
/** Consecutive upstream 5xx failures >= threshold -> 'unstable': report-only
|
|
2
|
+
* middle state — the alias stays listed and dispatch continues, consumers just
|
|
3
|
+
* see the warning and the errors keep passing through verbatim. */
|
|
4
|
+
const UNSTABLE_THRESHOLD = 2;
|
|
1
5
|
/** AUTH/QUOTA consecutive failures >= threshold -> degraded until a success. */
|
|
2
6
|
const DEGRADE_THRESHOLD = 2;
|
|
7
|
+
/** SERVER (upstream 5xx) consecutive failures >= threshold -> degraded, and
|
|
8
|
+
* only when `degradeOn5xx` opted in. Higher than AUTH/QUOTA's 2: a 401 is a
|
|
9
|
+
* deterministic account verdict, while 5xx pairs also come from transient
|
|
10
|
+
* upstream blips — degrading those would turn a momentary hiccup into a
|
|
11
|
+
* full 503 outage for every consumer on the alias. */
|
|
12
|
+
const SERVER_DEGRADE_THRESHOLD = 3;
|
|
3
13
|
// Recovery-probe backoff, awewarm-style: while degraded, each failed probe
|
|
4
14
|
// doubles the wait before the next one, so an exhausted quota isn't pinged at
|
|
5
15
|
// the base cadence for hours on end. Any success clears the degraded state
|
|
@@ -21,14 +31,20 @@ const PROBE_CAP_SCHEDULE = [
|
|
|
21
31
|
];
|
|
22
32
|
/**
|
|
23
33
|
* Per-backend health state. Degraded backends are reported in heartbeats and
|
|
24
|
-
* the hub stops dispatching to their offerings until they recover. The
|
|
25
|
-
*
|
|
34
|
+
* the hub stops dispatching to their offerings until they recover. The ladder
|
|
35
|
+
* is two rungs — healthy -> degraded, latched until a success — which
|
|
26
36
|
* for a relay is what awewarm's deeper ladder collapses to: its intermediate
|
|
27
37
|
* rungs trade probe expense against recovery speed, and a relay's probes are
|
|
28
38
|
* cheap pings, not quota-consuming activations. What does carry over from
|
|
29
39
|
* awewarm is the escalating probe schedule above: the longer a backend has
|
|
30
40
|
* been continuously degraded, the quieter its recovery probes become, down
|
|
31
41
|
* to a daily last gasp that never fully gives up.
|
|
42
|
+
*
|
|
43
|
+
* Upstream 5xx gets its own two-step path: 2 consecutive SERVER failures
|
|
44
|
+
* enter the report-only 'unstable' state (alias stays listed and dispatched,
|
|
45
|
+
* consumers see the warning), and with `degradeOn5xx` opted in, 3
|
|
46
|
+
* consecutive degrade for real. AUTH/QUOTA verdicts skip the middle state —
|
|
47
|
+
* they are deterministic account facts, not symptoms.
|
|
32
48
|
*/
|
|
33
49
|
export class HealthGate {
|
|
34
50
|
now;
|
|
@@ -38,6 +54,13 @@ export class HealthGate {
|
|
|
38
54
|
probeDelayMs = new Map();
|
|
39
55
|
probeNotBefore = new Map();
|
|
40
56
|
lastOk = new Map();
|
|
57
|
+
/** Backends sitting in the report-only middle state (2+ consecutive 5xx). */
|
|
58
|
+
unstable = new Set();
|
|
59
|
+
/** Opt-in enforcement step for upstream 5xx: 3+ consecutive SERVER failures
|
|
60
|
+
* degrade the backend (dispatch stops). Off by default — a 5xx is a symptom,
|
|
61
|
+
* not a verdict, so by default it only ever reports (unstable). Hot-reloaded
|
|
62
|
+
* by the config watcher; flipping it mid-flight affects the next failure. */
|
|
63
|
+
degradeOn5xx = false;
|
|
41
64
|
/** The clock is injected so tests can walk the cap ladder without waiting. */
|
|
42
65
|
constructor(now = Date.now) {
|
|
43
66
|
this.now = now;
|
|
@@ -47,10 +70,11 @@ export class HealthGate {
|
|
|
47
70
|
this.lastOk.set(backendId, this.now());
|
|
48
71
|
this.consecutive.delete(backendId);
|
|
49
72
|
const wasDegraded = this.degraded.delete(backendId);
|
|
73
|
+
const wasUnstable = this.unstable.delete(backendId);
|
|
50
74
|
this.degradedSince.delete(backendId);
|
|
51
75
|
this.probeDelayMs.delete(backendId);
|
|
52
76
|
this.probeNotBefore.delete(backendId);
|
|
53
|
-
return wasDegraded ? 'recovered' : null;
|
|
77
|
+
return wasDegraded || wasUnstable ? 'recovered' : null;
|
|
54
78
|
}
|
|
55
79
|
if (reason === undefined || reason === 'CANCELLED')
|
|
56
80
|
return null;
|
|
@@ -64,12 +88,23 @@ export class HealthGate {
|
|
|
64
88
|
const count = current?.reason === reason ? current.count + 1 : 1;
|
|
65
89
|
this.consecutive.set(backendId, { reason, count });
|
|
66
90
|
let transition = null;
|
|
67
|
-
|
|
91
|
+
const degradeNow = ((reason === 'AUTH' || reason === 'QUOTA') && count >= DEGRADE_THRESHOLD) ||
|
|
92
|
+
(reason === 'SERVER' && this.degradeOn5xx && count >= SERVER_DEGRADE_THRESHOLD);
|
|
93
|
+
if (degradeNow) {
|
|
68
94
|
if (!wasDegraded) {
|
|
69
95
|
transition = 'degraded';
|
|
70
96
|
this.degradedSince.set(backendId, this.now());
|
|
71
97
|
}
|
|
72
98
|
this.degraded.set(backendId, { state: 'degraded', reason });
|
|
99
|
+
this.unstable.delete(backendId);
|
|
100
|
+
}
|
|
101
|
+
else if (reason === 'SERVER' && count >= UNSTABLE_THRESHOLD && !wasDegraded) {
|
|
102
|
+
// first crossing of the 5xx threshold: report only — dispatch keeps
|
|
103
|
+
// flowing so a transient upstream blip never becomes a full outage
|
|
104
|
+
if (!this.unstable.has(backendId)) {
|
|
105
|
+
this.unstable.add(backendId);
|
|
106
|
+
transition = 'unstable';
|
|
107
|
+
}
|
|
73
108
|
}
|
|
74
109
|
if (wasDegraded) {
|
|
75
110
|
const since = this.degradedSince.get(backendId) ?? this.now();
|
|
@@ -90,10 +125,17 @@ export class HealthGate {
|
|
|
90
125
|
isDegraded(backendId) {
|
|
91
126
|
return this.degraded.has(backendId);
|
|
92
127
|
}
|
|
128
|
+
/** The report-only middle state — listed and dispatched, just flagged. */
|
|
129
|
+
isUnstable(backendId) {
|
|
130
|
+
return this.unstable.has(backendId);
|
|
131
|
+
}
|
|
93
132
|
statusMap() {
|
|
94
133
|
const out = {};
|
|
95
134
|
for (const [id, status] of this.degraded)
|
|
96
135
|
out[id] = status;
|
|
136
|
+
for (const id of this.unstable)
|
|
137
|
+
if (out[id] === undefined)
|
|
138
|
+
out[id] = { state: 'unstable' };
|
|
97
139
|
return out;
|
|
98
140
|
}
|
|
99
141
|
/** Epoch ms of the backend's last success (request or recovery probe); null
|
|
@@ -104,8 +146,9 @@ export class HealthGate {
|
|
|
104
146
|
}
|
|
105
147
|
/** Heartbeat payload covering every backend, not just the degraded ones:
|
|
106
148
|
* one 'ok' entry carrying lastOkAt per healthy backend, the degraded entry
|
|
107
|
-
* as statusMap would emit it
|
|
108
|
-
*
|
|
149
|
+
* as statusMap would emit it, and 'unstable' for 2+ consecutive-5xx
|
|
150
|
+
* backends. Old hubs ignore the extra entries (their status check only
|
|
151
|
+
* looks for state === 'degraded', so unstable renders as online there). */
|
|
109
152
|
snapshot(ids) {
|
|
110
153
|
const out = {};
|
|
111
154
|
for (const id of ids) {
|
|
@@ -115,7 +158,10 @@ export class HealthGate {
|
|
|
115
158
|
continue;
|
|
116
159
|
}
|
|
117
160
|
const at = this.lastOk.get(id);
|
|
118
|
-
|
|
161
|
+
const lastOkAt = at === undefined ? {} : { lastOkAt: at };
|
|
162
|
+
out[id] = this.unstable.has(id)
|
|
163
|
+
? { state: 'unstable', ...lastOkAt }
|
|
164
|
+
: { state: 'ok', ...lastOkAt };
|
|
119
165
|
}
|
|
120
166
|
return out;
|
|
121
167
|
}
|
|
@@ -126,11 +172,18 @@ export function logHealthTransition(log, backendId, transition, detail) {
|
|
|
126
172
|
if (transition === 'degraded') {
|
|
127
173
|
log.warn(`backend ${backendId} degraded${detail ? ` (${detail})` : ''}`);
|
|
128
174
|
}
|
|
175
|
+
else if (transition === 'unstable') {
|
|
176
|
+
log.warn(`backend ${backendId} unstable — upstream failing, still dispatching${detail ? ` (${detail})` : ''}`);
|
|
177
|
+
}
|
|
129
178
|
else if (transition === 'recovered') {
|
|
130
179
|
log.info(`backend ${backendId} recovered${detail ? ` — ${detail}` : ''}`);
|
|
131
180
|
}
|
|
132
181
|
}
|
|
133
|
-
/** Map an upstream HTTP status to a failure class (ok responses pass null).
|
|
182
|
+
/** Map an upstream HTTP status to a failure class (ok responses pass null).
|
|
183
|
+
* SERVER (5xx) means the upstream itself is failing — a symptom that reports
|
|
184
|
+
* early (unstable) and, opted-in, degrades when persistent. HTTP (other 4xx)
|
|
185
|
+
* is request-shaped trouble — one consumer's malformed request — and never
|
|
186
|
+
* touches the ladder. */
|
|
134
187
|
export function classifyStatus(status) {
|
|
135
188
|
if (status < 400)
|
|
136
189
|
return null;
|
|
@@ -138,6 +191,8 @@ export function classifyStatus(status) {
|
|
|
138
191
|
return 'AUTH';
|
|
139
192
|
if (status === 402 || status === 429)
|
|
140
193
|
return 'QUOTA';
|
|
194
|
+
if (status >= 500)
|
|
195
|
+
return 'SERVER';
|
|
141
196
|
return 'HTTP';
|
|
142
197
|
}
|
|
143
198
|
//# sourceMappingURL=health.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.js","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Human-facing number rendering, kept alongside the time formatters: the
|
|
2
|
+
* wire, the SQLite rows and `--json` stay raw integers — only what a human
|
|
3
|
+
* reads is grouped. */
|
|
4
|
+
/** Thousands grouping with a fixed ',' — locale-independent so CLI output
|
|
5
|
+
* stays stable and diffable ('1000000' → '1,000,000'). Integers only. */
|
|
6
|
+
export declare function fmtTokens(n: number): string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Human-facing number rendering, kept alongside the time formatters: the
|
|
2
|
+
* wire, the SQLite rows and `--json` stay raw integers — only what a human
|
|
3
|
+
* reads is grouped. */
|
|
4
|
+
/** Thousands grouping with a fixed ',' — locale-independent so CLI output
|
|
5
|
+
* stays stable and diffable ('1000000' → '1,000,000'). Integers only. */
|
|
6
|
+
export function fmtTokens(n) {
|
|
7
|
+
return String(n).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;uBAEuB;AAEvB;yEACyE;AACzE,MAAM,UAAU,SAAS,CAAC,CAAS;IACjC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAA;AACxD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
|
|
@@ -25,14 +25,18 @@ export interface Offering {
|
|
|
25
25
|
/** Shared per-alias token budget per UTC day; hub default 1000000, 0 = unlimited. */
|
|
26
26
|
dailyTokens?: number;
|
|
27
27
|
}
|
|
28
|
-
export type BackendState = 'ok' | 'degraded';
|
|
28
|
+
export type BackendState = 'ok' | 'unstable' | 'degraded';
|
|
29
29
|
export interface BackendStatus {
|
|
30
30
|
state: BackendState;
|
|
31
|
-
/** Failure class when degraded: AUTH | QUOTA | HTTP | NETWORK | CANCELLED
|
|
31
|
+
/** Failure class when degraded: AUTH | QUOTA | SERVER | HTTP | NETWORK | CANCELLED.
|
|
32
|
+
* 'unstable' entries carry no reason — they are always 2+ consecutive
|
|
33
|
+
* upstream 5xx (SERVER). Old hubs only check for state === 'degraded', so
|
|
34
|
+
* the extra 'unstable' state degrades gracefully to online there. */
|
|
32
35
|
reason?: string;
|
|
33
36
|
/** Epoch ms of the last successful upstream interaction (a relayed request
|
|
34
37
|
* or a recovery probe); absent when the backend has never succeeded. Only
|
|
35
|
-
* meaningful on
|
|
38
|
+
* meaningful on non-degraded entries — the hub's freshness evidence for
|
|
39
|
+
* consumers. */
|
|
36
40
|
lastOkAt?: number;
|
|
37
41
|
}
|
|
38
42
|
export interface RegisterMessage {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAA;AAI7B,MAAM,CAAC,MAAM,SAAS,GAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;AAElF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,MAAM,EAAE,aAAa;IACrB,SAAS,EAAE,kBAAkB;IAC7B,SAAS,EAAE,WAAW;CACvB,CAAA;AAED,gFAAgF;AAChF,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAQ,eAA0C,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAA;AAC1E,CAAC;
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAA;AAI7B,MAAM,CAAC,MAAM,SAAS,GAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;AAElF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,MAAM,EAAE,aAAa;IACrB,SAAS,EAAE,kBAAkB;IAC7B,SAAS,EAAE,WAAW;CACvB,CAAA;AAED,gFAAgF;AAChF,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAQ,eAA0C,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAA;AAC1E,CAAC;AAyHD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAS;IAClC,UAAU;IACV,WAAW;IACX,eAAe;IACf,cAAc;IACd,gBAAgB;IAChB,OAAO;IACP,YAAY;IACZ,eAAe;IACf,aAAa;IACb,gBAAgB;CACjB,CAAC,CAAA;AAEF,yEAAyE;AACzE,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,IAAI,MAAe,CAAA;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IACpD,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;IACnD,CAAC;IACD,MAAM,IAAI,GAAI,MAA6B,CAAC,IAAI,CAAA;IAChD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,iCAAiC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAClE,CAAC;IACD,OAAO,MAAwB,CAAA;AACjC,CAAC"}
|