Skip to content

Commit

Permalink
Merge pull request #537 from shanedewael/fix-statemachine-websocket-c…
Browse files Browse the repository at this point in the history
…lose

Fix and Add Logging for StateMachine websocket close
  • Loading branch information
Shane DeWael committed Apr 19, 2018
2 parents 017ef50 + 2c21341 commit 7cef7ec
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
18 changes: 15 additions & 3 deletions src/KeepAlive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ export class KeepAlive extends EventEmitter {
*/
private logger: Logger;

/**
* Flag that indicates whether this object is still monitoring.
*/
public isMonitoring?: Boolean;

/**
* Flag that indicates whether recommend_reconnect event has been emitted and stop() has not been called.
*/
public recommendReconnect?: Boolean;

constructor({
clientPingTimeout = 6000,
serverPongTimeout = 4000,
Expand Down Expand Up @@ -97,6 +107,7 @@ export class KeepAlive extends EventEmitter {
}

this.client = client;
this.isMonitoring = true;
this.client.on('outgoing_message', this.setPingTimer, this);
this.setPingTimer();
}
Expand All @@ -109,6 +120,7 @@ export class KeepAlive extends EventEmitter {
public stop(): void {
this.clearPreviousPingTimer();
this.lastPing = this.client = undefined;
this.recommendReconnect = this.isMonitoring = false;
}

/**
Expand Down Expand Up @@ -174,13 +186,13 @@ export class KeepAlive extends EventEmitter {
if (this.client === undefined) {
throw errorWithCode(new Error('no client found'), ErrorCode.KeepAliveInconsistentState);
}
// signal that this pong is done being handled
this.client.off('slack_event', attemptAcknowledgePong);

// no pong received to acknowledge the last ping within the serverPongTimeout
this.logger.debug('pong timer expired, recommend reconnect');
this.recommendReconnect = true;
this.emit('recommend_reconnect');

// signal that this pong is done being handled
this.client.off('slack_event', attemptAcknowledgePong);
}, this.serverPongTimeout);

this.client.on('slack_event', attemptAcknowledgePong, this);
Expand Down
16 changes: 16 additions & 0 deletions src/RTMClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,22 @@ export class RTMClient extends EventEmitter {
})
.on('websocket open').transitionTo('handshaking')
.state('handshaking') // a state in which to wait until the 'server hello' event
.on('websocket close')
.transitionTo('reconnecting').withCondition(() => this.autoReconnect)
.withAction((_from, _to, context) => {
this.logger.debug(`reconnecting after unexpected close ${context.eventPayload.reason}
${context.eventPayload.code} with isMonitoring set to ${this.keepAlive.isMonitoring}
and recommendReconnect set to ${this.keepAlive.recommendReconnect}`);
})
.transitionTo('disconnected')
.withAction((_from, _to, context) => {
this.logger.debug(`disconnected after unexpected close ${context.eventPayload.reason}
${context.eventPayload.code} with isMonitoring set to ${this.keepAlive.isMonitoring}
and recommendReconnect set to ${this.keepAlive.recommendReconnect}`);
// this transition circumvents the 'disconnecting' state (since the websocket is already closed),
// so we need to execute its onExit behavior here.
this.teardownWebsocket();
})
.global()
.onStateEnter((state) => {
this.logger.debug(`transitioning to state: connecting:${state}`);
Expand Down

0 comments on commit 7cef7ec

Please sign in to comment.