























1+import { resolveIntegerOption } from "openclaw/plugin-sdk/number-runtime";
12import { RateLimitError, readRetryAfter } from "./rest-errors.js";
23import { createBucketKey, createRouteKey, readHeaderNumber, readResetAt } from "./rest-routes.js";
34@@ -47,6 +48,29 @@ export type RestSchedulerOptions = {
4748const INVALID_REQUEST_WINDOW_MS = 10 * 60_000;
4849const requestPriorities = ["critical", "standard", "background"] as const;
495051+function normalizeRestSchedulerOptions(options: RestSchedulerOptions): RestSchedulerOptions {
52+return {
53+lanes: {
54+critical: normalizeLaneOptions(options.lanes.critical),
55+standard: normalizeLaneOptions(options.lanes.standard),
56+background: normalizeLaneOptions(options.lanes.background),
57+},
58+maxConcurrency: resolveIntegerOption(options.maxConcurrency, 1, { min: 1 }),
59+maxQueueSize: resolveIntegerOption(options.maxQueueSize, 1, { min: 1 }),
60+maxRateLimitRetries: resolveIntegerOption(options.maxRateLimitRetries, 0, { min: 0 }),
61+};
62+}
63+64+function normalizeLaneOptions(options: RestSchedulerLaneOptions): RestSchedulerLaneOptions {
65+return {
66+maxQueueSize: resolveIntegerOption(options.maxQueueSize, 1, { min: 1 }),
67+ ...(options.staleAfterMs === undefined
68+ ? {}
69+ : { staleAfterMs: resolveIntegerOption(options.staleAfterMs, 0, { min: 0 }) }),
70+weight: resolveIntegerOption(options.weight, 1, { min: 1 }),
71+};
72+}
73+5074function createLaneQueues<TData>(): LaneQueues<TData> {
5175return {
5276critical: [],
@@ -60,6 +84,7 @@ function countPending<TData>(bucket: BucketState<TData>): number {
6084}
61856286export class RestScheduler<TData> {
87+private readonly options: RestSchedulerOptions;
6388private activeWorkers = 0;
6489private buckets = new Map<string, BucketState<TData>>();
6590private drainTimer: NodeJS.Timeout | undefined;
@@ -82,10 +107,11 @@ export class RestScheduler<TData> {
82107private routeBuckets = new Map<string, string>();
8310884109constructor(
85-private readonly options: RestSchedulerOptions,
110+options: RestSchedulerOptions,
86111private readonly executor: (request: ScheduledRequest<TData>) => Promise<unknown>,
87112) {
88-this.laneSchedule = this.buildLaneSchedule(options.lanes);
113+this.options = normalizeRestSchedulerOptions(options);
114+this.laneSchedule = this.buildLaneSchedule(this.options.lanes);
89115}
9011691117enqueue(params: {
@@ -186,11 +212,11 @@ export class RestScheduler<TData> {
186212}
187213188214private get maxConcurrentWorkers(): number {
189-return Math.max(1, Math.floor(this.options.maxConcurrency));
215+return this.options.maxConcurrency;
190216}
191217192218private get maxRateLimitRetries(): number {
193-return Math.max(0, Math.floor(this.options.maxRateLimitRetries));
219+return this.options.maxRateLimitRetries;
194220}
195221196222private getBucket(key: string): BucketState<TData> {
@@ -528,7 +554,7 @@ export class RestScheduler<TData> {
528554private buildLaneSchedule(lanes: Record<RequestPriority, RestSchedulerLaneOptions>) {
529555const schedule: RequestPriority[] = [];
530556for (const lane of requestPriorities) {
531-const weight = Math.max(1, Math.floor(lanes[lane].weight));
557+const weight = lanes[lane].weight;
532558for (let i = 0; i < weight; i += 1) {
533559schedule.push(lane);
534560}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。