Fix idle timeouts
Remove process.now because it doesn't provide enough precision.
This commit is contained in:
parent
3238944c7a
commit
8e9ec4abea
25
lib/net.js
25
lib/net.js
@ -2,8 +2,7 @@ var sys = require("sys");
|
|||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var events = require("events");
|
var events = require("events");
|
||||||
|
|
||||||
var debugLevel = 0;
|
var debugLevel = process.env['NODE_DEBUG'] ? 1 : 0;
|
||||||
if ('NODE_DEBUG' in process.ENV) debugLevel = 1;
|
|
||||||
function debug () {
|
function debug () {
|
||||||
if (debugLevel > 0) sys.error.apply(this, arguments);
|
if (debugLevel > 0) sys.error.apply(this, arguments);
|
||||||
}
|
}
|
||||||
@ -102,7 +101,7 @@ var timeout = new (function () {
|
|||||||
// the main function - creates lists on demand and the watchers associated
|
// the main function - creates lists on demand and the watchers associated
|
||||||
// with them.
|
// with them.
|
||||||
function insert (socket, msecs) {
|
function insert (socket, msecs) {
|
||||||
socket._idleStart = process.now;
|
socket._idleStart = new Date();
|
||||||
socket._idleTimeout = msecs;
|
socket._idleTimeout = msecs;
|
||||||
|
|
||||||
if (!msecs) return;
|
if (!msecs) return;
|
||||||
@ -122,13 +121,14 @@ var timeout = new (function () {
|
|||||||
debug('timeout callback ' + msecs);
|
debug('timeout callback ' + msecs);
|
||||||
// TODO - don't stop and start the watcher all the time.
|
// TODO - don't stop and start the watcher all the time.
|
||||||
// just set its repeat
|
// just set its repeat
|
||||||
var now = process.now;
|
var now = new Date();
|
||||||
|
debug("now: " + now);
|
||||||
var first;
|
var first;
|
||||||
while (first = peek(list)) {
|
while (first = peek(list)) {
|
||||||
var diff = now - first._idleStart;
|
var diff = now - first._idleStart;
|
||||||
if (diff < msecs) {
|
if (diff < msecs) {
|
||||||
list.again(msecs - diff);
|
list.again(msecs - diff);
|
||||||
debug(msecs + ' list wait');
|
debug(msecs + ' list wait because diff is ' + diff);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
remove(first);
|
remove(first);
|
||||||
@ -190,7 +190,7 @@ var timeout = new (function () {
|
|||||||
insert(socket, msecs);
|
insert(socket, msecs);
|
||||||
} else {
|
} else {
|
||||||
// inline append
|
// inline append
|
||||||
socket._idleStart = process.now;
|
socket._idleStart = new Date();
|
||||||
socket._idleNext._idlePrev = socket._idlePrev;
|
socket._idleNext._idlePrev = socket._idlePrev;
|
||||||
socket._idlePrev._idleNext = socket._idleNext;
|
socket._idlePrev._idleNext = socket._idleNext;
|
||||||
socket._idleNext = list._idleNext;
|
socket._idleNext = list._idleNext;
|
||||||
@ -280,7 +280,7 @@ function initStream (self) {
|
|||||||
allocNewPool();
|
allocNewPool();
|
||||||
}
|
}
|
||||||
|
|
||||||
//debug('pool.used ' + pool.used);
|
debug('pool.used ' + pool.used);
|
||||||
var bytesRead;
|
var bytesRead;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -293,7 +293,7 @@ function initStream (self) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//debug('bytesRead ' + bytesRead + '\n');
|
debug('bytesRead ' + bytesRead + '\n');
|
||||||
|
|
||||||
if (bytesRead == 0) {
|
if (bytesRead == 0) {
|
||||||
self.readable = false;
|
self.readable = false;
|
||||||
@ -449,12 +449,12 @@ Stream.prototype._writeString = function (data, encoding) {
|
|||||||
buffer.used += bytesWritten;
|
buffer.used += bytesWritten;
|
||||||
self._writeQueueSize += bytesWritten;
|
self._writeQueueSize += bytesWritten;
|
||||||
|
|
||||||
//debug('charsWritten ' + charsWritten);
|
debug('charsWritten ' + charsWritten);
|
||||||
//debug('buffer.used ' + buffer.used);
|
debug('buffer.used ' + buffer.used);
|
||||||
|
|
||||||
// If we didn't finish, then recurse with the rest of the string.
|
// If we didn't finish, then recurse with the rest of the string.
|
||||||
if (charsWritten < data.length) {
|
if (charsWritten < data.length) {
|
||||||
//debug('recursive write');
|
debug('recursive write');
|
||||||
self._writeString(data.slice(charsWritten), encoding);
|
self._writeString(data.slice(charsWritten), encoding);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -499,8 +499,6 @@ Stream.prototype.write = function (data, encoding) {
|
|||||||
encoding = (encoding || 'utf8').toLowerCase();
|
encoding = (encoding || 'utf8').toLowerCase();
|
||||||
var bytes = Buffer.byteLength(data, encoding);
|
var bytes = Buffer.byteLength(data, encoding);
|
||||||
|
|
||||||
//debug('write string :' + JSON.stringify(data));
|
|
||||||
|
|
||||||
if (!pool) allocNewPool();
|
if (!pool) allocNewPool();
|
||||||
|
|
||||||
if (pool.length - pool.used < bytes) {
|
if (pool.length - pool.used < bytes) {
|
||||||
@ -620,7 +618,6 @@ Stream.prototype.flush = function () {
|
|||||||
|
|
||||||
timeout.active(self);
|
timeout.active(self);
|
||||||
|
|
||||||
|
|
||||||
if (bytesWritten === null) {
|
if (bytesWritten === null) {
|
||||||
// EAGAIN
|
// EAGAIN
|
||||||
debug('write EAGAIN');
|
debug('write EAGAIN');
|
||||||
|
@ -539,13 +539,6 @@ static Handle<Value> SetUid(const Arguments& args) {
|
|||||||
return Undefined();
|
return Undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Value>
|
|
||||||
NowGetter (Local<String> property, const AccessorInfo& info)
|
|
||||||
{
|
|
||||||
HandleScope scope;
|
|
||||||
return scope.Close(Integer::New(ev_now(EV_DEFAULT_UC)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
v8::Handle<v8::Value> Exit(const v8::Arguments& args) {
|
v8::Handle<v8::Value> Exit(const v8::Arguments& args) {
|
||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
@ -1234,8 +1227,6 @@ static void Load(int argc, char *argv[]) {
|
|||||||
Local<FunctionTemplate> process_template = FunctionTemplate::New();
|
Local<FunctionTemplate> process_template = FunctionTemplate::New();
|
||||||
node::EventEmitter::Initialize(process_template);
|
node::EventEmitter::Initialize(process_template);
|
||||||
|
|
||||||
process_template->InstanceTemplate()->SetAccessor(String::NewSymbol("now"), NowGetter, NULL);
|
|
||||||
|
|
||||||
process = Persistent<Object>::New(process_template->GetFunction()->NewInstance());
|
process = Persistent<Object>::New(process_template->GetFunction()->NewInstance());
|
||||||
|
|
||||||
// Add a reference to the global object
|
// Add a reference to the global object
|
||||||
|
@ -12,7 +12,6 @@ var echo_server = net.createServer(function (socket) {
|
|||||||
puts("server timeout");
|
puts("server timeout");
|
||||||
timeouttime = new Date;
|
timeouttime = new Date;
|
||||||
p(timeouttime);
|
p(timeouttime);
|
||||||
socket.forceClose();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.addListener("data", function (d) {
|
socket.addListener("data", function (d) {
|
||||||
@ -62,19 +61,20 @@ client.addListener("end", function () {
|
|||||||
client.close();
|
client.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
client.addListener("close", function (had_error) {
|
client.addListener("close", function () {
|
||||||
puts("client disconnect");
|
puts("client disconnect");
|
||||||
echo_server.close();
|
echo_server.close();
|
||||||
assert.equal(false, had_error);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
process.addListener("exit", function () {
|
process.addListener("exit", function () {
|
||||||
assert.equal(true, starttime != null);
|
assert.ok(starttime != null);
|
||||||
assert.equal(true, timeouttime != null);
|
assert.ok(timeouttime != null);
|
||||||
|
|
||||||
diff = timeouttime - starttime;
|
diff = timeouttime - starttime;
|
||||||
puts("diff = " + diff);
|
puts("diff = " + diff);
|
||||||
assert.equal(true, timeout < diff);
|
|
||||||
|
assert.ok(timeout < diff);
|
||||||
|
|
||||||
// Allow for 800 milliseconds more
|
// Allow for 800 milliseconds more
|
||||||
assert.equal(true, diff < timeout + 800);
|
assert.ok(diff < timeout + 800);
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user