@kindgi/bounds 0.1.8-rc.0 → 0.1.9-rc.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 -0
- package/dist/budget.d.ts +22 -0
- package/dist/budget.d.ts.map +1 -1
- package/dist/budget.js +33 -0
- package/dist/budget.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/budget.ts +46 -0
- package/src/index.ts +1 -0
package/README.md
CHANGED
|
@@ -56,6 +56,12 @@ await runAsTenant(tenantId, () => handle(request));
|
|
|
56
56
|
await runAsTenant(tenantId, () => publish(request), { compiles: 'all' });
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
+
Work that runs on another thread, such as a template rendered in a worker,
|
|
60
|
+
is charged with `TenantTimeBudget.admit(tenantId)`. It checks the budget
|
|
61
|
+
when the work is asked for, refusing a tenant past it, and returns a
|
|
62
|
+
`TenantWork` whose `start()` and `end()` charge the time between them.
|
|
63
|
+
Time the work spends waiting for a thread isn't charged.
|
|
64
|
+
|
|
59
65
|
## Patterns
|
|
60
66
|
|
|
61
67
|
`compileTenantPattern(source, flags)` compiles a pattern a tenant wrote, a
|
package/dist/budget.d.ts
CHANGED
|
@@ -32,6 +32,20 @@ export interface BudgetClock {
|
|
|
32
32
|
}
|
|
33
33
|
/** The system's clock, read when asked: `Date.now` and `performance.now`. */
|
|
34
34
|
export declare const SYSTEM_CLOCK: BudgetClock;
|
|
35
|
+
/**
|
|
36
|
+
* A piece of a tenant's work that runs somewhere else and ends later (a
|
|
37
|
+
* render in a child process), charged for the time from its `start` to
|
|
38
|
+
* its `end`.
|
|
39
|
+
*/
|
|
40
|
+
export interface TenantWork {
|
|
41
|
+
/** The work started: its time counts from now. A second call changes nothing. */
|
|
42
|
+
start(): void;
|
|
43
|
+
/**
|
|
44
|
+
* The work ended: charges the time since `start`, a failed piece's too.
|
|
45
|
+
* Work that never started is charged nothing. A second call changes nothing.
|
|
46
|
+
*/
|
|
47
|
+
end(): void;
|
|
48
|
+
}
|
|
35
49
|
/**
|
|
36
50
|
* The time each tenant spent on one kind of work in the last 60 seconds,
|
|
37
51
|
* against `budgetMs`; `refuse` makes the error for a tenant past it. An
|
|
@@ -52,6 +66,14 @@ export declare class TenantTimeBudget {
|
|
|
52
66
|
* budget. Its time is charged, a failed piece's too.
|
|
53
67
|
*/
|
|
54
68
|
charge<T>(tenant: string, work: () => T): T;
|
|
69
|
+
/**
|
|
70
|
+
* For work that runs somewhere else and ends later (a render in a worker
|
|
71
|
+
* thread): refused as `charge` refuses, now, before it's handed over,
|
|
72
|
+
* once the tenant has spent its budget. The work returned is charged for
|
|
73
|
+
* the time from its `start()` to its `end()`, as work that started then,
|
|
74
|
+
* so time it spends waiting to start isn't counted.
|
|
75
|
+
*/
|
|
76
|
+
admit(tenant: string): TenantWork;
|
|
55
77
|
/** Once a window: drops the work that left it, and the tenants with none left. */
|
|
56
78
|
private sweep;
|
|
57
79
|
/** Throws `refuse`'s error when `tenant` has spent its budget. */
|
package/dist/budget.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAEH,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,QAAS,CAAC;AAEvC,6EAA6E;AAC7E,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,GAAG,sBAAsB,CAAC;AAE/E;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAGxC,QAAQ,CAAC,KAAK,EAAE,iBAAiB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM;gBAH7B,OAAO,EAAE,MAAM,EACN,KAAK,EAAE,iBAAiB,EACxB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM;CAKhC;AAED,qCAAqC;AACrC,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,GAAG,IAAI,MAAM,CAAC;IACd,wEAAwE;IACxE,SAAS,IAAI,MAAM,CAAC;CACrB;AAED,6EAA6E;AAC7E,eAAO,MAAM,YAAY,EAAE,WAG1B,CAAC;AAyBF;;;;;GAKG;AACH,qBAAa,gBAAgB;IAMzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAPxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,OAAO,CAAK;gBAGD,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,iBAAiB,EACrE,KAAK,GAAE,WAA0B;IAKpD;;;;OAIG;IACH,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC;IAa3C,kFAAkF;IAClF,OAAO,CAAC,KAAK;IAQb,kEAAkE;IAClE,OAAO,CAAC,KAAK;IAoBb,6DAA6D;IAC7D,OAAO,CAAC,KAAK;IAYb,iGAAiG;IACjG,OAAO,CAAC,QAAQ;IAiBhB,OAAO,CAAC,QAAQ;CAQjB"}
|
|
1
|
+
{"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AAEH,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,QAAS,CAAC;AAEvC,6EAA6E;AAC7E,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,GAAG,sBAAsB,CAAC;AAE/E;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAGxC,QAAQ,CAAC,KAAK,EAAE,iBAAiB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM;gBAH7B,OAAO,EAAE,MAAM,EACN,KAAK,EAAE,iBAAiB,EACxB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM;CAKhC;AAED,qCAAqC;AACrC,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,GAAG,IAAI,MAAM,CAAC;IACd,wEAAwE;IACxE,SAAS,IAAI,MAAM,CAAC;CACrB;AAED,6EAA6E;AAC7E,eAAO,MAAM,YAAY,EAAE,WAG1B,CAAC;AAyBF;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,iFAAiF;IACjF,KAAK,IAAI,IAAI,CAAC;IACd;;;OAGG;IACH,GAAG,IAAI,IAAI,CAAC;CACb;AAKD;;;;;GAKG;AACH,qBAAa,gBAAgB;IAMzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAPxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,OAAO,CAAK;gBAGD,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,iBAAiB,EACrE,KAAK,GAAE,WAA0B;IAKpD;;;;OAIG;IACH,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC;IAa3C;;;;;;OAMG;IACH,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU;IAqBjC,kFAAkF;IAClF,OAAO,CAAC,KAAK;IAQb,kEAAkE;IAClE,OAAO,CAAC,KAAK;IAoBb,6DAA6D;IAC7D,OAAO,CAAC,KAAK;IAYb,iGAAiG;IACjG,OAAO,CAAC,QAAQ;IAiBhB,OAAO,CAAC,QAAQ;CAQjB"}
|
package/dist/budget.js
CHANGED
|
@@ -34,6 +34,8 @@ export const SYSTEM_CLOCK = {
|
|
|
34
34
|
now: () => Date.now(),
|
|
35
35
|
monotonic: () => performance.now(),
|
|
36
36
|
};
|
|
37
|
+
/** Work no budget counts. */
|
|
38
|
+
const UNCOUNTED = Object.freeze({ start: () => undefined, end: () => undefined });
|
|
37
39
|
/**
|
|
38
40
|
* The time each tenant spent on one kind of work in the last 60 seconds,
|
|
39
41
|
* against `budgetMs`; `refuse` makes the error for a tenant past it. An
|
|
@@ -72,6 +74,37 @@ export class TenantTimeBudget {
|
|
|
72
74
|
this.spend(tenant, now, this.clock.monotonic() - started);
|
|
73
75
|
}
|
|
74
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* For work that runs somewhere else and ends later (a render in a worker
|
|
79
|
+
* thread): refused as `charge` refuses, now, before it's handed over,
|
|
80
|
+
* once the tenant has spent its budget. The work returned is charged for
|
|
81
|
+
* the time from its `start()` to its `end()`, as work that started then,
|
|
82
|
+
* so time it spends waiting to start isn't counted.
|
|
83
|
+
*/
|
|
84
|
+
admit(tenant) {
|
|
85
|
+
if (this.budgetMs === Number.POSITIVE_INFINITY)
|
|
86
|
+
return UNCOUNTED;
|
|
87
|
+
const now = this.clock.now();
|
|
88
|
+
this.sweep(now);
|
|
89
|
+
this.check(tenant, now);
|
|
90
|
+
let started;
|
|
91
|
+
let ended = false;
|
|
92
|
+
return {
|
|
93
|
+
start: () => {
|
|
94
|
+
if (started !== undefined || ended)
|
|
95
|
+
return;
|
|
96
|
+
started = { at: this.clock.now(), monotonic: this.clock.monotonic() };
|
|
97
|
+
},
|
|
98
|
+
end: () => {
|
|
99
|
+
if (ended)
|
|
100
|
+
return;
|
|
101
|
+
ended = true;
|
|
102
|
+
if (started === undefined)
|
|
103
|
+
return;
|
|
104
|
+
this.spend(tenant, started.at, this.clock.monotonic() - started.monotonic);
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
75
108
|
/** Once a window: drops the work that left it, and the tenants with none left. */
|
|
76
109
|
sweep(now) {
|
|
77
110
|
if (now - this.sweptAt <= BUDGET_WINDOW_MS)
|
package/dist/budget.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC;;;;;;;;GAQG;AAEH,wEAAwE;AACxE,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAKvC;;;;;GAKG;AACH,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IAG/B;IACA;IACA;IAJX,YACE,OAAe,EACN,KAAwB,EACxB,QAAgB,EAChB,YAAoB;QAE7B,KAAK,CAAC,OAAO,CAAC,CAAC;QAJN,UAAK,GAAL,KAAK,CAAmB;QACxB,aAAQ,GAAR,QAAQ,CAAQ;QAChB,iBAAY,GAAZ,YAAY,CAAQ;QAG7B,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CACF;AAUD,6EAA6E;AAC7E,MAAM,CAAC,MAAM,YAAY,GAAgB;IACvC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;IACrB,SAAS,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;CACnC,CAAC;
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../src/budget.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { HOSTED_BOUNDS, SELF_HOSTED_BOUNDS, type TenantInputBounds, configureTenantInputBounds, tenantInputBounds, } from './bounds.js';
|
|
2
|
-
export { BUDGET_WINDOW_MS, type BudgetClock, SYSTEM_CLOCK, TenantBudgetError, type TenantBudgetLimit, TenantTimeBudget, } from './budget.js';
|
|
2
|
+
export { BUDGET_WINDOW_MS, type BudgetClock, SYSTEM_CLOCK, TenantBudgetError, type TenantBudgetLimit, TenantTimeBudget, type TenantWork, } from './budget.js';
|
|
3
3
|
export { type CompiledTenantPattern, type TenantPattern, compileTenantPattern, tenantPatternSyntaxProblem, } from './pattern.js';
|
|
4
4
|
export { type RunAsTenantOptions, type TenantCompiles, type TenantScope, currentTenant, runAsTenant, runOutsideTenant, } from './tenant.js';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,0BAA0B,EAC1B,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,KAAK,WAAW,EAChB,YAAY,EACZ,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,0BAA0B,EAC1B,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,KAAK,WAAW,EAChB,YAAY,EACZ,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,KAAK,UAAU,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAClB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,aAAa,EACb,WAAW,EACX,gBAAgB,GACjB,MAAM,aAAa,CAAC"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC,OAAO,EACL,aAAa,EACb,kBAAkB,EAElB,0BAA0B,EAC1B,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAEhB,YAAY,EACZ,iBAAiB,EAEjB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,iCAAiC;AAEjC,OAAO,EACL,aAAa,EACb,kBAAkB,EAElB,0BAA0B,EAC1B,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAEhB,YAAY,EACZ,iBAAiB,EAEjB,gBAAgB,GAEjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAGL,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,cAAc,CAAC;AACtB,OAAO,EAIL,aAAa,EACb,WAAW,EACX,gBAAgB,GACjB,MAAM,aAAa,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kindgi/bounds",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9-rc.0",
|
|
4
4
|
"description": "The limits a Kindgi server puts on what a tenant sends it: pattern length and engine (V8, or linear-time RE2 when hosted), schema size and depth, template limits, and the size and idle time of bodies read from tenant-named endpoints. Set once at boot; read by the packages that compile or read tenant input.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
package/src/budget.ts
CHANGED
|
@@ -72,6 +72,24 @@ interface Ledger {
|
|
|
72
72
|
refusedUntil: number;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* A piece of a tenant's work that runs somewhere else and ends later (a
|
|
77
|
+
* render in a child process), charged for the time from its `start` to
|
|
78
|
+
* its `end`.
|
|
79
|
+
*/
|
|
80
|
+
export interface TenantWork {
|
|
81
|
+
/** The work started: its time counts from now. A second call changes nothing. */
|
|
82
|
+
start(): void;
|
|
83
|
+
/**
|
|
84
|
+
* The work ended: charges the time since `start`, a failed piece's too.
|
|
85
|
+
* Work that never started is charged nothing. A second call changes nothing.
|
|
86
|
+
*/
|
|
87
|
+
end(): void;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Work no budget counts. */
|
|
91
|
+
const UNCOUNTED: TenantWork = Object.freeze({ start: () => undefined, end: () => undefined });
|
|
92
|
+
|
|
75
93
|
/**
|
|
76
94
|
* The time each tenant spent on one kind of work in the last 60 seconds,
|
|
77
95
|
* against `budgetMs`; `refuse` makes the error for a tenant past it. An
|
|
@@ -109,6 +127,34 @@ export class TenantTimeBudget {
|
|
|
109
127
|
}
|
|
110
128
|
}
|
|
111
129
|
|
|
130
|
+
/**
|
|
131
|
+
* For work that runs somewhere else and ends later (a render in a worker
|
|
132
|
+
* thread): refused as `charge` refuses, now, before it's handed over,
|
|
133
|
+
* once the tenant has spent its budget. The work returned is charged for
|
|
134
|
+
* the time from its `start()` to its `end()`, as work that started then,
|
|
135
|
+
* so time it spends waiting to start isn't counted.
|
|
136
|
+
*/
|
|
137
|
+
admit(tenant: string): TenantWork {
|
|
138
|
+
if (this.budgetMs === Number.POSITIVE_INFINITY) return UNCOUNTED;
|
|
139
|
+
const now = this.clock.now();
|
|
140
|
+
this.sweep(now);
|
|
141
|
+
this.check(tenant, now);
|
|
142
|
+
let started: { readonly at: number; readonly monotonic: number } | undefined;
|
|
143
|
+
let ended = false;
|
|
144
|
+
return {
|
|
145
|
+
start: () => {
|
|
146
|
+
if (started !== undefined || ended) return;
|
|
147
|
+
started = { at: this.clock.now(), monotonic: this.clock.monotonic() };
|
|
148
|
+
},
|
|
149
|
+
end: () => {
|
|
150
|
+
if (ended) return;
|
|
151
|
+
ended = true;
|
|
152
|
+
if (started === undefined) return;
|
|
153
|
+
this.spend(tenant, started.at, this.clock.monotonic() - started.monotonic);
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
112
158
|
/** Once a window: drops the work that left it, and the tenants with none left. */
|
|
113
159
|
private sweep(now: number): void {
|
|
114
160
|
if (now - this.sweptAt <= BUDGET_WINDOW_MS) return;
|