New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

core.io-cache-redis

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

core.io-cache-redis - npm Package Compare versions

Comparing version 0.3.2 to 0.4.0

129

lib/cache.js

@@ -57,21 +57,31 @@ 'use strict';

* we run `fallback` and cache the value returned from that.
*
* @param {String} key raw key
* @param {Function} fallback Called on cache miss
* @param {Int} ttl TTL for this key
* @param {Boolean} [serialize=true] Retrieve content as JSON
* @param {Boolean} [addTimestamp=true] Include a timestamp to payload
* @param {Boolean} [throwOnError=false] Throw if fallback errors
*
* You can use `forceCacheMiss` to always execute the `fallback`
* function thus bypassing the cache altogether.
*
* @param {String} key raw key
* @param {Function} fallback Called on cache miss
* @param {Object} options
* @param {Int} [options.ttl=defaultTTL] TTL for this key
* @param {Boolean} [options.deserialize=true] Retrieve content as JSON
* @param {Boolean} [options.addTimestamp=true] Include a timestamp to payload
* @param {Boolean} [options.throwOnError=false] Throw if fallback errors
* @param {Boolean} [options.forceCacheMiss=false] Throw if fallback errors
* @param {Function} [options.forceCacheMiss] Called with current key and options
* @returns {Promise}
*/
async tryGet(key, fallback, ttl = this.defaultTtl, serialize = true, addTimestamp = true, throwOnError = false) {
async tryGet(key, fallback, options = {}) {
options = extend({ ttl: this.defaultTTL }, this.tryGetOptions, options);
key = this.hashKey(key);
this.logger.info('try to fetch key "%s" from cache...', key);
let value;
let value = await this.get(key, false, serialize);
if (this.shouldQueryCache(key, options)) {
this.logger.info('fetching "%s"', key);
value = await this.get(key, false, options.deserialize);
}
if (value) {
this.logger.info('value was cached, return');
this.logger.info('returning cached value!');
return value;

@@ -81,3 +91,6 @@ }

try {
this.logger.info('cache miss "%s"', key);
value = await fallback();
/**

@@ -87,5 +100,5 @@ * We want to mark when we last accessed

*/
this.makeTimestamp(value, addTimestamp);
this.makeTimestamp(value, options.addTimestamp);
await this.set(key, value, ttl);
await this.set(key, value, options.ttl);
} catch (error) {

@@ -96,3 +109,3 @@ value = { $error: error };

this.handleError(error, 'cache try error');
if (throwOnError) throw error;
if (options.throwOnError) throw error;
}

@@ -105,3 +118,3 @@

* Retrieve key from store.
*
*
* @param {String} key cache key

@@ -127,3 +140,3 @@ * @param {Any} def Any value

*/
set(key, value, ttl = this.defaultTtl) {
set(key, value, ttl = this.defaultTTL) {
key = this.hashKey(key);

@@ -135,4 +148,5 @@ if (typeof value !== 'string') value = this.serialize(value);

/**
* Remove key from ache
* Remove key from cache.
* @param {String} key cache key
* @param {Object} key cache key
* @returns {Promise}

@@ -146,5 +160,16 @@ */

/**
* Format key.
* @param {String} key raw value to hash
* @param {Object} key raw value to hash
* Format `key`.
*
* If `key` is an object it will be
* `serialize`d into a string.
*
* If `key` is a string it will be hashed
* and appended to `cacheKeyPrefix`.
*
* Keys look like:
* ```js
* cache:1239ecd04b073b8f4615d4077be5e263
* ```
* @param {String} key raw value to hash
* @param {Object} key raw value to hash
* @returns {String} Formatted key

@@ -165,2 +190,66 @@ */

/**
* Purge all keys matching the `match` pattern.
*
* @param {String} match Pattern to match
* @param {Integer} count Number of keys per cycle
* @returns {Promise}
*/
purgeKeys(match = this.cacheKeyPrefix, count = 100) {
const stream = this.client.scanStream({
match,
count,
});
let total = 0,
step = 0;
let pipeline = this.client.pipeline();
return new Promise((resolve, reject) => {
stream.on('data', async(keys = []) => {
step += keys.length;
total += keys.length;
for (let key of keys) pipeline.del(key);
if (step > count) {
await pipeline.exec();
step = 0;
pipeline = this.client.pipeline();
this.logger.info('cache purging keys...');
}
});
stream.on('end', async _ => {
if (pipeline) await pipeline.exec();
this.logger.info('cache purged %s keys!', total);
resolve({
match,
total,
});
});
stream.on('error', error => {
this.logger.error('Error purging keys: %s', match);
this.logger.error(error);
reject(error);
});
});
}
shouldQueryCache(key, options) {
if (typeof options.forceCacheMiss === 'function') {
return options.forceCacheMiss(key, options);
}
/**
* If we set `forceCacheMiss` to true
* then we should skip cache and fallback
* to our source function.
*/
return options.forceCacheMiss !== true;
}
get timeUnit() {

@@ -167,0 +256,0 @@ return this.ttlInSeconds ? 'EX' : 'PX';

@@ -10,3 +10,3 @@ /*jshint esversion:6, node:true*/

logger: extend.shim(console),
defaultTtl: (1 * 24 * 60 * 60 * 1000),
defaultTTL: (1 * 24 * 60 * 60 * 1000),
lastError: null,

@@ -18,2 +18,8 @@ ttlInSeconds: false,

cacheKeyPrefix: 'cache:',
tryGetOptions: {
deserialize: true,
addTimestamp: true,
throwOnError: false,
forceCacheMiss: false,
},
/**

@@ -20,0 +26,0 @@ * Matches the string `cache:` followed

2

package.json
{
"name": "core.io-cache-redis",
"version": "0.3.2",
"version": "0.4.0",
"description": "Redis cache module",

@@ -5,0 +5,0 @@ "main": "index.js",

## core.io Cache Redis
This package provides a module for the [core.io](https://npmjs.com/package/core.io) library.

@@ -13,4 +11,41 @@

### Usage
The `CacheClient` exposes a `tryGet` function that takes a key, a `fallback` function and an options object.
* `key`: Either a string or an object that will be used to create a cache identification key. If key is not found in the cache we call `fallback` and store the functions output in cache using key as identifier. Next time we call `tryGet` we return the cached value.
* `fallback`: Some (expensive) function that we want to cache the outputs of its execution.
**Options**:
* `ttl` default(defaultTTL): Time to live for the key after which the key expires.
* `deserialize` default(`true`): Call `deserialize` on the cached value
* `addTimestamp` default(`true`): Add a time-stamp to the cached value
* `throwOnError` default(`false`): If `true` any errors while calling `fallback` will be thrown, else returned in the value
* `forceCacheMiss` default(`false`): Function or boolean to check if we want to force `fallback` call.
```js
result = await cache.tryGet(query, async _ => {
return await service.query(query);
});
```
#### Key Hashing
We can use strings or objects as the raw source for the cache key. If the raw key is an object will be serialized to a string.
Then the create an `md5` hash with the key and prepped the `cacheKeyPrefix`.
By default the `serialize` and `deserialize` functions are mapped to `JSON.stringify` and `JSON.parse` respectively.
If our raw key is the following object:
```js
const query = { limit: 100, order: 'DESC', where: { id: 23 } };
let key = cache.hashKey(query);
assert(key === 'cache:1239ecd04b073b8f4615d4077be5e263');
```
## License
® License by goliatone
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