Give the held-message flow one place a reader can follow it
Mirror / push (push) Successful in 6s
Test / lint (pull_request) Successful in 24s
Test / test (18) (pull_request) Successful in 32s
Test / test (20) (pull_request) Successful in 31s
Test / test (24) (pull_request) Successful in 32s
Test / test (22) (pull_request) Successful in 32s
Test / test (26) (pull_request) Successful in 31s
Mirror / push (push) Successful in 6s
Test / lint (pull_request) Successful in 24s
Test / test (18) (pull_request) Successful in 32s
Test / test (20) (pull_request) Successful in 31s
Test / test (24) (pull_request) Successful in 32s
Test / test (22) (pull_request) Successful in 32s
Test / test (26) (pull_request) Successful in 31s
This commit is contained in:
+28
-1
@@ -25,7 +25,10 @@ type HoldEntry = {
|
||||
release: () => void;
|
||||
};
|
||||
|
||||
/** One message offered to the application, held until it is answered or every listener gives up. */
|
||||
/**
|
||||
* One message offered to the application. A drain waits on it until the first of: `answered()`,
|
||||
* every listener that took it rejecting, no listener taking it, its deadline, or the link going.
|
||||
*/
|
||||
export class MessageHold {
|
||||
private readonly entry: HoldEntry;
|
||||
private working: number;
|
||||
@@ -64,6 +67,8 @@ export class HeldMessages {
|
||||
private readonly idleWaiters = new IdleWaiters();
|
||||
private readonly log: SmppLog;
|
||||
private readonly maxOctets: number;
|
||||
/** A rejecting listener hands the message back as an `unknown`, so its hold is found by identity. */
|
||||
private readonly offered = new WeakMap<object, MessageHold>();
|
||||
|
||||
constructor(options: HeldMessagesOptions) {
|
||||
this.held = new ExpiringGroups({
|
||||
@@ -112,6 +117,28 @@ export class HeldMessages {
|
||||
return hold;
|
||||
}
|
||||
|
||||
/** Holds a message, builds what the application is handed, and emits it. */
|
||||
offer<T extends object>(
|
||||
pduObjs: PduObject[],
|
||||
listeners: number,
|
||||
build: (hold: MessageHold) => T,
|
||||
emit: (message: T) => boolean,
|
||||
): void {
|
||||
const hold = this.hold(pduObjs, listeners);
|
||||
const message = build(hold);
|
||||
|
||||
this.offered.set(message, hold);
|
||||
|
||||
if (!emit(message)) hold.release();
|
||||
}
|
||||
|
||||
/** One listener gave up on a message; the last one to do so is what releases it. */
|
||||
listenerRejected(message: unknown): void {
|
||||
if (typeof message !== 'object' || message === null) return;
|
||||
|
||||
this.offered.get(message)?.listenerGaveUp();
|
||||
}
|
||||
|
||||
private has(pduObjs: PduObject[]): boolean {
|
||||
const key = keyOf(pduObjs);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user