Get unlimited public & private packages + team-based management with npm Teams.Learn more »

redis-cache-decorator

1.3.1 • Public • Published

redis-cache-decorator

NPM version Build status Test coverage Dependency Status License Downloads

A decorator to cache your functions. Features:

  • Uses Redis caching, expiration, and pub/sub.
  • Concurrency locking - if the function is being run elsewhere with the same arguments, it will wait for the result of that function instead of executing again.
  • Caching - caches results for as long as you want. If you set ttl=0, then you're just this library for concurrency locking, which is completely fine.
  • Timeouts - throws when executing or waiting for a function call takes too long
  • Only tested with ioredis

Use Cases:

  • Race conditions
  • API calls with rate limits
  • Expensive database calls
  • Expensive function calls

Example

Here's a function that caches all your queries.

const assert = require('assert')
const Redis = require('ioredis')
const pg = require('pg-then')
 
const pool = pg.Pool(process.env.POSTGRES_URI)
 
const CreateCacheDecorator = require('redis-cache-decorator')({
  client: Redis.createClient(),
  subscriber: Redis.createClient()
})
 
const fn = CreateCacheDecorator({
  namespace: 'crazy-database-call',
})((query, values) => {
  return db.query(query).then(result => result.rows)
})
 
fn(`
  SELECT *
  FROM users
  WHERE id = $1
`, [
  1
]).then(users => {
  assert(Array.isArray(users))
})

API

const CreateCacheDecorator = require('redis-cache-decorator')(options)

Creates a constructor with the following options:

  • client <required> - a redis client for GET/SET/PUBLISH, etc.
  • subscriber <required> - a redis client for PSUBSCIRBE
  • namespace = '' - a prefix for all the events
  • encoding = 'json' - how data is encoded between redis and node.js. Supported values are:
    • json - the default
    • string
    • buffer
  • ttl = '30s' - the TTL expiration in seconds.
  • timeout = '30s' - how long to wait for the function to execute.
  • pollFactor = 1 / 10 - the fraction of the timeout to poll. For example, a 30s timeout with a 1 / 10 factor means that redis is polled for new changes every 3 seconds.
  • minimumPollInterval = '100ms' - the minimum frequency of polling so you don't end up spamming redis
  • createTimeoutError = () => <Error>{ message: 'Timed out!', code: 'RCDTIMEDOUT' } - the function called to create a timeout error. By default, you can check for timeout errors by checking if (err.code === 'RCDTIMEDOUT').
  • onError = err => console.error(err.stack) - an error handler for redis network errors.
  • disabled = false - disable this decorator, specifically useful for testing.

const decorate = CreateCacheDecorator(options)

Create a decorator with a set of options.

  • namespace <required> - a namespace for this decorator
  • pollInterval - by default, calculated from timeout, pollFactor, and minimumPollInterval, but you can set this yourself.
  • ttl
  • timeout
  • pollFactor
  • minimumPollInterval
  • createTimeoutError
  • onError

const decoratedFunction = decorate(fn)

Decorates the function. The decorated function will have the same API as the original function.

  • The function should return a value or a Promise that can be JSON.stringify()d.
  • The function can be synchronous or asynchronous.
  • this is not supported. Do not access this within the function. The primary reason is that it's difficult to decide how to cache.

const job = decoratedFunction(...args)

Execute the decorated function. Will always return a Promise that resolves to the value. In addition, the promise will have the following properties:

  • .hash - hash of the arguments for this job.

job.then(value => {}, err => {})

Resolve the promise to retrieve the results of the job.

const hash = decoratedFunction.createHash(...args)

Create the hash string for the specified arguments.

decoratedFunction.set(hash, value).then(value => {})

Manually set the value of a hash.

Streams

If a stream is returned, the values will automatically be buffered.

  • encoding='json' - the stream will be concatenated as an object stream -> array. If the stream is not an object stream, it will throw.
  • encoding='string' - the stream will be buffered into a string.
  • encoding='buffer' - the stream will be buffered into a Buffer() instance.

Install

npm i redis-cache-decorator

DownloadsWeekly Downloads

15

Version

1.3.1

License

MIT

Last publish

Collaborators

  • avatar