Say what ExpiringGroups leaves to its owners
Test / lint (pull_request) Successful in 23s
Test / test (18) (pull_request) Successful in 31s
Test / test (20) (pull_request) Successful in 31s
Test / test (22) (pull_request) Successful in 31s
Test / test (24) (pull_request) Successful in 30s
Test / test (26) (pull_request) Successful in 31s
Mirror / push (push) Successful in 5s
Test / lint (pull_request) Successful in 23s
Test / test (18) (pull_request) Successful in 31s
Test / test (20) (pull_request) Successful in 31s
Test / test (22) (pull_request) Successful in 31s
Test / test (24) (pull_request) Successful in 30s
Test / test (26) (pull_request) Successful in 31s
Mirror / push (push) Successful in 5s
This commit was merged in pull request #36.
This commit is contained in:
+5
-11
@@ -1,10 +1,10 @@
|
|||||||
export type ExpiringGroupsOptions = {
|
export type ExpiringGroupsOptions = {
|
||||||
max: number;
|
max: number;
|
||||||
/** What the groups may weigh together before weigh() evicts the oldest. */
|
/** Enforced by weigh() alone; set() never evicts. */
|
||||||
maxWeight?: number | undefined;
|
maxWeight?: number | undefined;
|
||||||
/** Injected so expiry can be exercised without a wall clock. */
|
/** Injected so expiry can be exercised without a wall clock. */
|
||||||
now?: (() => number) | undefined;
|
now?: (() => number) | undefined;
|
||||||
/** Runs on the sweeper's own timer; the owner reports whatever it takes out. */
|
/** Must call takeExpired(): the timer itself removes nothing. */
|
||||||
onSweep: () => void;
|
onSweep: () => void;
|
||||||
timeout: number;
|
timeout: number;
|
||||||
};
|
};
|
||||||
@@ -15,10 +15,7 @@ type Entry<T> = {
|
|||||||
weight: number;
|
weight: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/** Enforces neither max nor timeout itself: owners check full and call takeExpired(); only weigh() evicts. */
|
||||||
* A capped store of groups that expire. Nothing is dropped silently: the owner takes the expired
|
|
||||||
* and the evicted out itself, so the accounting and the log line stay where the group is understood.
|
|
||||||
*/
|
|
||||||
export class ExpiringGroups<T> {
|
export class ExpiringGroups<T> {
|
||||||
private readonly entries = new Map<string, Entry<T>>();
|
private readonly entries = new Map<string, Entry<T>>();
|
||||||
private readonly max: number;
|
private readonly max: number;
|
||||||
@@ -53,7 +50,7 @@ export class ExpiringGroups<T> {
|
|||||||
return this.entries.get(key)?.group;
|
return this.entries.get(key)?.group;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Starts the group's deadline, and the sweeper if this is the only group held. */
|
/** Replacing a key restarts its deadline and zeroes its weight; weigh() it again. */
|
||||||
set(key: string, group: T): void {
|
set(key: string, group: T): void {
|
||||||
this.remove(key);
|
this.remove(key);
|
||||||
this.entries.set(key, { deadline: this.now() + this.timeout, group, weight: 0 });
|
this.entries.set(key, { deadline: this.now() + this.timeout, group, weight: 0 });
|
||||||
@@ -69,7 +66,7 @@ export class ExpiringGroups<T> {
|
|||||||
this.idle();
|
this.idle();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Records what a group weighs now, and hands over the oldest groups evicted to bring the total under maxWeight. */
|
/** The returned groups are already removed, and may include key itself. */
|
||||||
weigh(key: string, weight: number): [string, T][] {
|
weigh(key: string, weight: number): [string, T][] {
|
||||||
const entry = this.entries.get(key);
|
const entry = this.entries.get(key);
|
||||||
const taken: [string, T][] = [];
|
const taken: [string, T][] = [];
|
||||||
@@ -90,7 +87,6 @@ export class ExpiringGroups<T> {
|
|||||||
return taken;
|
return taken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes every group and hands them over, so an owner that must account for them can. */
|
|
||||||
takeAll(): [string, T][] {
|
takeAll(): [string, T][] {
|
||||||
const taken: [string, T][] = [];
|
const taken: [string, T][] = [];
|
||||||
|
|
||||||
@@ -105,7 +101,6 @@ export class ExpiringGroups<T> {
|
|||||||
return taken;
|
return taken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes every group past its deadline and hands them over. */
|
|
||||||
takeExpired(): [string, T][] {
|
takeExpired(): [string, T][] {
|
||||||
const now = this.now();
|
const now = this.now();
|
||||||
const taken: [string, T][] = [];
|
const taken: [string, T][] = [];
|
||||||
@@ -122,7 +117,6 @@ export class ExpiringGroups<T> {
|
|||||||
return taken;
|
return taken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes the group held longest and hands it over. Undefined means there was none. */
|
|
||||||
takeOldest(): [string, T] | undefined {
|
takeOldest(): [string, T] | undefined {
|
||||||
const oldest = this.entries.entries().next();
|
const oldest = this.entries.entries().next();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user