Comparing version 0.2.8 to 1.0.0
@@ -15,5 +15,5 @@ var HashRing = require( '../lib/hashring' ).HashRing; | ||
// Return the server based on the key | ||
process.stdout.write( Ring.getNode( "my-super-secret-cache-key" ) ); | ||
process.stdout.write( Ring.getNode( "hello-world" ) ); | ||
process.stdout.write( Ring.getNode( "my-super-secret-cache-key" ) ); | ||
process.stdout.write( Ring.get( "my-super-secret-cache-key" ) ); | ||
process.stdout.write( Ring.get( "hello-world" ) ); | ||
process.stdout.write( Ring.get( "my-super-secret-cache-key" ) ); | ||
@@ -34,4 +34,4 @@ // Different algorithms produce different hash maps. So choose wisely | ||
process.stdout.write( sha1Ring.getNode( "my-super-secret-cache-key" ) ); | ||
process.stdout.write( sha1Ring.getNode( "hello-world" ) ); | ||
process.stdout.write( sha1Ring.getNode( "my-super-secret-cache-key" ) ); | ||
process.stdout.write( sha1Ring.get( "my-super-secret-cache-key" ) ); | ||
process.stdout.write( sha1Ring.get( "hello-world" ) ); | ||
process.stdout.write( sha1Ring.get( "my-super-secret-cache-key" ) ); |
@@ -62,3 +62,5 @@ "use strict"; | ||
this.servers = servers; | ||
this.HashRing = new HashRing(args, this.algorithm); | ||
this.HashRing = new HashRing(args, this.algorithm, { | ||
compatiblity: this.compatiblity | ||
}); | ||
this.connections = {}; | ||
@@ -75,3 +77,4 @@ this.issues = []; | ||
, maxQueueSize: -1 | ||
, algorithm: 'crc32' // hashing algorithm that is used for key mapping | ||
, algorithm: 'md5' // hashing algorithm that is used for key mapping | ||
, compatiblity: 'ketama' // hashring compatiblity | ||
@@ -231,3 +234,3 @@ , poolSize: 10 // maximal parallel connections | ||
? memcached.servers[0] | ||
: memcached.HashRing.getNode(key); | ||
: memcached.HashRing.get(key); | ||
@@ -261,3 +264,2 @@ if (map[server]){ | ||
var query = queryCompiler(); | ||
query.domain = process.domain; | ||
@@ -292,3 +294,3 @@ if (this.activeQueries> this.maxQueueSize && this.maxQueueSize > 0){ | ||
} else { | ||
server = this.HashRing.getNode(query.key); | ||
server = this.HashRing.get(query.key); | ||
} | ||
@@ -302,3 +304,3 @@ } | ||
if (!server || (server in this.issues && this.issues[server].failed)) { | ||
return query.callback && memcached.makeCallback(query.callback,new Error('Server not available')); | ||
return query.callback && memcached.makeCallback(query.callback,new Error(['Server at', server, 'not available'].join(' '))); | ||
} | ||
@@ -410,3 +412,3 @@ | ||
} else { | ||
memcached.HashRing.removeServer(server); | ||
memcached.HashRing.remove(server); | ||
memcached.emit('failure', details); | ||
@@ -486,3 +488,3 @@ } | ||
, 'END': function end(tokens, dataSet, err, queue) { | ||
if (!queue.length) queue.push(false); | ||
if (!queue.length) queue.push(undefined); | ||
return [FLUSH, true]; | ||
@@ -657,2 +659,10 @@ } | ||
if (S.responseBuffer.substr(S.responseBuffer.length - 2) === LINEBREAK) { | ||
// Force v8 to re-allocate the responseBuffer and free the BufferStream | ||
// chunks that were appended to it. This works around an issue in v8 where | ||
// it doesn't free the appended strings which can cause poor GC behavior | ||
// and make this function very slow for larger key values. | ||
// See: https://code.google.com/p/v8/issues/detail?id=2869 | ||
S.responseBuffer = (' ' + S.responseBuffer).substr(1); | ||
var chunks = S.responseBuffer.split(LINEBREAK); | ||
@@ -675,13 +685,5 @@ | ||
memcached.delegateCallback = function(master){ | ||
// restore domain if needed | ||
if (master.domain) { | ||
master.domain.enter(); | ||
} | ||
else { | ||
while (process.domain) { | ||
process.domain.exit(); | ||
} | ||
} | ||
memcached.delegateCallback = function(){ | ||
this.activeQueries--; | ||
var master = arguments[0]; | ||
var cb = arguments[arguments.length-1]; | ||
@@ -688,0 +690,0 @@ var args = Array.prototype.slice.call(arguments, 1, arguments.length-1); |
{ | ||
"name": "memcached", | ||
"version": "0.2.8", | ||
"version": "1.0.0", | ||
"author": "Arnout Kazemier", | ||
@@ -20,13 +20,3 @@ "description": "A fully featured Memcached API client, supporting both single and clustered Memcached servers through consistent hashing and failover/failure. Memcached is rewrite of nMemcached, which will be deprecated in the near future.", | ||
], | ||
"maintainers": [ | ||
{ | ||
"name": "Arnout Kazemier", | ||
"email": "info@3rd-Eden.com", | ||
"url": "http://www.3rd-Eden.com" | ||
} | ||
], | ||
"license": { | ||
"type": "MIT", | ||
"url": "http://github.com/3rd-Eden/node-memcached/blob/master/LICENSE" | ||
}, | ||
"license": "MIT", | ||
"repository": { | ||
@@ -37,3 +27,3 @@ "type": "git", | ||
"dependencies": { | ||
"hashring": "0.0.x", | ||
"hashring": "1.0.x", | ||
"jackpot": ">=0.0.6" | ||
@@ -47,4 +37,4 @@ }, | ||
"scripts": { | ||
"test": "./node_modules/.bin/mocha $(shell find test -name '*.test.js')" | ||
"test": "mocha $(find test -name '*.test.js')" | ||
} | ||
} |
396
README.md
# Memcached [![Build Status](https://secure.travis-ci.org/3rd-Eden/node-memcached.png?branch=master)](http://travis-ci.org/3rd-Eden/node-memcached) | ||
`memcached` is a fully featured Memcached client for Node.js. `memcached` is | ||
build with scaling, high availability and exceptional performance in mind. We | ||
built with scaling, high availability and exceptional performance in mind. We | ||
use consistent hashing to store the data across different nodes. Consistent | ||
@@ -21,3 +21,3 @@ hashing is a scheme that provides a hash table functionality in a way that | ||
The client is configurable on different levels. There's a global configuration | ||
that you update so all you Memcached clusters will use the same failure | ||
that you update so all your Memcached clusters will use the same failure | ||
configuration for example, but it's also possible to overwrite these changes per | ||
@@ -28,8 +28,6 @@ `memcached` instance. | ||
This module uses the ASCII protocol to communicate with the server, this makes | ||
it easier to debug for you are user as you can see what is send over the wire | ||
but also for me as developer. But this also means that SASL auth is not | ||
supported in this driver as that requires the use of the binary protocol. The | ||
ASCII protocol not only used by memcached but also by other databases and | ||
message queues, so that is a nice extra. | ||
As in other databases and message queues, this module uses the ASCII protocol to communicate with | ||
the server, which means that you can see what is send over the wire. For debugging this is easier | ||
for both the users and the developers however this also means that SASL auth is not supported | ||
because it demands the binary protocol. | ||
@@ -52,6 +50,6 @@ ## Setting up the client | ||
1. **String**, this only works if you have are running a single server instance | ||
1. **String**, this only works if you are running a single server instance | ||
of Memcached. It's as easy a suppling a string in the following format: | ||
`hostname:port`. For example `192.168.0.102:11212` This would tell the client | ||
to connect to host `192.168.0.102` on port number `11212`. | ||
`hostname:port`. For example `192.168.0.102:11211` This would tell the client | ||
to connect to host `192.168.0.102` on port number `11211`. | ||
@@ -61,24 +59,13 @@ 2. **Array**, if you are running a single server you would only have to supply | ||
running a cluster of Memcached servers. This will allow you to spread the keys | ||
and load between the different servers. Giving you higher availability for | ||
and load between the different servers. Giving you higher availability | ||
when one of your Memcached servers goes down. | ||
3. **Object**, when you are running a cluster of Memcached servers it could | ||
happen to not all server can allocate the same amount of memory. You might | ||
have a Memcached server with 128mb, 512, 128mb. If you would the array | ||
structure all servers would have the same weight in the consistent hashing | ||
scheme. Spreading the keys 33/33/33 over the servers. But as server 2 has | ||
more memory available you might want to give it more weight so more keys get | ||
stored on that server. When you are using a object, the `key` should | ||
represent the server location syntax and the value the weight of the server. | ||
By default all servers have a weight of 1. `{ '192.168.0.102:11212': 1, | ||
'192.168.0.103:11212': 2, '192.168.0.104:11212': 1 }` would generate a | ||
25/50/25 distribution of the keys. | ||
3. **Object**, when running a cluster of Memcached servers, some servers may allocate different amounts of memory, e.g. 128, 512, and 128mb. While by default all servers are equally important and dispatch consistently the keys between the servers (33/33/33%), it is possible to send more keys in servers having more memory. To do so, define an object whose `key` represents the server location and whose value represents a server weight, the default weight for a server being 1; so, for instance `{ '192.168.0.102:11211': 1, '192.168.0.103:11211': 2, '192.168.0.104:11211': 1 }` distributes 50% of the keys on server 103, but only 25% on 104 and 25% on 102. | ||
If you would implement one of the above formats, your constructor would | ||
something like this: | ||
To implement one of the above formats, your constructor would look like this: | ||
```js | ||
var memcached = new Memcached({ '192.168.0.102:11212': 1, '192.168.0.103:11212': 2, '192.168.0.104:11212': 1 }); | ||
var memcached = new Memcached([ '192.168.0.102:11212', '192.168.0.103:11212', '192.168.0.104:11212' ]); | ||
var memcached = new Memcached('192.168.0.102:11212'); | ||
var memcached = new Memcached({ '192.168.0.102:11211': 1, '192.168.0.103:11211': 2, '192.168.0.104:11211': 1 }); | ||
var memcached = new Memcached([ '192.168.0.102:11211', '192.168.0.103:11211', '192.168.0.104:11211' ]); | ||
var memcached = new Memcached('192.168.0.102:11211'); | ||
``` | ||
@@ -88,30 +75,20 @@ | ||
There 2 kinds of options that can be configured. A global configuration that | ||
will be inherited by all Memcached servers instances and a client specific | ||
configuration that can be used to overwrite the globals. The options should be | ||
formatted in an JavaScript `object`. They both use the same object structure: | ||
Memcached accepts two option schemes. The first one inherits of all Memcached server instances | ||
while the second one is client specific and overwrites the globals. To define these options, | ||
Memcached server uses the same properties: | ||
* `maxKeySize`: *250*, the max size of they key allowed by the Memcached server. | ||
* `maxExpiration`: *2592000*, the max expiration of keys by the Memcached server | ||
in seconds. | ||
* `maxValue`: *1048576*, the max size of a value that is allowed by the | ||
Memcached server. | ||
* `poolSize`: *10*, the maximum connections we can allocate in our connection pool. | ||
* `algorithm`: *crc32*, the hashing algorithm that should be used to generate | ||
the hashRing values. | ||
* `reconnect`: *18000000*, when the server is marked as dead we will attempt to | ||
reconnect every x milliseconds. | ||
* `timeout`: *5000*, after x ms the server should send a timeout if we can't | ||
connect. This will also be used close the connection if we are idle. | ||
* `retries`: *5*, How many times to retry socket allocation for given request | ||
* `failures`: *5*, Number of times a server may have issues before marked dead. | ||
* `retry`: *30000*, time to wait between failures before putting server back in | ||
service. | ||
* `remove`: *false*, when the server is marked as dead you can remove it from | ||
the pool so all other will receive the keys instead. | ||
* `failOverServers`: *undefined*, the ability use these servers as failover when | ||
the dead server get's removed from the consistent hashing scheme. This must be | ||
an array of servers confirm the server_locations specification. | ||
* `keyCompression`: *true*, compress keys using md5 if they exceed the | ||
maxKeySize option. | ||
* `maxKeySize`: *250*, the maximum key size allowed. | ||
* `maxExpiration`: *2592000*, the maximum expiration time of keys (in seconds). | ||
* `maxValue`: *1048576*, the maximum size of a value. | ||
* `poolSize`: *10*, the maximum size of the connection pool. | ||
* `algorithm`: *md5*, the hashing algorithm used to generate the `hashRing` values. | ||
* `reconnect`: *18000000*, the time between reconnection attempts (in milliseconds). | ||
* `timeout`: *5000*, the time after which Memcached sends a connection timeout (in milliseconds). | ||
* `retries`: *5*, the number of socket allocation retries per request. | ||
* `failures`: *5*, the number of failed-attempts to a server before it is regarded as 'dead'. | ||
* `retry`: *30000*, the time between a server failure and an attempt to set it up back in service. | ||
* `remove`: *false*, if *true*, authorizes the automatic removal of dead servers from the pool. | ||
* `failOverServers`: *undefined*, an array of `server_locations` to replace servers that fail and | ||
that are removed from the consistent hashing scheme. | ||
* `keyCompression`: *true*, whether to use `md5` as hashing scheme when keys exceed `maxKeySize`. | ||
* `idle`: *5000*, the idle timeout for the connections. | ||
@@ -122,3 +99,3 @@ | ||
```js | ||
var memcached = new Memcached('localhost:11212', {retries:10,retry:10000,remove:true,failOverServers:['192.168.0.103:11212']}); | ||
var memcached = new Memcached('localhost:11211', {retries:10,retry:10000,remove:true,failOverServers:['192.168.0.103:11211']}); | ||
``` | ||
@@ -138,27 +115,17 @@ | ||
#### memcached.touch(key, lifetime, callback); | ||
**memcached.touch** Touches the given key. | ||
Touches the given key. | ||
* `key`: **String** The key | ||
* `lifetime`: **Number** After how long should the key expire measured in `seconds` | ||
* `callback`: **Function** | ||
**Arguments** | ||
`key`: **String** The key | ||
`lifetime`: **Number** After how long should the key expire measured in `seconds` | ||
`callback`: **Function** | ||
```js | ||
memcached.touch('key', 10, function (err) { | ||
// stuff | ||
}); | ||
memcached.touch('key', 10, function (err) { /* stuff */ }); | ||
``` | ||
#### memcached.get(key, callback); | ||
**memcached.get** Get the value for the given key. | ||
Get the value for the given key. | ||
* `key`: **String**, the key | ||
* `callback`: **Function**, the callback. | ||
**Arguments** | ||
`key`: **String**, the key | ||
`callback`: **Function**, the callback. | ||
```js | ||
@@ -170,11 +137,7 @@ memcached.get('foo', function (err, data) { | ||
#### memcached.gets(key, callback); | ||
**memcached.gets** Get the value and the CAS id. | ||
Get the value and the CAS id. | ||
* `key`: **String**, the key | ||
* `callback`: **Function**, the callback. | ||
**Arguments** | ||
`key`: **String**, the key | ||
`callback`: **Function**, the callback. | ||
```js | ||
@@ -188,12 +151,7 @@ memcached.gets('foo', function (err, data) { | ||
``` | ||
**memcached.getMulti** Retrieves a bunch of values from multiple keys. | ||
#### memcached.getMulti(keys, callback); | ||
* `keys`: **Array**, all the keys that needs to be fetched | ||
* `callback`: **Function**, the callback. | ||
Retrieves a bunch of values from multiple keys. | ||
**Arguments** | ||
`keys`: **Array**, all the keys that needs to be fetched | ||
`callback`: **Function**, the callback. | ||
```js | ||
@@ -206,205 +164,145 @@ memcached.getMulti(['foo', 'bar'], function (err, data) { | ||
#### memcached.set(key, value, lifetime, callback); | ||
**memcached.set** Stores a new value in Memcached. | ||
Stores a new value in Memcached. | ||
* `key`: **String** the name of the key | ||
* `value`: **Mixed** Either a buffer, JSON, number or string that you want to store. | ||
* `lifetime`: **Number**, how long the data needs to be stored measured in `seconds` | ||
* `callback`: **Function** the callback | ||
**Arguments** | ||
`key`: **String** the name of the key | ||
`value`: **Mixed** Either a buffer, JSON, number or string that you want to store. | ||
`lifetime`: **Number**, how long the data needs to be stored measured in `seconds` | ||
`callback`: **Function** the callback | ||
```js | ||
memcached.set('foo', 'bar', 10, function (err) { | ||
// stuff | ||
}); | ||
memcached.set('foo', 'bar', 10, function (err) { /* stuff */ }); | ||
``` | ||
#### memcached.replace(key, value, lifetime, callback); | ||
**memcached.replace** Replaces the value in memcached. | ||
Replaces the value in memcached. | ||
* `key`: **String** the name of the key | ||
* `value`: **Mixed** Either a buffer, JSON, number or string that you want to store. | ||
* `lifetime`: **Number**, how long the data needs to be replaced measured in `seconds` | ||
* `callback`: **Function** the callback | ||
**Arguments** | ||
`key`: **String** the name of the key | ||
`value`: **Mixed** Either a buffer, JSON, number or string that you want to store. | ||
`lifetime`: **Number**, how long the data needs to be replaced measured in `seconds` | ||
`callback`: **Function** the callback | ||
```js | ||
memcached.replace('foo', 'bar', 10, function (err) { | ||
// stuff | ||
}); | ||
memcached.replace('foo', 'bar', 10, function (err) { /* stuff */ }); | ||
``` | ||
#### memcached.add(key, value, lifetime, callback); | ||
**memcached.add** Add the value, only if it's not in memcached already. | ||
Add the value, only if it's not in memcached already. | ||
* `key`: **String** the name of the key | ||
* `value`: **Mixed** Either a buffer, JSON, number or string that you want to store. | ||
* `lifetime`: **Number**, how long the data needs to be replaced measured in `seconds` | ||
* `callback`: **Function** the callback | ||
**Arguments** | ||
`key`: **String** the name of the key | ||
`value`: **Mixed** Either a buffer, JSON, number or string that you want to store. | ||
`lifetime`: **Number**, how long the data needs to be replaced measured in `seconds` | ||
`callback`: **Function** the callback | ||
```js | ||
memcached.add('foo', 'bar', 10, function (err) { | ||
// stuff | ||
}); | ||
memcached.add('foo', 'bar', 10, function (err) { /* stuff */ }); | ||
``` | ||
#### memcached.cas(key, value, cas, lifetime, callback); | ||
**memcached.cas** Add the value, only if it matches the given CAS value. | ||
Add the value, only if it matches the given CAS value. | ||
* `key`: **String** the name of the key | ||
* `value`: **Mixed** Either a buffer, JSON, number or string that you want to store. | ||
* `lifetime`: **Number**, how long the data needs to be replaced measured in `seconds` | ||
* `cas`: **String** the CAS value | ||
* `callback`: **Function** the callback | ||
**Arguments** | ||
`key`: **String** the name of the key | ||
`value`: **Mixed** Either a buffer, JSON, number or string that you want to store. | ||
`lifetime`: **Number**, how long the data needs to be replaced measured in `seconds` | ||
`cas`: **String** the CAS value | ||
`callback`: **Function** the callback | ||
```js | ||
memcached.gets('foo', function (err, data) { | ||
memcached.cas('foo', 'bar', data.cas, 10, function (err) { | ||
// stuff | ||
}); | ||
memcached.cas('foo', 'bar', data.cas, 10, function (err) { /* stuff */ }); | ||
}); | ||
``` | ||
#### memcached.append(key, value, callback); | ||
**memcached.append** Add the given value string to the value of an existing item. | ||
Add the given value string to the value of an existing item. | ||
* `key`: **String** the name of the key | ||
* `value`: **Mixed** Either a buffer, JSON, number or string that you want to store. | ||
* `callback`: **Function** the callback | ||
**Arguments** | ||
`key`: **String** the name of the key | ||
`value`: **Mixed** Either a buffer, JSON, number or string that you want to store. | ||
`callback`: **Function** the callback | ||
```js | ||
memcached.append('foo', 'bar', function (err) { | ||
// stuff | ||
}); | ||
memcached.append('foo', 'bar', function (err) { /* stuff */ }); | ||
``` | ||
#### memcached.prepend(key, value, callback); | ||
**memcached.prepend** Add the given value string to the value of an existing item. | ||
Add the given value string to the value of an existing item. | ||
* `key`: **String** the name of the key | ||
* `value`: **Mixed** Either a buffer, JSON, number or string that you want to store. | ||
* `callback`: **Function** the callback | ||
**Arguments** | ||
`key`: **String** the name of the key | ||
`value`: **Mixed** Either a buffer, JSON, number or string that you want to store. | ||
`callback`: **Function** the callback | ||
```js | ||
memcached.preprend('foo', 'bar', function (err) { | ||
// stuff | ||
}); | ||
memcached.preprend('foo', 'bar', function (err) { /* stuff */ }); | ||
``` | ||
#### memcached.incr(key, amount, callback); | ||
**memcached.incr** Increment a given key. | ||
Increment a given key. | ||
* `key`: **String** the name of the key | ||
* `amount`: **Number** The increment | ||
* `callback`: **Function** the callback | ||
**Arguments** | ||
`key`: **String** the name of the key | ||
`amount`: **Number** The increment | ||
`callback`: **Function** the callback | ||
```js | ||
memcached.incr('foo', 10, function (err) { | ||
// stuff | ||
}); | ||
memcached.incr('foo', 10, function (err) { /* stuff */ }); | ||
``` | ||
#### memcached.decr(key, amount, callback); | ||
**memcached.decr** Decrement a given key. | ||
Decrement a given key. | ||
* `key`: **String** the name of the key | ||
* `amount`: **Number** The increment | ||
* `callback`: **Function** the callback | ||
**Arguments** | ||
`key`: **String** the name of the key | ||
`amount`: **Number** The increment | ||
`callback`: **Function** the callback | ||
```js | ||
memcached.incr('foo', 10, function (err) { | ||
// stuff | ||
}); | ||
memcached.decr('foo', 10, function (err) { /* stuff */ }); | ||
``` | ||
#### memcached.del(key, callback); | ||
**memcached.del** Remove the key from memcached. | ||
Remove the key from memcached. | ||
* `key`: **String** the name of the key | ||
* `callback`: **Function** the callback | ||
**Arguments** | ||
`key`: **String** the name of the key | ||
`callback`: **Function** the callback | ||
```js | ||
memcached.del('foo', function (err) { | ||
// stuff | ||
}); | ||
memcached.del('foo', function (err) { /* stuff */ }); | ||
``` | ||
#### memcached.version(callback); | ||
**memcached.version** Retrieves the version number of your server. | ||
Retrieves the version number of your server. | ||
* `callback` | ||
#### memcached.flush(callback); | ||
**memcached.flush** Flushes the memcached server. | ||
Flushes the memcached server. | ||
* `callback` | ||
#### memcached.stats(callback); | ||
**memcached.stats** Retrieves stats from your memcached server. | ||
Retrieves stats from your memcached server. | ||
* `callback` | ||
#### memcached.settings(callback); | ||
**memcached.settings** Retrieves your `stats settings`. | ||
Retrieves your `stats settings`. | ||
* `callback` | ||
#### memcached.slabs(callback); | ||
**memcached.slabs** Retrieves `stats slabs` information. | ||
Retrieves `stats slabs` information. | ||
* `callback` | ||
#### memcached.items(callback); | ||
**memcached.items** Retrieves `stats items` information. | ||
Retrieves `stats items` information. | ||
* `callback` | ||
#### memcached.cachedump(server, slabid, number, callback); | ||
**memcached.cachedump** Inspect cache, see examples for a detailed explanation. | ||
Inspect cache, see examples for a detailed explanation. | ||
* `server` | ||
* `slabid` | ||
* `number` | ||
* `callback` | ||
#### memcached.end(); | ||
**memcached.end** Closes all active memcached connections. | ||
Closes all active memcached connections. | ||
### Private methods | ||
The following methods are intended for private usage: | ||
--------------------------------------- | ||
#### .connect | ||
Fetches or generates a connection for the given server. The supplied callback | ||
The following methods are intended for private usage | ||
**.connect** Fetches or generates a connection for the given server. The supplied callback | ||
function will receive a reference to the connection as argument. | ||
If there are issues with the server connection, we are going to respond with cache-miss pattern. | ||
**Arguments** | ||
`server`: *String*, The server that needs a connection, the format must be | ||
* `server`: *String*, The server that needs a connection, the format must be | ||
confirm the server_locations specification. | ||
* `callback`: *Function*, The callback function that receives the net.Stre | ||
`callback`: *Function*, The callback function that receives the net.Stream | ||
connection. It will be called with 2 arguments `error` and `connection`. | ||
Example: | ||
``` js | ||
memcached.connect( '192.168.0.103:11212', function( err, conn ){ | ||
memcached.connect( '192.168.0.103:11211', function( err, conn ){ | ||
if( err ) throw new Error( err ); | ||
@@ -415,14 +313,8 @@ console.log( conn.server ); | ||
--------------------------------------- | ||
#### .multi | ||
A small wrapper function that makes it easier to query multiple Memcached | ||
**.multi** A small wrapper function that makes it easier to query multiple Memcached | ||
servers. It will return the location for each key or the complete list of | ||
servers. | ||
**Arguments** | ||
`keys`: *Array* **(optional)**, They keys that needs to be converted to a server. | ||
`callback`: *Function*, The callback function for the data, it will be called | ||
* `keys`: *Array* **(optional)**, They keys that needs to be converted to a server. | ||
* `callback`: *Function*, The callback function for the data, it will be called | ||
for **each** key. It will be called with 4 arguments: | ||
@@ -436,4 +328,2 @@ | ||
Example: | ||
``` js | ||
@@ -449,6 +339,3 @@ memcached.multi( false, function( server, key, index, totals ){ | ||
--------------------------------------- | ||
#### .command | ||
This is the core functionality of the `memcached` client. All public API's are | ||
**.command** This is the core functionality of the `memcached` client. All public API's are | ||
routed through this function. It takes care of the argument validations Server | ||
@@ -459,12 +346,7 @@ retrieval ( If the server argument isn't specified ). After all data ready a | ||
**Arguments** | ||
`query`: *Object*, The metaData object, see the `Callbacks` section for the | ||
* `query`: *Object*, The metaData object, see the `Callbacks` section for the | ||
specification. | ||
`server`: *String*, The server the to connect. This is only needed when the | ||
* `server`: *String*, The server the to connect. This is only needed when the | ||
metaData object doesn't contain a key property to retrieve the server from. | ||
Example: | ||
``` js | ||
@@ -483,6 +365,3 @@ memcached.command({ | ||
--------------------------------------- | ||
#### .connectionIssue | ||
A internal function for logging issues with connections. As there can be various | ||
**.connectionIssue** A internal function for logging issues with connections. As there can be various | ||
of ways that an error occurs we need solid issue manager to handle all these | ||
@@ -492,14 +371,8 @@ cases. For example server could crash or the Memcached server could respond with | ||
**Arguments** | ||
`error`: *String*, The actual error message. | ||
`Stream`: *net.Stream*, A reference to the connection stream where the error | ||
* `error`: *String*, The actual error message. | ||
* `Stream`: *net.Stream*, A reference to the connection stream where the error | ||
occurred on. | ||
`callback`: *Function* **(optional)**, The callback function of a potential | ||
* `callback`: *Function* **(optional)**, The callback function of a potential | ||
request, it will be marked as cache miss if it was provided | ||
Example: | ||
``` js | ||
@@ -585,3 +458,3 @@ memcached.connectionIssue( "Server down", connectionReference ); | ||
```js | ||
var memcached = new Memcached([ '192.168.0.102:11212', '192.168.0.103:11212' ]); | ||
var memcached = new Memcached([ '192.168.0.102:11211', '192.168.0.103:11211' ]); | ||
memcached.on('failure', function( details ){ sys.error( "Server " + details.server + "went down due to: " + details.messages.join( '' ) ) }); | ||
@@ -591,2 +464,9 @@ memcached.on('reconnecting', function( details ){ sys.debug( "Total downtime caused by server " + details.server + " :" + details.totalDownTime + "ms")}); | ||
# Compatibility | ||
For compatibility with other [libmemcached](http://libmemcached.org/Clients.html) clients they need to have the behavior | ||
`ketama_weighted` set to true and the `hash` set to the same as `node-memcached`'s | ||
`algorithm`. | ||
Due to client dependent type flags it is unlikely that any types other than `string` will work. | ||
# Contributors | ||
@@ -593,0 +473,0 @@ |
@@ -52,3 +52,3 @@ //global it | ||
}; | ||
assert.throws(noserver, /Server not available/); | ||
assert.throws(noserver, new RegExp('Server at 127.0.1.1234 not available')); | ||
memcached.end(); | ||
@@ -94,3 +94,3 @@ done(); | ||
memcached.get('idontcare', function(err) { | ||
assert.throws(function() { throw err }, /Server not available/); | ||
assert.throws(function() { throw err }, /not available/); | ||
assert.deepEqual(memcached.issues[server].failures, 5); | ||
@@ -134,3 +134,3 @@ assert.deepEqual(memcached.issues[server].locked, true); | ||
memcached.get('idontcare', function (err) { | ||
assert.throws(function() { throw err }, /Server not available/); | ||
assert.throws(function() { throw err }, /not available/); | ||
// Allow enough time to pass for a connection retries to occur | ||
@@ -167,3 +167,3 @@ setTimeout(function() { | ||
memcached.get('idontcare', function(err) { | ||
assert.throws(function() { throw err }, /Server not available/); | ||
assert.throws(function() { throw err }, /not available/); | ||
// Give enough time for server to reconnect | ||
@@ -231,3 +231,3 @@ setTimeout(function() { | ||
memcached.get('idontcare', function(err) { | ||
assert.throws(function() { throw err; }, /Server not available/); | ||
assert.throws(function() { throw err; }, /not available/); | ||
done(); | ||
@@ -234,0 +234,0 @@ }); |
@@ -154,3 +154,3 @@ /** | ||
assert.ok(!error); | ||
answer.should.be.false; | ||
assert.ok(answer===undefined); | ||
@@ -157,0 +157,0 @@ memcached.end(); // close connections |
@@ -46,3 +46,3 @@ 'use strict'; | ||
ok.should.be.true; | ||
answer.should.be.false; | ||
assert.ok(answer===undefined); | ||
@@ -156,3 +156,3 @@ // OK, now let's put it in with the namespace prepended | ||
}), callbacks = 0; | ||
// put a value | ||
@@ -174,3 +174,3 @@ memcached.set('test1', 'test1answer', 1000, function(error, ok) { | ||
assert.ok(!error); | ||
// no longer there | ||
@@ -194,3 +194,3 @@ memcached.get('test1', function(error,answer) { | ||
}), callbacks = 0; | ||
// put a value | ||
@@ -213,3 +213,3 @@ memcached.set('test1', 1, 1000, function(error, ok) { | ||
answer.should.be.eql(2); | ||
// decrement it | ||
@@ -226,3 +226,3 @@ memcached.decr('test1', 1, function(err) { | ||
answer.should.be.eql(1); | ||
//get rid of it | ||
@@ -229,0 +229,0 @@ memcached.del('test1', function(error,answer) { |
@@ -43,3 +43,3 @@ /** | ||
assert.ok(!error); | ||
answer.should.be.false; | ||
assert.ok(answer===undefined); | ||
@@ -46,0 +46,0 @@ memcached.end(); // close connections |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
1
5
433164
62
3127
466
+ Addedbindings@1.1.1(transitive)
+ Addedconnection-parse@0.0.7(transitive)
+ Addedhashring@1.0.3(transitive)
+ Addednan@0.3.2(transitive)
- Removedbisection@0.0.3(transitive)
- Removedhashring@0.0.8(transitive)
Updatedhashring@1.0.x