Skip to content

fed135/ha-store

Repository files navigation

High-Availability store

Efficient data fetching



ha-store Node Build Status Dependencies Status


How it works

Want to make your app faster and don't want to spend on extra infrastructure ? Learn how you can do both with HA-store!

HA-store is a generic wrapper for your data queries, it features:

  • Smart micro-caching for 'hot' information (in-memory or using the redis-adapter)
  • Request coalescing, batching, retrying and circuit-breaking
  • Insightful stats and events
  • Lightweight, configurable and has zero dependencies

Installing

npm install ha-store

Usage

const store = require('ha-store');
const itemStore = store({
  resolver: getItems, // Your resolver can be an async function or should return a Promise
  uniqueParams: ['language']
});

// Anywhere in your application

itemStore.get('123', { language: 'fr' })
  .then(item => /* The item you requested */);

itemStore.get(['123', '456'], { language: 'en' })
  .then(items => /* All the items you requested */);

Options

Name Required Default Description
resolver true - The method to wrap, and how to interpret the returned data. Uses the format <function(ids, params)>
responseParser false (system) The method that format the results from the resolver into an indexed collection. Accepts indexed collections or arrays of objects with an id property. Uses the format <function(response, requestedIds, params)>
uniqueParams false [] The list of parameters that, when passed, generate unique results. Ex: 'language', 'view', 'fields', 'country'. These will generate different combinations of cache keys.
timeout false null The maximum time allowed for the resolver to resolve.
cache false
{
  base: 1000,
  step: 5,
  limit: 30000,
  curve: <function(progress, start, end)>
}
Caching options for the data
batch false
{
  tick: 50,
  max: 100
}
Batching options for the requests
retry false
{
  base: 5,
  step: 3,
  limit: 5000,
  curve: <function(progress, start, end)>
}
Retry options for the requests
breaker false
{
  base: 1000,
  step: 10,
  limit: 65535,
  curve: <function(progress, start, end)>,
  tolerance: 1,
  toleranceFrame: 10000
}
Circuit-breaker options, enabled by default and triggers after the retry limit
storeOptions false
{
  pluginFallback: true,
  pluginRecoveryDelay: 10000,
  memoryLimit: 0.9,
  recordLimit: Infinity
}
If the store plugin errors and pluginFallback is true, the Store instance will attempt to fallback to the default in-memory store. It will then attempt to recover the original store every storePluginRecoveryDelay. The memory limit tells the store to not record new entries once the process RSS memory reaches a certain percentage of the maximum memory allocated by V8.

*All options are in (ms) *Scaling options are represented via and exponential curve with base and limit being the 2 edge values while steps is the number of events over that curve.

Monitoring and events

HA-store emits events to track cache hits, miss and outbound requests.

Event Description
cacheHit When the requested item is present in the microcache, or is already being fetched. Prevents another request from being created.
cacheMiss When the requested item is not present in the microcache and is not currently being fetched. A new request will be made.
cacheFull Whenever a store set is denied because process memory usage has reached its acceptable limit or the number of maximum records was reached for that store.
coalescedHit When a record query successfully hooks to the promise of the same record in transit.
query When a batch of requests is about to be sent.
queryFailed Indicates that the batch has failed. Retry policy will dictate if it should be re-attempted.
retryCancelled Indicates that the batch has reached the allowed number of retries and is now abandoning.
querySuccess Indicates that the batch request was successful.
bumpCache When a call for an item fully loaded in the microcache succeeds, its ttl gets extended.
clearCache When an item in the microcache has reached its ttl and is now being evicted.
circuitBroken When a batch call fails after the limit amount of retries, the circuit gets broken - all calls in the next ttl will automatically fail. It is assumed that there is a problem with the data-source.
circuitRestored Circuit temporarily restored, a tentative to the data-source may be sent.
circuitRecovered The tentative request was successful and the wrapper assumes that the data-source has recovered.
storePluginErrored The custom store has encountered an error
storePluginRestored The custom store has been re-instantiated

You may also want to track the amount of contexts and records stored via the size method.

Testing

npm test

npm run bench

Contribute

Please do! This is an open source project - if you see something that you want, open an issue or file a pull request.

I am always looking for more maintainers, as well.

License

Apache 2.0 (c) 2018 Frederic Charette