Skip to content

Commit

Permalink
lib: use Timer.now() in readline module
Browse files Browse the repository at this point in the history
Using Date.now() introduces problems when operating under load or
otherwise with constrained resources. Use Timer.now() to mitigate.

The problem was identified in `test-readline-interface` where under
heavy load, `\r` and `\n` were received so far apart that they were
treated as separate line endings rather than a single line ending.
Switching to `Timer.now()` prevented this from happening.

PR-URL: nodejs#14681
Refs: nodejs#14674
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
  • Loading branch information
Trott committed Aug 10, 2017
1 parent 02371c7 commit fe54bc7
Showing 1 changed file with 6 additions and 4 deletions.
10 changes: 6 additions & 4 deletions lib/readline.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ const {
kClearScreenDown
} = CSI;

const now = process.binding('timer_wrap').Timer.now;

const kHistorySize = 30;
const kMincrlfDelay = 100;
// \r\n, \n, or \r followed by something other than \n
Expand Down Expand Up @@ -409,7 +411,7 @@ Interface.prototype._normalWrite = function(b) {
}
var string = this._decoder.write(b);
if (this._sawReturnAt &&
Date.now() - this._sawReturnAt <= this.crlfDelay) {
now() - this._sawReturnAt <= this.crlfDelay) {
string = string.replace(/^\n/, '');
this._sawReturnAt = 0;
}
Expand All @@ -422,7 +424,7 @@ Interface.prototype._normalWrite = function(b) {
this._line_buffer = null;
}
if (newPartContainsEnding) {
this._sawReturnAt = string.endsWith('\r') ? Date.now() : 0;
this._sawReturnAt = string.endsWith('\r') ? now() : 0;

// got one or more newlines; process into "line" events
var lines = string.split(lineEnding);
Expand Down Expand Up @@ -916,14 +918,14 @@ Interface.prototype._ttyWrite = function(s, key) {

switch (key.name) {
case 'return': // carriage return, i.e. \r
this._sawReturnAt = Date.now();
this._sawReturnAt = now();
this._line();
break;

case 'enter':
// When key interval > crlfDelay
if (this._sawReturnAt === 0 ||
Date.now() - this._sawReturnAt > this.crlfDelay) {
now() - this._sawReturnAt > this.crlfDelay) {
this._line();
}
this._sawReturnAt = 0;
Expand Down

0 comments on commit fe54bc7

Please sign in to comment.