


















@@ -89,6 +89,7 @@ export class RestScheduler<TData> {
8989return {
9090globalRateLimitUntil: this.globalRateLimitUntil,
9191activeBuckets: this.buckets.size,
92+routeBucketMappings: this.routeBuckets.size,
9293buckets: Array.from(this.buckets.entries()).map(([key, bucket]) => ({
9394 key,
9495active: bucket.active,
@@ -144,6 +145,34 @@ export class RestScheduler<TData> {
144145return false;
145146}
146147148+private isBucketRateLimited(bucket: BucketState<TData>, now = Date.now()): boolean {
149+return bucket.remaining === 0 && bucket.resetAt > now;
150+}
151+152+private pruneRouteMapping(routeKey: string): void {
153+const bucketKey = this.routeBuckets.get(routeKey);
154+if (!bucketKey) {
155+return;
156+}
157+this.routeBuckets.delete(routeKey);
158+this.buckets.get(bucketKey)?.routeKeys.delete(routeKey);
159+}
160+161+private pruneIdleRouteMappings(
162+bucketKey: string,
163+bucket: BucketState<TData>,
164+now = Date.now(),
165+): void {
166+if (bucket.active > 0 || bucket.pending.length > 0 || this.isBucketRateLimited(bucket, now)) {
167+return;
168+}
169+for (const routeKey of Array.from(bucket.routeKeys)) {
170+if (this.routeBuckets.get(routeKey) === bucketKey) {
171+this.pruneRouteMapping(routeKey);
172+}
173+}
174+}
175+147176private shouldPruneIdleBucket(key: string): boolean {
148177const mappedBucketKey = this.routeBuckets.get(key);
149178return mappedBucketKey !== key && !this.hasBucketReference(key);
@@ -267,7 +296,15 @@ export class RestScheduler<TData> {
267296break;
268297}
269298if (bucket.pending.length === 0) {
270-if (bucket.active === 0 && this.shouldPruneIdleBucket(key)) {
299+if (bucket.active !== 0) {
300+continue;
301+}
302+if (this.isBucketRateLimited(bucket, now)) {
303+nextDelayMs = Math.min(nextDelayMs, bucket.resetAt - now);
304+continue;
305+}
306+this.pruneIdleRouteMappings(key, bucket, now);
307+if (this.shouldPruneIdleBucket(key)) {
271308this.buckets.delete(key);
272309}
273310continue;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。