deepline 0.1.294 → 0.1.295
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/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +83 -54
- package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +7 -0
- package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +4 -0
- package/dist/bundling-sources/shared_libs/play-runtime/pacing.ts +11 -1
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.mjs +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
|
@@ -155,7 +155,7 @@ export const SDK_RELEASE = {
|
|
|
155
155
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
156
156
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
157
157
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
158
|
-
version: '0.1.
|
|
158
|
+
version: '0.1.295',
|
|
159
159
|
contracts: {
|
|
160
160
|
api: {
|
|
161
161
|
name: 'sdk-http-api',
|
package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts
CHANGED
|
@@ -228,13 +228,14 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
228
228
|
|
|
229
229
|
const ordered = [...rules].sort((a, b) => a.ruleId.localeCompare(b.ruleId));
|
|
230
230
|
const rulesKey = rulesSignature(ordered);
|
|
231
|
+
const laneKey = rateLaneKey(bucketId, rulesKey);
|
|
231
232
|
|
|
232
233
|
// Drawing a cached permit is a synchronous, single-threaded critical
|
|
233
234
|
// section (`drawFromBlock` has no `await`), so concurrent acquires can never
|
|
234
235
|
// hand out the same permit — no lock is needed for the fast path. The ONLY
|
|
235
236
|
// thing that needs coordination is the block refill, which we single-flight
|
|
236
|
-
// per bucket: one network round-trip (and any window-exhausted
|
|
237
|
-
// the whole
|
|
237
|
+
// per bucket + rule set: one network round-trip (and any window-exhausted
|
|
238
|
+
// sleep) serves the whole matching wave, then everyone re-draws. This replaces the old
|
|
238
239
|
// per-bucket lock that held across the RPC + up-to-5s sleep and thereby
|
|
239
240
|
// serialized every map row behind one sleeping acquirer.
|
|
240
241
|
while (true) {
|
|
@@ -243,7 +244,7 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
243
244
|
? signal.reason
|
|
244
245
|
: new Error('Rate-state acquire aborted.');
|
|
245
246
|
}
|
|
246
|
-
const localPermit = this.drawFromBlock(bucketId,
|
|
247
|
+
const localPermit = this.drawFromBlock(bucketId, laneKey);
|
|
247
248
|
if (localPermit) {
|
|
248
249
|
const waitMs = localPermit.scheduledAtMs - this.now();
|
|
249
250
|
if (waitMs > 0) await this.sleep(waitMs);
|
|
@@ -258,19 +259,20 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
258
259
|
// Count this acquirer as waiting on the refill so the single-flight refill
|
|
259
260
|
// can size its block to the live wave. Decremented once a block lands (or
|
|
260
261
|
// the refill errors) — see the finally in `refillBlock`.
|
|
261
|
-
this.waiters.set(
|
|
262
|
+
this.waiters.set(laneKey, (this.waiters.get(laneKey) ?? 0) + 1);
|
|
262
263
|
try {
|
|
263
264
|
await this.refillBlock(
|
|
264
265
|
bucketId,
|
|
265
266
|
input.rateScopeToken?.trim() || null,
|
|
266
267
|
ordered,
|
|
267
268
|
rulesKey,
|
|
269
|
+
laneKey,
|
|
268
270
|
signal,
|
|
269
271
|
);
|
|
270
272
|
} finally {
|
|
271
|
-
const remaining = (this.waiters.get(
|
|
272
|
-
if (remaining > 0) this.waiters.set(
|
|
273
|
-
else this.waiters.delete(
|
|
273
|
+
const remaining = (this.waiters.get(laneKey) ?? 1) - 1;
|
|
274
|
+
if (remaining > 0) this.waiters.set(laneKey, remaining);
|
|
275
|
+
else this.waiters.delete(laneKey);
|
|
274
276
|
}
|
|
275
277
|
}
|
|
276
278
|
}
|
|
@@ -285,7 +287,7 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
285
287
|
* without reserving a single slot that cannot be used.
|
|
286
288
|
*/
|
|
287
289
|
private requestedForBucket(
|
|
288
|
-
|
|
290
|
+
laneKey: string,
|
|
289
291
|
rules: readonly PacingRule[],
|
|
290
292
|
): number {
|
|
291
293
|
const floor = APP_RUNTIME_RATE_STATE_LEASE_BLOCK_SIZE;
|
|
@@ -294,7 +296,7 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
294
296
|
);
|
|
295
297
|
const horizonBudget = Math.max(
|
|
296
298
|
1,
|
|
297
|
-
Math.ceil(this.effectiveRps.get(
|
|
299
|
+
Math.ceil(this.effectiveRps.get(laneKey) ?? configuredRps),
|
|
298
300
|
);
|
|
299
301
|
const rateBudget = Math.min(
|
|
300
302
|
horizonBudget,
|
|
@@ -303,7 +305,7 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
303
305
|
.filter((value) => Number.isFinite(value) && value > 0),
|
|
304
306
|
);
|
|
305
307
|
if (!Number.isFinite(rateBudget) || rateBudget <= 0) return floor;
|
|
306
|
-
const waiters = this.waiters.get(
|
|
308
|
+
const waiters = this.waiters.get(laneKey) ?? 1;
|
|
307
309
|
const concurrencyLimits = rules.flatMap((rule) =>
|
|
308
310
|
rule.maxConcurrency != null &&
|
|
309
311
|
Number.isFinite(rule.maxConcurrency) &&
|
|
@@ -391,22 +393,24 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
391
393
|
rateScopeToken: string | null,
|
|
392
394
|
ordered: PacingRule[],
|
|
393
395
|
rulesKey: string,
|
|
396
|
+
laneKey: string,
|
|
394
397
|
signal?: AbortSignal,
|
|
395
398
|
): Promise<void> {
|
|
396
|
-
const existing = this.refills.get(
|
|
399
|
+
const existing = this.refills.get(laneKey);
|
|
397
400
|
if (existing) return existing;
|
|
398
401
|
const promise = this.performRefill(
|
|
399
402
|
bucketId,
|
|
400
403
|
rateScopeToken,
|
|
401
404
|
ordered,
|
|
402
405
|
rulesKey,
|
|
406
|
+
laneKey,
|
|
403
407
|
signal,
|
|
404
408
|
).finally(() => {
|
|
405
|
-
if (this.refills.get(
|
|
406
|
-
this.refills.delete(
|
|
409
|
+
if (this.refills.get(laneKey) === promise) {
|
|
410
|
+
this.refills.delete(laneKey);
|
|
407
411
|
}
|
|
408
412
|
});
|
|
409
|
-
this.refills.set(
|
|
413
|
+
this.refills.set(laneKey, promise);
|
|
410
414
|
return promise;
|
|
411
415
|
}
|
|
412
416
|
|
|
@@ -415,6 +419,7 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
415
419
|
rateScopeToken: string | null,
|
|
416
420
|
ordered: PacingRule[],
|
|
417
421
|
rulesKey: string,
|
|
422
|
+
laneKey: string,
|
|
418
423
|
signal?: AbortSignal,
|
|
419
424
|
): Promise<void> {
|
|
420
425
|
let consecutiveFailures = 0;
|
|
@@ -435,24 +440,25 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
435
440
|
if (signal?.aborted) return;
|
|
436
441
|
}
|
|
437
442
|
try {
|
|
438
|
-
const
|
|
443
|
+
const successKey = pendingSuccessKey(bucketId, ordered);
|
|
444
|
+
const observedSuccesses = this.pendingSuccesses.get(successKey) ?? 0;
|
|
439
445
|
const response = await this.port.acquire({
|
|
440
446
|
bucketId,
|
|
441
447
|
rateScopeToken,
|
|
442
448
|
// Stamp adaptiveMaxRps on default-pacing rules so the DB row's ceiling
|
|
443
449
|
// matches the old in-memory AIMD range.
|
|
444
450
|
rules: withAdaptiveMaxRps(ordered),
|
|
445
|
-
requested: this.requestedForBucket(
|
|
451
|
+
requested: this.requestedForBucket(laneKey, ordered),
|
|
446
452
|
observedSuccesses,
|
|
447
453
|
schedulerSchema: this.schedulerSchema,
|
|
448
454
|
});
|
|
449
455
|
if (observedSuccesses > 0) {
|
|
450
456
|
const remaining = Math.max(
|
|
451
457
|
0,
|
|
452
|
-
(this.pendingSuccesses.get(
|
|
458
|
+
(this.pendingSuccesses.get(successKey) ?? 0) - observedSuccesses,
|
|
453
459
|
);
|
|
454
|
-
if (remaining > 0) this.pendingSuccesses.set(
|
|
455
|
-
else this.pendingSuccesses.delete(
|
|
460
|
+
if (remaining > 0) this.pendingSuccesses.set(successKey, remaining);
|
|
461
|
+
else this.pendingSuccesses.delete(successKey);
|
|
456
462
|
}
|
|
457
463
|
this.recordCooldown(bucketId, response);
|
|
458
464
|
if (
|
|
@@ -460,7 +466,7 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
460
466
|
Number(response.effectiveRequestsPerSecond) > 0
|
|
461
467
|
) {
|
|
462
468
|
this.effectiveRps.set(
|
|
463
|
-
|
|
469
|
+
laneKey,
|
|
464
470
|
Number(response.effectiveRequestsPerSecond),
|
|
465
471
|
);
|
|
466
472
|
}
|
|
@@ -472,6 +478,7 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
472
478
|
rateScopeToken,
|
|
473
479
|
ordered,
|
|
474
480
|
rulesKey,
|
|
481
|
+
laneKey,
|
|
475
482
|
response,
|
|
476
483
|
);
|
|
477
484
|
return;
|
|
@@ -523,6 +530,7 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
523
530
|
rateScopeToken: string | null,
|
|
524
531
|
ordered: PacingRule[],
|
|
525
532
|
rulesKey: string,
|
|
533
|
+
laneKey: string,
|
|
526
534
|
response: {
|
|
527
535
|
granted: number;
|
|
528
536
|
leaseIds?: unknown;
|
|
@@ -579,6 +587,7 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
579
587
|
hasConcurrency ? (leaseIds[index] ?? null) : null,
|
|
580
588
|
]),
|
|
581
589
|
rulesKey,
|
|
590
|
+
laneKey,
|
|
582
591
|
ordered,
|
|
583
592
|
);
|
|
584
593
|
}
|
|
@@ -589,7 +598,7 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
589
598
|
cooldownMs: number;
|
|
590
599
|
}): Promise<void> {
|
|
591
600
|
if (input.cooldownMs <= 0) return;
|
|
592
|
-
this.
|
|
601
|
+
this.drainBlocksForBucket(input.bucketId);
|
|
593
602
|
try {
|
|
594
603
|
await this.port.penalize({
|
|
595
604
|
bucketId: input.bucketId,
|
|
@@ -609,10 +618,14 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
609
618
|
}
|
|
610
619
|
}
|
|
611
620
|
|
|
612
|
-
observeSuccess(input: {
|
|
621
|
+
observeSuccess(input: {
|
|
622
|
+
bucketId: string;
|
|
623
|
+
rules: readonly PacingRule[];
|
|
624
|
+
}): void {
|
|
625
|
+
const key = pendingSuccessKey(input.bucketId, input.rules);
|
|
613
626
|
this.pendingSuccesses.set(
|
|
614
|
-
|
|
615
|
-
Math.min(1_000_000, (this.pendingSuccesses.get(
|
|
627
|
+
key,
|
|
628
|
+
Math.min(1_000_000, (this.pendingSuccesses.get(key) ?? 0) + 1),
|
|
616
629
|
);
|
|
617
630
|
}
|
|
618
631
|
|
|
@@ -645,12 +658,13 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
645
658
|
rateScopeToken: string | null,
|
|
646
659
|
permits: LeasedBlock['permits'],
|
|
647
660
|
rulesKey: string,
|
|
661
|
+
laneKey: string,
|
|
648
662
|
rules: PacingRule[],
|
|
649
663
|
): void {
|
|
650
664
|
const lastScheduledAtMs = permits.at(-1)?.[0] ?? this.now();
|
|
651
665
|
const freshExpiresAt =
|
|
652
666
|
Math.max(this.now(), lastScheduledAtMs) + leasedBlockTtlMs(rules);
|
|
653
|
-
const existing = this.blocks.get(
|
|
667
|
+
const existing = this.blocks.get(laneKey);
|
|
654
668
|
if (
|
|
655
669
|
existing &&
|
|
656
670
|
existing.rulesKey === rulesKey &&
|
|
@@ -668,7 +682,7 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
668
682
|
existing.rules,
|
|
669
683
|
existing.permits.flatMap(([, leaseId]) => (leaseId ? [leaseId] : [])),
|
|
670
684
|
);
|
|
671
|
-
this.blocks.set(
|
|
685
|
+
this.blocks.set(laneKey, {
|
|
672
686
|
permits,
|
|
673
687
|
rateScopeToken,
|
|
674
688
|
expiresAt: freshExpiresAt,
|
|
@@ -679,12 +693,12 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
679
693
|
|
|
680
694
|
private drawFromBlock(
|
|
681
695
|
bucketId: string,
|
|
682
|
-
|
|
696
|
+
laneKey: string,
|
|
683
697
|
): { permit: PacingPermit; scheduledAtMs: number } | null {
|
|
684
|
-
const block = this.blocks.get(
|
|
698
|
+
const block = this.blocks.get(laneKey);
|
|
685
699
|
if (!block) return null;
|
|
686
|
-
if (block.
|
|
687
|
-
this.blocks.delete(
|
|
700
|
+
if (block.expiresAt <= this.now()) {
|
|
701
|
+
this.blocks.delete(laneKey);
|
|
688
702
|
// Unused window permits are forfeited on TTL expiry (the server already
|
|
689
703
|
// decremented the provider window for them, and the rule-scoped TTL is
|
|
690
704
|
// capped so at most one block's worth is stranded per bucket/window).
|
|
@@ -699,10 +713,10 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
699
713
|
}
|
|
700
714
|
const scheduled = block.permits.shift();
|
|
701
715
|
if (!scheduled) {
|
|
702
|
-
this.blocks.delete(
|
|
716
|
+
this.blocks.delete(laneKey);
|
|
703
717
|
return null;
|
|
704
718
|
}
|
|
705
|
-
if (block.permits.length === 0) this.blocks.delete(
|
|
719
|
+
if (block.permits.length === 0) this.blocks.delete(laneKey);
|
|
706
720
|
return {
|
|
707
721
|
permit: this.permitFor(
|
|
708
722
|
bucketId,
|
|
@@ -714,16 +728,18 @@ export class AppRuntimeRateStateBackend implements RateStateBackend {
|
|
|
714
728
|
};
|
|
715
729
|
}
|
|
716
730
|
|
|
717
|
-
private
|
|
718
|
-
const
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
731
|
+
private drainBlocksForBucket(bucketId: string): void {
|
|
732
|
+
const prefix = `${bucketId}\0`;
|
|
733
|
+
for (const [laneKey, block] of this.blocks) {
|
|
734
|
+
if (!laneKey.startsWith(prefix)) continue;
|
|
735
|
+
this.blocks.delete(laneKey);
|
|
736
|
+
this.releaseReserved(
|
|
737
|
+
bucketId,
|
|
738
|
+
block.rateScopeToken,
|
|
739
|
+
block.rules,
|
|
740
|
+
block.permits.flatMap(([, leaseId]) => (leaseId ? [leaseId] : [])),
|
|
741
|
+
);
|
|
742
|
+
}
|
|
727
743
|
}
|
|
728
744
|
|
|
729
745
|
private releaseReserved(
|
|
@@ -814,20 +830,22 @@ function isDefaultPacingRuleId(ruleId: string): boolean {
|
|
|
814
830
|
}
|
|
815
831
|
|
|
816
832
|
/**
|
|
817
|
-
*
|
|
818
|
-
*
|
|
819
|
-
*
|
|
820
|
-
* `normalizeRules` reads it, everyone else ignores it.
|
|
833
|
+
* Preserve explicit advisory ceilings and stamp the legacy base * 25 ceiling
|
|
834
|
+
* only onto undeclared default-pacing rules. Declared rules without a ceiling
|
|
835
|
+
* remain pinned at base.
|
|
821
836
|
*/
|
|
822
837
|
function withAdaptiveMaxRps(rules: readonly PacingRule[]): PacingRule[] {
|
|
823
838
|
return rules.map((rule) =>
|
|
824
|
-
|
|
825
|
-
?
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
rule
|
|
829
|
-
|
|
830
|
-
|
|
839
|
+
rule.adaptiveMaxRps != null
|
|
840
|
+
? rule
|
|
841
|
+
: isDefaultPacingRuleId(rule.ruleId)
|
|
842
|
+
? ({
|
|
843
|
+
...rule,
|
|
844
|
+
adaptiveMaxRps:
|
|
845
|
+
rule.requestsPerWindow *
|
|
846
|
+
DEFAULT_PACING_ADAPTIVE_MAX_RPS_MULTIPLIER,
|
|
847
|
+
} as PacingRule)
|
|
848
|
+
: rule,
|
|
831
849
|
);
|
|
832
850
|
}
|
|
833
851
|
|
|
@@ -835,12 +853,23 @@ function rulesSignature(rules: readonly PacingRule[]): string {
|
|
|
835
853
|
return [...rules]
|
|
836
854
|
.map(
|
|
837
855
|
(rule) =>
|
|
838
|
-
`${rule.ruleId}:${rule.requestsPerWindow}:${rule.windowMs}:${rule.maxConcurrency ?? ''}`,
|
|
856
|
+
`${rule.ruleId}:${rule.requestsPerWindow}:${rule.windowMs}:${rule.adaptiveMaxRps ?? ''}:${rule.maxConcurrency ?? ''}`,
|
|
839
857
|
)
|
|
840
858
|
.sort()
|
|
841
859
|
.join('|');
|
|
842
860
|
}
|
|
843
861
|
|
|
862
|
+
function rateLaneKey(bucketId: string, rulesKey: string): string {
|
|
863
|
+
return `${bucketId}\0${rulesKey}`;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
function pendingSuccessKey(
|
|
867
|
+
bucketId: string,
|
|
868
|
+
rules: readonly PacingRule[],
|
|
869
|
+
): string {
|
|
870
|
+
return rateLaneKey(bucketId, rulesSignature(rules));
|
|
871
|
+
}
|
|
872
|
+
|
|
844
873
|
function leasedBlockTtlMs(rules: readonly PacingRule[]): number {
|
|
845
874
|
const shortestWindowMs = Math.min(
|
|
846
875
|
...rules
|
|
@@ -267,6 +267,7 @@ export function createPlayExecutionGovernor(
|
|
|
267
267
|
});
|
|
268
268
|
const budgetState = input.budgetState ?? new InMemoryBudgetStateBackend();
|
|
269
269
|
const providerByTool = new Map<string, string>();
|
|
270
|
+
const pacingRulesByTool = new Map<string, PacingRule[]>();
|
|
270
271
|
const scopeByTool = new Map<string, [string, string]>();
|
|
271
272
|
const providerConcurrencySlotsByTool = new Map<string, Semaphore>();
|
|
272
273
|
|
|
@@ -308,6 +309,7 @@ export function createPlayExecutionGovernor(
|
|
|
308
309
|
// row is authoritative.
|
|
309
310
|
const pacing = declaredPacing ?? defaultPacingForTool(toolId, policy);
|
|
310
311
|
providerByTool.set(toolId, pacing.provider);
|
|
312
|
+
pacingRulesByTool.set(toolId, pacing.rules);
|
|
311
313
|
return pacing;
|
|
312
314
|
}
|
|
313
315
|
const pacing = adaptiveAdmission.resolvePacing({
|
|
@@ -317,6 +319,7 @@ export function createPlayExecutionGovernor(
|
|
|
317
319
|
fallbackPacing: defaultPacingForTool(toolId, policy),
|
|
318
320
|
});
|
|
319
321
|
providerByTool.set(toolId, pacing.provider);
|
|
322
|
+
pacingRulesByTool.set(toolId, pacing.rules);
|
|
320
323
|
return pacing;
|
|
321
324
|
}
|
|
322
325
|
|
|
@@ -486,9 +489,13 @@ export function createPlayExecutionGovernor(
|
|
|
486
489
|
|
|
487
490
|
observeProviderSuccess(success) {
|
|
488
491
|
if (dbAuthoritativePacing) {
|
|
492
|
+
if (!success.toolId) return;
|
|
489
493
|
const rateScope = scopeFor(success.toolId, success.provider);
|
|
494
|
+
const rules = pacingRulesByTool.get(success.toolId);
|
|
495
|
+
if (!rules) return;
|
|
490
496
|
input.rateState.observeSuccess?.({
|
|
491
497
|
bucketId: rateScope[0],
|
|
498
|
+
rules,
|
|
492
499
|
});
|
|
493
500
|
return;
|
|
494
501
|
}
|
|
@@ -11,6 +11,8 @@ export interface PacingRule {
|
|
|
11
11
|
readonly ruleId: string;
|
|
12
12
|
readonly requestsPerWindow: number;
|
|
13
13
|
readonly windowMs: number;
|
|
14
|
+
/** Optional learned-rate ceiling in requests per second. */
|
|
15
|
+
readonly adaptiveMaxRps?: number | null;
|
|
14
16
|
/**
|
|
15
17
|
* Optional simultaneous-in-flight cap for this rule.
|
|
16
18
|
*
|
|
@@ -35,6 +37,7 @@ export interface PlayQueueHint {
|
|
|
35
37
|
ruleId: string;
|
|
36
38
|
requestsPerWindow: number;
|
|
37
39
|
windowMs: number;
|
|
40
|
+
adaptiveMaxRps?: number | null;
|
|
38
41
|
maxConcurrency: number | null;
|
|
39
42
|
}
|
|
40
43
|
|
|
@@ -88,6 +91,7 @@ export interface RateStateBackend {
|
|
|
88
91
|
observeSuccess?(input: {
|
|
89
92
|
bucketId: string;
|
|
90
93
|
rateScopeToken?: string | null;
|
|
94
|
+
rules: readonly PacingRule[];
|
|
91
95
|
}): void;
|
|
92
96
|
}
|
|
93
97
|
|
|
@@ -8,7 +8,12 @@ export type ResolvedPacingPolicy = {
|
|
|
8
8
|
|
|
9
9
|
type PacingPolicyQueueHint = Pick<
|
|
10
10
|
PlayQueueHint,
|
|
11
|
-
|
|
11
|
+
| 'provider'
|
|
12
|
+
| 'ruleId'
|
|
13
|
+
| 'requestsPerWindow'
|
|
14
|
+
| 'windowMs'
|
|
15
|
+
| 'adaptiveMaxRps'
|
|
16
|
+
| 'maxConcurrency'
|
|
12
17
|
>;
|
|
13
18
|
|
|
14
19
|
function isFinitePositiveNumber(value: unknown): value is number {
|
|
@@ -35,6 +40,9 @@ export function pacingPolicyFromQueueHints(
|
|
|
35
40
|
ruleId: hint.ruleId,
|
|
36
41
|
requestsPerWindow: hint.requestsPerWindow,
|
|
37
42
|
windowMs: hint.windowMs,
|
|
43
|
+
adaptiveMaxRps: isFinitePositiveNumber(hint.adaptiveMaxRps)
|
|
44
|
+
? hint.adaptiveMaxRps
|
|
45
|
+
: null,
|
|
38
46
|
maxConcurrency:
|
|
39
47
|
typeof hint.maxConcurrency === 'number' &&
|
|
40
48
|
Number.isFinite(hint.maxConcurrency) &&
|
|
@@ -65,6 +73,8 @@ export function pacingPolicyFromUnknownQueueHints(
|
|
|
65
73
|
: Number.NaN,
|
|
66
74
|
windowMs:
|
|
67
75
|
typeof hint.windowMs === 'number' ? hint.windowMs : Number.NaN,
|
|
76
|
+
adaptiveMaxRps:
|
|
77
|
+
typeof hint.adaptiveMaxRps === 'number' ? hint.adaptiveMaxRps : null,
|
|
68
78
|
maxConcurrency:
|
|
69
79
|
typeof hint.maxConcurrency === 'number' ? hint.maxConcurrency : null,
|
|
70
80
|
})),
|
package/dist/cli/index.js
CHANGED
|
@@ -718,7 +718,7 @@ var SDK_RELEASE = {
|
|
|
718
718
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
719
719
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
720
720
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
721
|
-
version: "0.1.
|
|
721
|
+
version: "0.1.295",
|
|
722
722
|
contracts: {
|
|
723
723
|
api: {
|
|
724
724
|
name: "sdk-http-api",
|
package/dist/cli/index.mjs
CHANGED
|
@@ -703,7 +703,7 @@ var SDK_RELEASE = {
|
|
|
703
703
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
704
704
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
705
705
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
706
|
-
version: "0.1.
|
|
706
|
+
version: "0.1.295",
|
|
707
707
|
contracts: {
|
|
708
708
|
api: {
|
|
709
709
|
name: "sdk-http-api",
|
package/dist/index.js
CHANGED
|
@@ -438,7 +438,7 @@ var SDK_RELEASE = {
|
|
|
438
438
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
439
439
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
440
440
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
441
|
-
version: "0.1.
|
|
441
|
+
version: "0.1.295",
|
|
442
442
|
contracts: {
|
|
443
443
|
api: {
|
|
444
444
|
name: "sdk-http-api",
|
package/dist/index.mjs
CHANGED
|
@@ -367,7 +367,7 @@ var SDK_RELEASE = {
|
|
|
367
367
|
// 0.1.253 makes play-page browser opening opt-in and retires --no-open.
|
|
368
368
|
// 0.1.254 removes the internal operations tree from the published SDK CLI.
|
|
369
369
|
// Operators use the checkout-local deepline-admin binary instead.
|
|
370
|
-
version: "0.1.
|
|
370
|
+
version: "0.1.295",
|
|
371
371
|
contracts: {
|
|
372
372
|
api: {
|
|
373
373
|
name: "sdk-http-api",
|