diff --git a/src/session.ts b/src/session.ts index 7e92bcc..614c0b5 100644 --- a/src/session.ts +++ b/src/session.ts @@ -72,8 +72,8 @@ export class Session extends EventEmitter { private readonly timers: LinkTimers; private readonly transport: PduTransport; - /** `torn-down` goes back to `attached` when the reconnect loop brings a link up. */ - private link: 'attached' | 'ended' | 'torn-down' = 'attached'; + /** `ended` is final: end() stops the reconnect loop before any attach() can run. */ + private lifecycle: 'attached' | 'ended' | 'torn-down' = 'attached'; /** A listener that throws is the application's bug; it must not become ours. Hard rule 1. */ override emit( @@ -186,7 +186,7 @@ export class Session extends EventEmitter { const sent = built.err ? { err: built.err } : this.transport.write(built.buffer); // A peer that unbinds and drops the link takes our response with it; that is not a failure. - if (sent.err && this.link === 'attached') { + if (sent.err && this.lifecycle === 'attached') { this.log.warn('session - could not answer a request', { cmdName, message: sent.err.message, @@ -221,12 +221,12 @@ export class Session extends EventEmitter { */ async unbind(): Promise { const drained = await this.drain(undefined); - const wasOpen = this.link === 'attached'; + const wasOpen = this.lifecycle === 'attached'; // now(), not send(): a drain refuses a send, and the unbind goes out either way. const sent = wasOpen ? await this.outgoing.now({ cmdName: 'unbind' }) : { err: new Error('Session is closed') }; - const closedOnUnbind = wasOpen && this.link !== 'attached'; + const closedOnUnbind = wasOpen && this.lifecycle !== 'attached'; this.end(); @@ -325,7 +325,7 @@ export class Session extends EventEmitter { private attach(sock: Socket): void { this.transport.attach(sock); - this.link = 'attached'; + this.lifecycle = 'attached'; } /** Stops new sends and waits out the messages we hold and the requests already issued. */ @@ -371,17 +371,17 @@ export class Session extends EventEmitter { } private emitClose(): void { - if (this.link === 'ended') return; + if (this.lifecycle === 'ended') return; - this.link = 'ended'; + this.lifecycle = 'ended'; this.outgoing.linkLost(false); this.emit('close'); } private teardown(): void { - if (this.link !== 'attached') return; + if (this.lifecycle !== 'attached') return; - this.link = 'torn-down'; + this.lifecycle = 'torn-down'; // Read once: clear() reports lost segments, and a listener could stop the loop between reads. const retrying = this.retrying(); @@ -445,7 +445,7 @@ export class Session extends EventEmitter { } private resetTimers(): void { - if (this.link !== 'attached') return; + if (this.lifecycle !== 'attached') return; this.timers.reset(); }