General caching that protects against a cache-stampede


Most caching libraries do not place a variable into cache until its value has been resolved. When multiple requests for the same key arrive at the same time, all of them will work on resolving the cached key (instead of only the first one) and then each of them will try to update the cache when resolved (i.e. cache stampede).

In cache-stampede, the first request to see an empty cache results for a particular key will immediately register the key in the cache as {__caching__ : true }and move on the resolve the results. When the variable has been resolved the cache is updated with the results. Any subsequent request that see the variable as {__caching__ : true}will wait for retryDelaymilliseconds and then try polling the cache again (until maxRetrieshave been made).


Four basic database adapters are provided.

  • require('cache-stampede').mongo(mongo_collection_object,[options])- Legacy promisification by bluebird
  • require('cache-stampede').mongodb(mongo_collection_object,[options])- Uses mongodb 2.1.x internal promises
  • require('cache-stampede').mongoHistory(mongo_collection_object,[options])- Retains history instead of purging
  • require('cache-stampede').mongoose(collection_name,[options])
  • require('cache-stampede').redis(redis_client,[options])
  • require('cache-stampede').dynamodb(aws_client,[options])
  • require('cache-stampede').gcloudDatastore([datastore_client,redis_client],[options])
  • require('cache-stampede').file(directory,[options])

The relevant database libraries (mongo, mongodb, mongoose, redis, datastore, and dynamodb) are only included as dev depdencies and are not installed through regular npm install. You only need to install them if you want to run tests (mocha). You can specify the particular mongooseobject you want to use, as a property mongoosein options. The file adapter maintains a list of files (named by the respective keys) the specified directory and does not require any third party database servers. The mongoand mongodbadapters allows you to specify the collection as a promise to deliver a collection object (optional).

A special adapter called mongoHistoryretains historical cached values in the collection instead of deleting them. The adapter defines a custom method getHistorythat returns all records for a particular key.

The gcloud datastore adapter gcloudDatastoreuses redis to control locking, so both clients must be specified.

This library can be initialized with a custom adapter. A custom adapter needs to provide get, insert, updateand removefunctions which should return Promise A+ compliant promises. The insertmethod should return KEY_EXISTSerror if a key already exists in the datastore and the getmethod should return nullor undefinedif a key was not found. Please note:



This function either returns a cached value for the supplied key or attempts to resolve the value and update the cache, returning a promise on the results. If an infoproperty is defined in the options, it will be stored (and available) immediately. This function is explicitly bound to the stampede object and can be passed directly to consumers of the cache without having to bind it separately.


Retrieve the supplied key from the cache. If the variable is cachingthe function will retry until maxRetriesis reached. The resulting promise will either be resolved with the cached value or errored with the message MAX_RETRIES. The retry parameter is internally used to keep track of how many retries have been made (if any). If expirywas defined when the key was defined and it has expired, the key will be deleted and KEY_NOT_FOUNDerror thrown.


Set the supplied key as the result of the supplied function and return a promise. The function can either return a value or a promise. If fnis not a function, the cache will be set to the value of this argument. If the key already exists in the cache, the promise will return a E11000error, otherwise the resolved value will be returned. If an infoproperty is defined in the options, it will be stored (and available) immediately. If option upsert is true this function will overwrite any current value.

Returns the infofor the supplied key if this key is either caching or finished running.

Additional controls


Setting payload: truein options will return the full payload of a cached record, including .updated, .expiryetc. The underlying data can be found under the .dataproperty.

Retry and expiry

Optional control options are maxRetriesand retryDelayand expiry(in ms). They are applied as default options to any request that doesn't explicitly specify them.


Old cached records can be purged by defining maxAge(in millisecond) in options when .cachedis called. Passing in `{maxAge:0} will force a refresh.

find (mongo adapters only)

If you include a find(mongo search object) in options, then the search criteria for pre-existing cached record will be an $orof the supplied key and the supplied findcriteria. This method can match a record with a different key than requested, provided the find criteria is fulfilled. This can be very helpful when exact hashes can not be guaranteed between queries.


You can (optional) specify passphraseand algo(defaults to aes192) when you require the module, to encrypt/decrypt all data that flows through the cache. Any record that was saved with a passphrase will be encrypted and have the property encryptedequal to truein the database record. You can also specify a record-specific passphrasein the options of each cached, getand setcommand.


If you specify compressionas true the data will be deflated into a base64 string. When data is fetched from the cache, stampede will look for a compressed: trueflag and automatically inflate the contents when required.


When processing bulk-data it is often conventient to load data in bulk from cache as well. By defining an object perCachein options you can supply any known information to avoid repeat calls to the db. If a any requested key is found in preCacheit is simply returned, otherwise the regular caching mechanism applies. The objects in preCacheneed to adhere to the cache-stampedestorage specification, i.e. the data should be under property data.

clues resolution

If you specify clues: truein options of either .cachedor .setmethod, the function supplied function will be returned to be resolved by cluesin the same thiscontext as there the method was called. It is important to returnthe cache-method so that the resolution machine can evaluate the formula that gets returned (see test/clues-test.js). Failure to do so will result in an orphan record that will remain in __caching__state.

Where do errors go?

The default behaviour is to notcache errors. However, if any error object has a property cacheset to true, then cache-stampedewill save that error to cache and return it as rejected promise when it's requested again. This can be very handy when you know an error represent an irrevocable state for a particular key.




  • 精读《JS 引擎基础之 Shapes and Inline Caches》

    1 引言 本期精读的文章是:JS 引擎基础之 Shapes and Inline Caches( 一起了解下 J...

    2 年前
  • 精读《Caches API》

    1 引言 这个 API 是针对 的。 一般结合 使用,因为请求级别的缓存与具有页面拦截功能的 最配。 本周精读的文章是 cacheapi(

    1 年前
  • 浏览器缓存、CacheStorage、Web Worker 与 Service Worker

    前言 最近在翻红宝书,看到 Web Worker 那章,猛然意识到,通过它竟然可以把几个缓存相关的概念串起来,甚是有趣,撰文记之。最后我也写了一个完整的离线应用 Demo(https://link...

    2 年前
  • 使用vuex缓存数据,一步步优化自己的vuex-cache

    需求: 1. 请求接口之后,缓存当前接口的数据,下次请求同一接口时拿缓存数据,不再重新请求 2. 添加缓存失效时间 cache使用map来实现 1. ES6 模块与 CommonJS ...

    2 年前
  • 从浏览器的Disable cache谈起

    浏览器调试工具的disable cache功能,相信在座的各位都用过。开启这个功能,浏览器关于当前网站的js、css、图片...等缓存都会失效,所有请求都会重新发送给服务器。

    1 个月前
  • 【译】JavaScript engine fundamentals: Shapes and Inline Caches

    前言 前往 ➡️ 我的博客() 本文是根据自己的理解翻译而来,如有疑惑可查看原文 JavaScript engine fundamentals: Shapes and Inline Caches...

    8 个月前
  • 【每日一包0028】cache-content-type,mime-types

    github地址: cachecon...

    1 年前
  • zzcache

    JS library to handle set/get/del/delpattern operations for cache zzcache JS library to handle set...

    7 个月前
  • workbox-cacheable-response

    This library takes a Response object and determines whether it's cacheable based on a specific confi...

    1 年前
  • workbox-cache-expiration

    A service worker helper library that expires cached responses based on age or maximum number of entr...

    1 年前


扫码加入 JavaScript 社区