Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

lru-cache-for-clusters-as-promised

Package Overview
Dependencies
Maintainers
1
Versions
49
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lru-cache-for-clusters-as-promised - npm Package Compare versions

Comparing version 1.3.1 to 1.4.0

29

lru-cache-for-clusters-as-promised.js

@@ -13,2 +13,3 @@ /**

const cluster = require('cluster');
const CronJob = require('cron').CronJob;
const Debug = require('debug');

@@ -19,2 +20,3 @@ const uuid = require('uuid');

const debug = new Debug('lru-cache-for-clusters-as-promised');
const messages = new Debug('lru-cache-for-clusters-as-promised-messages');

@@ -30,2 +32,17 @@ // lru caches by namespace on the master

function startPruneCronJob(cache, cronTime) {
debug('Creating cache prune job.', cache);
const job = new CronJob({
cronTime,
onTick: () => {
debug('Pruning cache', cache);
cache.prune();
},
start: true,
runOnInit: true,
});
job.start();
return job;
}
// only run on the master thread

@@ -38,2 +55,3 @@ if (cluster.isMaster) {

if (request.source !== source) return;
messages(`Master recieved message from worker ${worker.id}`, request);

@@ -46,2 +64,3 @@ // send a response back to the worker thread

response.func = request.func;
messages(`Master sending response to worker ${worker.id}`, response);
worker.send(response);

@@ -61,2 +80,6 @@ }

lru = caches[request.namespace] = new LRUCache(...request.arguments);
// start a job to clean the cache
if (request.arguments[0].prune) {
lru.job = startPruneCronJob(lru, request.arguments[0].prune);
}
}

@@ -123,2 +146,3 @@ sendResponse({

process.on('message', (response) => {
messages(`Worker ${cluster.worker.id} recieved message`, response);
// look up the callback based on the response ID, delete it, then call it

@@ -161,2 +185,5 @@ if (response.source !== source || !callbacks[response.id]) return;

lru = new LRUCache(options);
if (options.prune) {
lru.job = startPruneCronJob(lru, options.prune);
}
}

@@ -248,3 +275,3 @@ }

return {
set: (key, value) => promiseTo('set', key, value),
set: (key, value, maxAge) => promiseTo('set', key, value, maxAge),
get: key => promiseTo('get', key),

@@ -251,0 +278,0 @@ peek: key => promiseTo('peek', key),

9

package.json
{
"name": "lru-cache-for-clusters-as-promised",
"version": "1.3.1",
"version": "1.4.0",
"description": "LRU Cache that is safe for clusters",

@@ -31,2 +31,3 @@ "main": "./lru-cache-for-clusters-as-promised.js",

"dependencies": {
"cron": "^1.1.1",
"debug": "^2.2.0",

@@ -41,7 +42,7 @@ "lru-cache": "^4.0.1",

"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-mocha": "^4.6.0",
"eslint-plugin-react": "^6.4.0",
"eslint-plugin-mocha": "^4.7.0",
"eslint-plugin-react": "^6.4.1",
"express": "^4.14.0",
"should": "^11.1.1",
"supertest": "^2.0.0"
"supertest": "^2.0.1"
},

@@ -48,0 +49,0 @@ "pre-commit": [

@@ -38,2 +38,4 @@ # lru-cache-for-clusters-as-promised

* When `true` expired items are return before they are removed rather than `undefined`
* `prune: false|crontime string`, defaults to `false`
* Use a cron job on the master thread to call `prune()` on your cache at regular intervals specified in "crontime", for example "*/30 * * * * *" would prune the cache every 30 seconds. Also works in single threaded environments not using the `cluster` module.

@@ -44,4 +46,4 @@ > ! note that `length` and `dispose` are missing as it is not possible to pass `functions` via IPC messages.

* `set(key, value)`
* Sets a value for a key.
* `set(key, value, maxAge)`
* Sets a value for a key. Specifying the `maxAge` will cause the value to expire per the `stale` value or when `prune`d.
* `get(key)`

@@ -137,28 +139,8 @@ * Returns a value for a key.

**Clustered cache on master thread for clustered environments**
```
+-----+
+--------+ +---------------+ +---------+ +---------------+ # M T #
| +--> LRU Cache for +--> +--> Worker Sends +--># A H #
| Worker | | Clusters as | | Promise | | IPC Message | # S R #
| <--+ Promised <--+ <--+ to Master <---# T E #
+--------+ +---------------+ +---------+ +---------------+ # E A #
# R D #
v---------------------------------------------------------------+-----+
+-----+
* W T * +--------------+ +--------+ +-----------+
* O H *---> Master +--> +--> LRU Cache |
* R R * | IPC Message | | Master | | by |
* K E *<--+ Listener <--+ <--+ namespace |
* E A * +--------------+ +--------+ +-----------+
* R D *
+-----+
```
![Clustered/Worker Thread](https://www.websequencediagrams.com/files/render?link=RqoArRgR8ZFZCL9ELm9C)
**Promisified for non-clustered environments**
```
+---------------+ +---------------+ +---------+ +-----------+
| +--> LRU Cache for +--> +--> |
| Non-clustered | | Clusters as | | Promise | | LRU Cache |
| <--+ Promised <--+ <--+ |
+---------------+ +---------------+ +---------+ +-----------+
```
![Single/Master Thread](https://www.websequencediagrams.com/files/render?link=OfdL9HvP0ntvqPSAavdV)

@@ -37,4 +37,3 @@ const request = require('supertest');

}
response.body.should.equal(true);
return done();
return response.body === true ? done() : done(new Error(response.body));
});

@@ -41,0 +40,0 @@ });

const config = require('./config');
const cluster = require('cluster');
const should = require('should');
const LRUCache = require('../../');
const member = cluster.isWorker ? 'worker' : 'master';
function TestUtils(cache) {

@@ -13,2 +16,3 @@ return {

tests: {
pruneJob: 'prune cache using cron job',
set: 'set(key, value)',

@@ -56,3 +60,3 @@ get: 'get(key)',

timeout: 1,
namespace: 'bad-cache-resolve',
namespace: `bad-cache-resolve-${member}`,
});

@@ -73,3 +77,3 @@ let large = '1234567890';

failsafe: 'reject',
namespace: 'bad-cache-reject',
namespace: `bad-cache-reject-${member}`,
});

@@ -84,2 +88,32 @@ let large = '1234567890';

},
pruneJob: (cb) => {
const prunedCache = new LRUCache({
max: 10,
stale: true,
maxAge: 100,
namespace: `pruned-cache-${member}`,
prune: '*/1 * * * * *',
});
prunedCache.set(config.args.one, config.args.one)
.then(() => prunedCache.set(config.args.two, config.args.two, 2000))
.then(() => prunedCache.itemCount())
.then((itemCount) => {
// we should see 2 items in the cache
should(itemCount).equal(2);
// check again in 1100 ms
setTimeout(() => {
// one of the items should have been removed based on the expiration
prunedCache.itemCount()
.then((itemCount2) => {
try {
should(itemCount2).equal(1);
return cb(null, true);
} catch (err) {
return cb(err);
}
});
}, 1100);
})
.catch(err => cb(err));
},
set: (cb) => {

@@ -86,0 +120,0 @@ cache.set(config.args.one, config.args.one)

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc