Fold the session's closed and ended flags into one lifecycle state #41
+11
-11
@@ -72,8 +72,8 @@ export class Session extends EventEmitter<SessionEvents> {
|
|||||||
private readonly timers: LinkTimers;
|
private readonly timers: LinkTimers;
|
||||||
private readonly transport: PduTransport;
|
private readonly transport: PduTransport;
|
||||||
|
|
||||||
/** `torn-down` goes back to `attached` when the reconnect loop brings a link up. */
|
/** `ended` is final: end() stops the reconnect loop before any attach() can run. */
|
||||||
private link: 'attached' | 'ended' | 'torn-down' = 'attached';
|
private lifecycle: 'attached' | 'ended' | 'torn-down' = 'attached';
|
||||||
|
|
||||||
/** A listener that throws is the application's bug; it must not become ours. Hard rule 1. */
|
/** A listener that throws is the application's bug; it must not become ours. Hard rule 1. */
|
||||||
override emit<K extends keyof SessionEvents>(
|
override emit<K extends keyof SessionEvents>(
|
||||||
@@ -186,7 +186,7 @@ export class Session extends EventEmitter<SessionEvents> {
|
|||||||
const sent = built.err ? { err: built.err } : this.transport.write(built.buffer);
|
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.
|
// 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', {
|
this.log.warn('session - could not answer a request', {
|
||||||
cmdName,
|
cmdName,
|
||||||
message: sent.err.message,
|
message: sent.err.message,
|
||||||
@@ -221,12 +221,12 @@ export class Session extends EventEmitter<SessionEvents> {
|
|||||||
*/
|
*/
|
||||||
async unbind(): Promise<VoidResult> {
|
async unbind(): Promise<VoidResult> {
|
||||||
const drained = await this.drain(undefined);
|
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.
|
// now(), not send(): a drain refuses a send, and the unbind goes out either way.
|
||||||
const sent = wasOpen
|
const sent = wasOpen
|
||||||
? await this.outgoing.now({ cmdName: 'unbind' })
|
? await this.outgoing.now({ cmdName: 'unbind' })
|
||||||
: { err: new Error('Session is closed') };
|
: { err: new Error('Session is closed') };
|
||||||
const closedOnUnbind = wasOpen && this.link !== 'attached';
|
const closedOnUnbind = wasOpen && this.lifecycle !== 'attached';
|
||||||
|
|
||||||
this.end();
|
this.end();
|
||||||
|
|
||||||
@@ -325,7 +325,7 @@ export class Session extends EventEmitter<SessionEvents> {
|
|||||||
|
|
||||||
private attach(sock: Socket): void {
|
private attach(sock: Socket): void {
|
||||||
this.transport.attach(sock);
|
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. */
|
/** Stops new sends and waits out the messages we hold and the requests already issued. */
|
||||||
@@ -371,17 +371,17 @@ export class Session extends EventEmitter<SessionEvents> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private emitClose(): void {
|
private emitClose(): void {
|
||||||
if (this.link === 'ended') return;
|
if (this.lifecycle === 'ended') return;
|
||||||
|
|
||||||
this.link = 'ended';
|
this.lifecycle = 'ended';
|
||||||
this.outgoing.linkLost(false);
|
this.outgoing.linkLost(false);
|
||||||
this.emit('close');
|
this.emit('close');
|
||||||
}
|
}
|
||||||
|
|
||||||
private teardown(): void {
|
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.
|
// Read once: clear() reports lost segments, and a listener could stop the loop between reads.
|
||||||
const retrying = this.retrying();
|
const retrying = this.retrying();
|
||||||
@@ -445,7 +445,7 @@ export class Session extends EventEmitter<SessionEvents> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private resetTimers(): void {
|
private resetTimers(): void {
|
||||||
if (this.link !== 'attached') return;
|
if (this.lifecycle !== 'attached') return;
|
||||||
|
|
||||||
this.timers.reset();
|
this.timers.reset();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user