Split linkDown() into canCarry() and droppedWhileDraining()
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 34s
Test / test (24) (pull_request) Successful in 40s
Test / test (26) (pull_request) Successful in 33s
Mirror / push (push) Waiting to run

This commit is contained in:
2026-09-28 01:31:39 +02:00
parent 1371137fef
commit 8d443bf670
4 changed files with 16 additions and 16 deletions
+10 -5
View File
@@ -51,9 +51,14 @@ export class OutgoingRequests {
this.window = new SendWindow({ limit: options.maxOutstanding, log: options.log });
}
/** Read through a method: a drop can land while a request is awaiting. */
linkDown(): boolean {
return !this.gate.isUp() || this.transport.sock.destroyed;
/** Whether a request made now reaches the socket. Read through a method: a drop can land while one awaits. */
canCarry(): boolean {
return this.gate.isUp() && !this.transport.sock.destroyed;
}
/** The link went while draining, so the teardown settled what the drain waited on, not the peer. */
droppedWhileDraining(): boolean {
return this.draining && !this.canCarry();
}
/** A link is up and bound, so everything held for one goes out on it. */
@@ -84,8 +89,8 @@ export class OutgoingRequests {
if (wrong) return Promise.resolve({ err: wrong });
// A drain on a live link. A link that is down is the gate's answer, which says closed instead.
if (this.draining && !this.linkDown()) {
// With no link, the gate answers instead, and says closed.
if (this.draining && this.canCarry()) {
return Promise.resolve({ err: new Error('Session is shutting down') });
}
+3 -3
View File
@@ -333,7 +333,8 @@ export class Session extends EventEmitter<SessionEvents> {
this.reconnectLoop?.stop();
this.outgoing.stopAccepting();
if (this.outgoing.linkDown()) return {};
// No link, so nothing is on the wire to wait out.
if (!this.outgoing.canCarry()) return {};
const timeout = this.options.shutdownTimeout ?? defaults.shutdownTimeout;
const deadline = timeout > 0 ? Date.now() + timeout : 0;
@@ -341,8 +342,7 @@ export class Session extends EventEmitter<SessionEvents> {
const messages = await this.incoming.drain(this.answering(timeout), signal);
const requests = await this.outgoing.drain(leftOf(deadline), signal);
// The window empties on a teardown too, which settles everything the link was carrying.
if (this.outgoing.linkDown()) {
if (this.outgoing.droppedWhileDraining()) {
return { err: new Error('The session closed before the drain finished') };
}