npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

redis-memolock

v1.0.5

Published

A simple, fast, and reliable memolock for Node.js and TypeScript.

Downloads

291

Readme

Redis Memolock for Node

A simple, fast, and reliable memolock for Node.js and TypeScript.

A MemoLock is a form of distributed caching with promises. It's like memoization, but since the cache is shared by multiple consumers, each key has a locking mechanism that ensures that multiple concurrent requests for the same resource don't cause unnecessary work.

- Stolen from https://github.com/kristoff-it/redis-memolock. Read more about memolock and why you want it there :)

Installation

npm i --save redis-memolock

Usage

import MemolockCache from 'redis-memolock';

const cache = new MemolockCache();

function getArticle(id: string) {
  return cache.get(
    // Key
    'article:' + id,

    // Cache for a minute
    { ttlMs: 60 * 1000 },

    // Fetch article normally
    () => getArticleFromDb(id),
  );
}

OR:

import MemolockCache from 'redis-memolock';

const cache = new MemolockCache();
const articleCache = cache.new(
  {
    getKey: (articleId: number) => 'article:' + articleId,
    ttlMs: 60 * 1000,
  },
  (id) => getArticleFromDb(id),
);

// Fetch the article at any time
articleCache.get(123);

// When article is updated
articleCache.delete(123);

API


MemolockCache

MemolockCache.get(redisKey, opt, fetchFn)

Fetch a value from the cache. If the value is not in the cache, it will be fetched or wait for another process to fetch it.

  • redisKey: The key to use in Redis.
  • opt: Options for the cache (see below).
  • fetchFn: A function that will be called to fetch the actual data if the cache is empty.

MemolockCache.delete(redisKey)

Identical to redis.del(redisKey).

MemolockCache.set(redisKey, value, opt)

Uses redis.set. Valid options are ttlMs and, optionally, encode (more about these in the "Options" section).

MemolockCache.new(opt, fetchFn)

Returns a CacheClient instance with two methods: get and delete.

  • opt: Options for the cache (see below).
  • fetchFn(getVal): A function that will be called to fetch the actual data if the cache is empty. It receives an argument which is the value passed into CacheClient.get.

CacheClient

CacheClient.get(keyVal, opt)

Passes keyVal into your provided getKey function to get the Redis key. opt will override any options passed to new. Otherwise works the same as MemolockCache.get.

CacheClient.delete(keyVal)

Pass keyVal into your provided getKey function to get the Redis key. Works the same as MemolockCache.delete.

CacheClient.set(keyVal, val)

Pass keyVal into your provided getKey function to get the Redis key. Simply uses the redis SET command with the provided value and client TTL.

Warning: A race condition can occur where a get that makes a fetch will overwrite your set. It's recommended that you only use set to warm up the cache, since it could be overwritten by the client's fetchFn before the key expires.


Options

Options are available on MemolockCache.get, MemolockCache.new, and CacheClient.get.

When using MemolockCache.get, you should always pass the same options for the same key to avoid unexpected behavior.

  • ttlMs: How long before the cache expires in milliseconds. (Required for MemolockCache.get and CacheClient.new)
  • lockTimeout: How long a lock is held. This should be longer than you expect a full fetch to take. If a process waits longer than lockTimeout for the cache to be populated, it will try again. (Default: 1000ms)
  • maxAttempts: How many lock timeouts before giving up and throwing an error. (Default: 3)
  • forceRefresh: Will ignore the cache and attempt to fetch the data again. Will not attempt a fetch if there's already a fetch in-progress. (Default: false)
    • getKey(keyVal): Function that converts a value to the cache key (Required, only on CacheClient.new)
  • encode(dataFromFetch): Function that encodes the value to a string before storing it in the cache. (Default: JSON.stringify)
  • decode(strFromRedis): Function that decodes the value from a string before returning it from the cache. (Default: JSON.parse)
  • cacheIf(dataFromFetch): Function that determines whether to cache the value. NOTE: This will still publish the same value to all processes trying to fetch at the same time. It merely will not store the value in the cache. (Default: () => true)