-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add "timeoutPerCommand" option to detect dead connection #658
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,25 @@ exports.connectHandler = function (self) { | |
|
||
self.initParser(); | ||
|
||
self.lastWriteTime = null; | ||
if (typeof self.options.timeoutPerCommand === 'number') { | ||
var timeoutPerCommand = self.options.timeoutPerCommand; | ||
debug('Per-command timeout set to %s', self.options.timeoutPerCommand); | ||
self.timeoutPerCommand = setInterval(() => { | ||
var commandQueueLength = self.commandQueue.length; | ||
if ( | ||
commandQueueLength > 0 && | ||
Date.now() - self.lastWriteTime > self.options.timeoutPerCommand | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since Perhaps in |
||
) { | ||
debug('Command timed out. Pending commands: %s', commandQueueLength); | ||
var err = new Error('Command timed out'); | ||
self.flushQueue(err, { offlineQueue: false }); | ||
self.silentEmit('error', err); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is emitting an
While I do also handle the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the callbacks will be called besides an |
||
self.disconnect(true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume that this will trigger an automatic reconnect to that server, correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's correct. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good, but see my follow-up to #587. If this node was part of a cluster, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per #587, there will not be any automatic reconnect in a cluster environment. |
||
} | ||
}, 500); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It appears that the minimum practical value for |
||
} | ||
|
||
if (self.options.enableReadyCheck) { | ||
self._readyCheck(function (err, info) { | ||
if (err) { | ||
|
@@ -71,6 +90,11 @@ exports.closeHandler = function (self) { | |
self.prevCommandQueue = self.commandQueue; | ||
} | ||
|
||
if (self.timeoutPerCommand) { | ||
clearInterval(self.timeoutPerCommand); | ||
self.timeoutPerCommand = null; | ||
} | ||
|
||
if (self.manuallyClosing) { | ||
self.manuallyClosing = false; | ||
debug('skip reconnecting since the connection is manually closed.'); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about using this: https://nodejs.org/api/net.html#net_socket_settimeout_timeout_callback to generate a timeout event from the socket if it becomes inactive while the queue is being processed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This timeout guards against a socket which has no activity. The value to use probably greatly depends on the use cases. In a production environment, there's probably enough traffic to keep such a timeout from triggering. But in a dev environment, there might not be any traffic for relatively long stretches of time making this an idle connection which then times out. Setting a per command timeout seems better.
Also, if this socket timeout occurs, it doesn't enable specific error handling / recovery for the specific commands which timed out.
Or were you suggesting this as an additional check and not an alternative solution?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am suggesting to set this to something reasonable while we are processing commands and to disable it while the socket is not used.
It just seems that it can be easier to implement than setting and cancelling timeouts in the lib. And more powerful as well.