Browse Source

Fix idle timeouts

Remove process.now because it doesn't provide enough precision.
v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
8e9ec4abea
  1. 25
      lib/net.js
  2. 9
      src/node.cc
  3. 14
      test/pummel/test-tcp-timeout.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');

9
src/node.cc

@ -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

14
test/pummel/test-tcp-timeout.js

@ -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…
Cancel
Save