Commit 01f771a7 authored by Ian Ward's avatar Ian Ward

Merge pull request #132 from ianshward/connection-issues

Connection issues
parents 8e3741e4 86f6573c
......@@ -84,6 +84,7 @@ Client.config = {
, timeout: 5000 // after x ms the server should send a timeout if we can't connect
, failures: 5 // Number of times a server can have an issue before marked dead
, retry: 30000 // When a server has an error, wait this amount of time before retrying
, idle: 5000 // Remove connection from pool when no I/O after `idle` ms
, remove: false // remove server if dead if false, we will attempt to reconnect
, redundancy: false // allows you do re-distribute the keys over a x amount of servers
, keyCompression: true // compress keys if they are to large (md5)
......@@ -144,11 +145,25 @@ Client.config = {
manager.maxTimeout = memcached.maxTimeout;
manager.randomize = memcached.randomize;
manager.setMaxListeners(0);
manager.factory(function factory() {
var S = Array.isArray(serverTokens)
? new Stream
: new Socket
, Manager = this;
, Manager = this
, idleTimeout = function() {
Manager.remove(this);
}
, connectTimeout = function() {
memcached.connectionIssue('Stream connect timeout', S);
Manager.remove(this);
memcached.makeCallback(callback, new Error('Stream connect timeout'));
}
, streamError = function() {
memcached.connectionIssue('Stream error', S);
Manager.remove(this);
};
// config the Stream
S.streamID = sid++;
......@@ -168,12 +183,13 @@ Client.config = {
Manager.remove(this);
}
, data: curry(memcached, privates.buffer, S)
, timeout: function streamTimeout() {
Manager.remove(this);
}
, error: function streamError() {
// callback called when retries is exhausted
memcached.connectionIssue('Stream error', S);
, timeout: connectTimeout
, error: streamError
, connect: function streamConnect() {
// Remove connection timeout listener
this.setTimeout(0, connectTimeout);
// Close idle connections
this.setTimeout(this.memcached.idle, idleTimeout);
}
, end: S.end
});
......@@ -370,6 +386,7 @@ Client.config = {
memcached.HashRing.replaceServer(server, this.failOverServers.shift());
} else {
memcached.HashRing.removeServer(server);
memcached.emit('failure', details);
}
}
});
......
......@@ -177,4 +177,35 @@ describe('Memcached connections', function () {
},10); // Make sure `retry`, which is immediate, has passed
});
});
it('should return error on connection timeout', function(done) {
// Use a non routable IP
var server = '10.255.255.255:1234'
, memcached = new Memcached(server, {
retries: 0,
timeout: 100,
idle: 1000,
failures: 0 });
memcached.get('idontcare', function(err) {
assert.throws(function() { throw err }, /Stream connect timeout/);
memcached.end();
done();
});
});
it('should remove connection when idle', function(done) {
var memcached = new Memcached(common.servers.single, {
retries: 0,
timeout: 100,
idle: 100,
failures: 0 });
memcached.get('idontcare', function(err) {
assert.deepEqual(memcached.connections[common.servers.single].pool.length, 1);
setTimeout(function() {
assert.deepEqual(memcached.connections[common.servers.single].pool.length, 0);
memcached.end();
done();
}, 100);
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment