1 | node-cache
|
2 | ===========
|
3 |
|
4 | [![Build Status](https://secure.travis-ci.org/tcs-de/nodecache.png?branch=master)](http://travis-ci.org/tcs-de/nodecache)
|
5 | [![Build Status](https://david-dm.org/tcs-de/nodecache.png)](https://david-dm.org/tcs-de/nodecache)
|
6 | [![NPM version](https://badge.fury.io/js/node-cache.png)](http://badge.fury.io/js/node-cache)
|
7 |
|
8 | [![NPM](https://nodei.co/npm/node-cache.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/node-cache/)
|
9 |
|
10 | # Simple and fast NodeJS internal caching.
|
11 |
|
12 | A simple caching module that has `set`, `get` and `delete` methods and works a little bit like memcached.
|
13 | Keys can have a timeout after which they expire and are cleaned from the cache.
|
14 | All keys are stored in a single object so the practical limit is at around 1m keys.
|
15 |
|
16 | # :warning: Breaking changes in version 2.x :warning:
|
17 |
|
18 | Due to the [Issue #11](https://github.com/tcs-de/nodecache/issues/11) the return format of the `.get()` method has been changed!
|
19 |
|
20 | Instead of returning an object with the key `{ "myKey": "myValue" }` it returns the value itself `"myValue"`.
|
21 |
|
22 |
|
23 |
|
24 | # Install
|
25 |
|
26 | ```bash
|
27 | npm install node-cache
|
28 | ```
|
29 |
|
30 | Or just require the `node_cache.js` file to get the superclass
|
31 |
|
32 | # Examples:
|
33 |
|
34 | ## Initialize (INIT):
|
35 |
|
36 | ```js
|
37 | var NodeCache = require( "node-cache" );
|
38 | var myCache = new NodeCache();
|
39 | ```
|
40 |
|
41 | ### Options
|
42 |
|
43 | - `stdTTL`: *(default: `0`)* the standard ttl as number in seconds for every generated cache element.
|
44 | `0` = unlimited
|
45 | - `checkperiod`: *(default: `600`)* The period in seconds, as a number, used for the automatic delete check interval.
|
46 | `0` = no periodic check.
|
47 | **Note:** If you use `checkperiod > 0` you script will not exit at the end, because a internal timeout will always be active.
|
48 |
|
49 | ```js
|
50 | var NodeCache = require( "node-cache" );
|
51 | var myCache = new NodeCache( { stdTTL: 100, checkperiod: 120 } );
|
52 | ```
|
53 |
|
54 | ## Store a key (SET):
|
55 |
|
56 | `myCache.set( key, val, [ ttl ], [callback] )`
|
57 |
|
58 | Sets a `key` `value` pair. It is possible to define a `ttl` (in seconds).
|
59 | Returns `true` on success.
|
60 |
|
61 | ```js
|
62 | obj = { my: "Special", variable: 42 };
|
63 | myCache.set( "myKey", obj, function( err, success ){
|
64 | if( !err && success ){
|
65 | console.log( success );
|
66 | // true
|
67 | // ... do something ...
|
68 | }
|
69 | });
|
70 | ```
|
71 |
|
72 | **Since `1.0.0`**:
|
73 | Callback is now optional. You can also use synchronous syntax.
|
74 |
|
75 | ```js
|
76 | obj = { my: "Special", variable: 42 };
|
77 | success = myCache.set( "myKey", obj, 10000 );
|
78 | // true
|
79 | ```
|
80 |
|
81 |
|
82 | ## Retrieve a key (GET):
|
83 |
|
84 | `myCache.get( key, [callback] )`
|
85 |
|
86 | Gets a saved value from the cache.
|
87 | Returns a `undefined` if not found or expired.
|
88 | If the value was found it returns an object with the `key` `value` pair.
|
89 |
|
90 | ```js
|
91 | myCache.get( "myKey", function( err, value ){
|
92 | if( !err ){
|
93 | if(value == undefined){
|
94 | // key not found
|
95 | }else{
|
96 | console.log( value );
|
97 | //{ my: "Special", variable: 42 }
|
98 | // ... do something ...
|
99 | }
|
100 | }
|
101 | });
|
102 | ```
|
103 |
|
104 | **Since `1.0.0`**:
|
105 | Callback is now optional. You can also use synchronous syntax.
|
106 |
|
107 | ```js
|
108 | value = myCache.get( "myKey" );
|
109 | if ( value == undefined ){
|
110 | // handle miss!
|
111 | }
|
112 | // { my: "Special", variable: 42 }
|
113 | ```
|
114 |
|
115 | **Since `2.0.0`**:
|
116 |
|
117 | The return format changed to the simple value and a `ENOTFOUND` error if not found *( as `callback( err )` or on sync call as result instance of `Error` )*.
|
118 |
|
119 | **Since `2.1.0`**:
|
120 |
|
121 | The return format changed to the simple value, but a due to discussion in #11 a miss shouldn't return an error.
|
122 | So until 2.1.0 it'll return a `undefined`.
|
123 |
|
124 | ## Get multiple keys (MGET):
|
125 |
|
126 | `myCache.mget( [ key1, key2, ... ,keyn ], [callback] )`
|
127 |
|
128 | Gets multiple saved values from the cache.
|
129 | Returns an empty object `{}` if not found or expired.
|
130 | If the value was found it returns an object with the `key` `value` pair.
|
131 |
|
132 | ```js
|
133 | myCache.mget( [ "myKeyA", "myKeyB" ], function( err, value ){
|
134 | if( !err ){
|
135 | console.log( value );
|
136 | /*
|
137 | {
|
138 | "myKeyA": { my: "Special", variable: 123 },
|
139 | "myKeyB": { the: "Glory", answer: 42 }
|
140 | }
|
141 | */
|
142 | // ... do something ...
|
143 | }
|
144 | });
|
145 | ```
|
146 |
|
147 | **Since `1.0.0`**:
|
148 | Callback is now optional. You can also use synchronous syntax.
|
149 |
|
150 | ```js
|
151 | value = myCache.mget( [ "myKeyA", "myKeyB" ] );
|
152 | /*
|
153 | {
|
154 | "myKeyA": { my: "Special", variable: 123 },
|
155 | "myKeyB": { the: "Glory", answer: 42 }
|
156 | }
|
157 | */
|
158 | ```
|
159 |
|
160 | **Since `2.0.0`**:
|
161 |
|
162 | The method for mget changed from `.get( [ "a", "b" ] )` to `.mget( [ "a", "b" ] )`
|
163 |
|
164 | ## Delete a key (DEL):
|
165 |
|
166 | `myCache.del( key, [callback] )`
|
167 |
|
168 | Delete a key. Returns the number of deleted entries. A delete will never fail.
|
169 |
|
170 | ```
|
171 | myCache.del( "myKey", function( err, count ){
|
172 | if( !err ){
|
173 | console.log( count ); // 1
|
174 | // ... do something ...
|
175 | }
|
176 | });
|
177 | ```
|
178 |
|
179 | **Since `1.0.0`**:
|
180 | Callback is now optional. You can also use synchronous syntax.
|
181 |
|
182 | ```js
|
183 | value = myCache.del( "myKeyA" );
|
184 | // 1
|
185 | ```
|
186 |
|
187 | ## Delete multiple keys (MDEL):
|
188 |
|
189 | `myCache.del( [ key1, key2, ... ,keyn ], [callback] )`
|
190 |
|
191 | Delete multiple keys. Returns the number of deleted entries. A delete will never fail.
|
192 |
|
193 | ```js
|
194 | myCache.del( [ "myKeyA", "myKeyB" ], function( err, count ){
|
195 | if( !err ){
|
196 | console.log( count ); // 2
|
197 | // ... do something ...
|
198 | }
|
199 | });
|
200 | ```
|
201 |
|
202 | **Since `1.0.0`**:
|
203 | Callback is now optional. You can also use synchronous syntax.
|
204 |
|
205 | ```js
|
206 | value = myCache.del( [ "myKeyA", "myKeyB", "notExistendKey" ] );
|
207 | // 2
|
208 | ```
|
209 |
|
210 | ## Change TTL (TTL):
|
211 |
|
212 | `myCache.ttl( key, ttl, [callback] )`
|
213 |
|
214 | Redefine the ttl of a key. Returns true if the key has been found and changed. Otherwise returns false.
|
215 | If the ttl-argument isn't passed the default-TTL will be used.
|
216 |
|
217 | ```js
|
218 | myCache = new NodeCache( { stdTTL: 100 } )
|
219 | myCache.ttl( "existendKey", 100, function( err, changed ){
|
220 | if( !err ){
|
221 | console.log( changed ); // true
|
222 | // ... do something ...
|
223 | }
|
224 | });
|
225 |
|
226 | myCache.ttl( "missingKey", 100, function( err, changed ){
|
227 | if( !err ){
|
228 | console.log( changed ); // false
|
229 | // ... do something ...
|
230 | }
|
231 | });
|
232 |
|
233 | myCache.ttl( "existendKey", function( err, changed ){
|
234 | if( !err ){
|
235 | console.log( changed ); // true
|
236 | // ... do something ...
|
237 | }
|
238 | });
|
239 | ```
|
240 |
|
241 | **Since `1.0.0`**:
|
242 | Callback is now optional. You can also use synchronous syntax.
|
243 |
|
244 | ```js
|
245 | value = myCache.ttl( "existendKey", 100 );
|
246 | // true
|
247 | ```
|
248 |
|
249 | ## List keys (KEYS)
|
250 |
|
251 | `myCache.keys( [callback] )`
|
252 |
|
253 | Returns an array of all existing keys.
|
254 |
|
255 | ```js
|
256 | // async
|
257 | myCache.keys( function( err, mykeys ){
|
258 | if( !err ){
|
259 | console.log( mykeys );
|
260 | // [ "all", "my", "keys", "foo", "bar" ]
|
261 | }
|
262 | });
|
263 |
|
264 | // sync
|
265 | mykeys = myCache.keys();
|
266 |
|
267 | console.log( mykeys );
|
268 | // [ "all", "my", "keys", "foo", "bar" ]
|
269 |
|
270 | ```
|
271 |
|
272 | ## Statistics (STATS):
|
273 |
|
274 | `myCache.getStats()`
|
275 |
|
276 | Returns the statistics.
|
277 |
|
278 | ```js
|
279 | myCache.getStats();
|
280 | /*
|
281 | {
|
282 | keys: 0, // global key count
|
283 | hits: 0, // global hit count
|
284 | misses: 0, // global miss count
|
285 | ksize: 0, // global key size count
|
286 | vsize: 0 // global value size count
|
287 | }
|
288 | */
|
289 | ```
|
290 |
|
291 | ## Flush all data (FLUSH):
|
292 |
|
293 | `myCache.flushAll()`
|
294 |
|
295 | Flush all data.
|
296 |
|
297 | ```js
|
298 | myCache.flushAll();
|
299 | myCache.getStats();
|
300 | /*
|
301 | {
|
302 | keys: 0, // global key count
|
303 | hits: 0, // global hit count
|
304 | misses: 0, // global miss count
|
305 | ksize: 0, // global key size count
|
306 | vsize: 0 // global value size count
|
307 | }
|
308 | */
|
309 | ```
|
310 |
|
311 | ## Close the cache:
|
312 |
|
313 | `myCache.close()`
|
314 |
|
315 | This will clear the interval timeout which is set on check period option.
|
316 |
|
317 | ```js
|
318 | myCache.close();
|
319 | ```
|
320 |
|
321 | # Events
|
322 |
|
323 | ## set
|
324 |
|
325 | Fired when a key has been added or changed.
|
326 | You will get the `key` and the `value` as callback argument.
|
327 |
|
328 | ```js
|
329 | myCache.on( "set", function( key, value ){
|
330 | // ... do something ...
|
331 | });
|
332 | ```
|
333 |
|
334 | ## del
|
335 |
|
336 | Fired when a key has been removed manually or due to expiry.
|
337 | You will get the `key` and the deleted `value` as callback arguments.
|
338 |
|
339 | ```js
|
340 | myCache.on( "del", function( key, value ){
|
341 | // ... do something ...
|
342 | });
|
343 | ```
|
344 |
|
345 | ## expired
|
346 |
|
347 | Fired when a key expires.
|
348 | You will get the `key` and `value` as callback argument.
|
349 |
|
350 | ```js
|
351 | myCache.on( "expired", function( key, value ){
|
352 | // ... do something ...
|
353 | });
|
354 | ```
|
355 |
|
356 | ## flush
|
357 |
|
358 | Fired when the cache has been flushed.
|
359 |
|
360 | ```js
|
361 | myCache.on( "flush", function(){
|
362 | // ... do something ...
|
363 | });
|
364 | ```
|
365 |
|
366 | ## Benchmarks
|
367 |
|
368 | ### Version 1.1.x
|
369 |
|
370 | After adding io.js to the travis test here are the benchmark results for set and get of 100000 elements.
|
371 | But be careful with this results, because it has been executed on travis machines, so it is not guaranteed, that was executed on similar hardware.
|
372 |
|
373 | **node.js `0.10.36`**
|
374 | SET: `324`ms ( `3.24`µs per item )
|
375 | GET: `7956`ms ( `79.56`µs per item )
|
376 |
|
377 | **node.js `0.12.0`**
|
378 | SET: `432`ms ( `4.32`µs per item )
|
379 | GET: `42767`ms ( `427.67`µs per item )
|
380 |
|
381 | **io.js `v1.1.0`**
|
382 | SET: `510`ms ( `5.1`µs per item )
|
383 | GET: `1535`ms ( `15.35`µs per item )
|
384 |
|
385 | ### Version 2.0.x
|
386 |
|
387 | Again the same benchmarks by travis with version 2.0
|
388 |
|
389 | **node.js `0.6.21`**
|
390 | SET: `786`ms ( `7.86`µs per item )
|
391 | GET: `56`ms ( `0.56`µs per item )
|
392 |
|
393 | **node.js `0.10.36`**
|
394 | SET: `353`ms ( `3.53`µs per item )
|
395 | GET: `41`ms ( `0.41`µs per item )
|
396 |
|
397 | **node.js `0.12.2`**
|
398 | SET: `327`ms ( `3.27`µs per item )
|
399 | GET: `32`ms ( `0.32`µs per item )
|
400 |
|
401 | **io.js `v1.7.1`**
|
402 | SET: `238`ms ( `2.38`µs per item )
|
403 | GET: `34`ms ( `0.34`µs per item )
|
404 |
|
405 | > As you can see the version 2.0.x will increase the GET performance up to 200x in node 0.10.x.
|
406 | This is possible because the memory allocation for the object returned by 1.x is very expensive.
|
407 |
|
408 | ## Release History
|
409 | |Version|Date|Description|
|
410 | |:--:|:--:|:--|
|
411 | |2.1.1|2015-04-17|Passed old value to the `del` event. Thanks to [Qix](https://github.com/qix) for the pull.|
|
412 | |2.1.0|2015-04-17|Changed get miss to return `undefined` instead of an error. Thanks to all [#11](https://github.com/tcs-de/nodecache/issues/11) contributors |
|
413 | |2.0.1|2015-04-17|Added close function (Thanks to [ownagedj](https://github.com/ownagedj)). Changed the development environment to use grunt.|
|
414 | |2.0.0|2015-01-05|changed return format of `.get()` with a error return on a miss and added the `.mget()` method. *Side effect: Performance of .get() up to 330 times faster!*|
|
415 | |1.1.0|2015-01-05|added `.keys()` method to list all existing keys|
|
416 | |1.0.3|2014-11-07|fix for setting numeric values. Thanks to [kaspars](https://github.com/kaspars) + optimized key ckeck.|
|
417 | |1.0.2|2014-09-17|Small change for better ttl handling|
|
418 | |1.0.1|2014-05-22|Readme typos. Thanks to [mjschranz](https://github.com/mjschranz)|
|
419 | |1.0.0|2014-04-09|Made `callback`s optional. So it's now possible to use a syncron syntax. The old syntax should also work well. Push : Bugfix for the value `0`|
|
420 | |0.4.1|2013-10-02|Added the value to `expired` event|
|
421 | |0.4.0|2013-10-02|Added nodecache events|
|
422 | |0.3.2|2012-05-31|Added Travis tests|
|
423 |
|
424 | [![NPM](https://nodei.co/npm-dl/node-cache.png?months=6)](https://nodei.co/npm/node-cache/)
|
425 |
|
426 | ## Other projects
|
427 |
|
428 | |Name|Description|
|
429 | |:--|:--|
|
430 | |[**rsmq**](https://github.com/smrchy/rsmq)|A really simple message queue based on redis|
|
431 | |[**redis-sessions**](https://github.com/smrchy/redis-sessions)|An advanced session store for NodeJS and Redis|
|
432 | |[**connect-redis-sessions**](https://github.com/mpneuried/connect-redis-sessions)|A connect or express middleware to simply use the [redis sessions](https://github.com/smrchy/redis-sessions). With [redis sessions](https://github.com/smrchy/redis-sessions) you can handle multiple sessions per user_id.|
|
433 | |[**redis-heartbeat**](https://github.com/mpneuried/redis-heartbeat)|Pulse a heartbeat to redis. This can be used to detach or attach servers to nginx or similar problems.|
|
434 | |[**systemhealth**](https://github.com/mpneuried/systemhealth)|Node module to run simple custom checks for your machine or it's connections. It will use [redis-heartbeat](https://github.com/mpneuried/redis-heartbeat) to send the current state to redis.|
|
435 | |[**task-queue-worker**](https://github.com/smrchy/task-queue-worker)|A powerful tool for background processing of tasks that are run by making standard http requests
|
436 | |[**soyer**](https://github.com/mpneuried/soyer)|Soyer is small lib for server side use of Google Closure Templates with node.js.|
|
437 | |[**grunt-soy-compile**](https://github.com/mpneuried/grunt-soy-compile)|Compile Goggle Closure Templates ( SOY ) templates including the handling of XLIFF language files.|
|
438 | |[**backlunr**](https://github.com/mpneuried/backlunr)|A solution to bring Backbone Collections together with the browser fulltext search engine Lunr.js|
|
439 |
|
440 |
|
441 | # The MIT License (MIT)
|
442 |
|
443 | Copyright © 2013 Mathias Peter, http://www.tcs.de
|
444 |
|
445 | Permission is hereby granted, free of charge, to any person obtaining
|
446 | a copy of this software and associated documentation files (the
|
447 | 'Software'), to deal in the Software without restriction, including
|
448 | without limitation the rights to use, copy, modify, merge, publish,
|
449 | distribute, sublicense, and/or sell copies of the Software, and to
|
450 | permit persons to whom the Software is furnished to do so, subject to
|
451 | the following conditions:
|
452 |
|
453 | The above copyright notice and this permission notice shall be
|
454 | included in all copies or substantial portions of the Software.
|
455 |
|
456 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
457 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
458 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
459 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
460 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
461 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
462 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|