{"id":45592,"library":"node-redis-warlock","title":"node-redis-warlock","description":"node-redis-warlock is a distributed locking library for Node.js using Redis, version 1.0.2. It provides battle-hardened locking mechanisms such as simple lock, optimistic lock with retries, unlocking by lock ID, and TTL modification. It requires node-redis (v0.10 compatible) and Redis v2.6.12+. The library is synchronous in style, relying on callbacks rather than promises or async/await, which is a key differentiator from modern Redis locking libraries like redlock that support promises. Release cadence is sporadic; no recent updates.","status":"maintenance","version":"1.0.2","language":"javascript","source_language":"en","source_url":"https://github.com/thedeveloper/warlock","tags":["javascript","node.js","redis","lock"],"install":[{"cmd":"npm install node-redis-warlock","lang":"bash","label":"npm"},{"cmd":"yarn add node-redis-warlock","lang":"bash","label":"yarn"},{"cmd":"pnpm add node-redis-warlock","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Need a Redis client instance to create the locker.","package":"redis","optional":false}],"imports":[{"note":"The package does not support ESM. Use CommonJS require.","wrong":"import Warlock from 'node-redis-warlock';","symbol":"Warlock","correct":"const Warlock = require('node-redis-warlock');"},{"note":"lock is callback-based, not promise-based.","wrong":"warlock.lock(key, ttl).then(...);","symbol":"warlock.lock","correct":"warlock.lock(key, ttl, (err, unlock) => { ... });"},{"note":"Optimistic locking with retry. Cannot promisify directly.","wrong":"","symbol":"warlock.optimistic","correct":"warlock.optimistic(key, ttl, maxAttempts, wait, (err, unlock) => {});"},{"note":"Unlock by lock ID, not just the key.","wrong":"","symbol":"warlock.unlock","correct":"warlock.unlock(key, lockId, (err, result) => {});"}],"quickstart":{"code":"const Redis = require('redis');\nconst Warlock = require('node-redis-warlock');\n\nconst redis = Redis.createClient({ url: process.env.REDIS_URL || 'redis://localhost:6379' });\nconst warlock = Warlock(redis);\n\nconst key = 'my-lock';\nconst ttl = 5000;\n\nwarlock.lock(key, ttl, (err, unlock, id) => {\n  if (err) {\n    console.error('Lock error:', err);\n    return;\n  }\n  if (typeof unlock === 'function') {\n    console.log('Lock acquired');\n    // Do critical work\n    setTimeout(() => {\n      unlock();\n      console.log('Lock released');\n      redis.quit();\n    }, 1000);\n  } else {\n    console.log('Could not acquire lock');\n    redis.quit();\n  }\n});","lang":"javascript","description":"Connects to Redis, creates a warlock instance, acquires a lock, does work, then releases the lock."},"warnings":[{"fix":"Check typeof unlock === 'function' before calling it.","message":"The callback for lock receives (err, unlock, id); unlock is a function that releases the lock. If the lock is not acquired, unlock is not a function (null or undefined).","severity":"gotcha","affected_versions":">=0.0.1"},{"fix":"Always pass the lock ID to warlock.unlock().","message":"lock returns a lock ID as third argument; use unlock with that ID to release the lock. Using unlock without ID may not work.","severity":"gotcha","affected_versions":">=0.0.1"},{"fix":"Use the 'redis' package (not 'ioredis') to create the client.","message":"The module requires a Redis client from the 'redis' npm package (v0.10 compatible). It will not work with ioredis or other Redis clients.","severity":"gotcha","affected_versions":">=0.0.1"},{"fix":"Use 'redis' v2.8 or later, but ensure compatibility with callback style.","message":"The 'redis' package v0.10 is outdated; modern versions (v3+) have breaking API changes (e.g., no callback in createClient).","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"Always check if unlock is a function before calling it.","message":"optimistic locks may fail after maxAttempts; the callback receives (err, unlock) where unlock may be undefined.","severity":"gotcha","affected_versions":">=0.0.1"}],"env_vars":null,"search_vec":"'1.0.2':19 'async/await':65 'battl':23 'battle-harden':22 'cadenc':82 'callback':60 'compat':48 'differenti':70 'distribut':11 'harden':24 'id':38 'javascript':88 'key':69 'librari':13,53,75 'like':76 'lock':12,25,30,32,37,74,91 'mechan':26 'modern':72 'modif':41 'node':2,6,45 'node-redi':44 'node-redis-warlock':1,5 'node.js':15,89 'optimist':31 'promis':63,80 'provid':21 'rather':61 'recent':86 'redi':3,7,17,46,50,73,90 'redlock':77 'releas':81 'reli':58 'requir':43 'retri':34 'simpl':29 'sporad':84 'style':57 'support':79 'synchron':55 'ttl':40 'unlock':35 'updat':87 'use':16 'v0.10':47 'v2.6.12':51 'version':18 'warlock':4,8","created_at":"2026-06-07T12:55:46.294637+00:00","updated_at":"2026-06-07T12:55:46.294637+00:00","problems":[{"fix":"Use const Warlock = require('node-redis-warlock'); then const warlock = Warlock(redis);","cause":"Incorrect import: using ES import instead of require.","error":"TypeError: warlock.lock is not a function"},{"fix":"Check typeof unlock === 'function' before calling unlock().","cause":"Lock was not acquired; calling unlock without checking type.","error":"Unlock is not a function"},{"fix":"Install and use 'redis' npm package (npm install redis).","cause":"Using 'ioredis' instead of 'redis' package.","error":"Redis connection error: RedisClient is not a constructor"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":null,"cli_version":null,"type":"library","homepage":"https://github.com/thedeveloper/warlock","github":"https://github.com/thedeveloper/warlock","docs":null,"changelog":null,"pypi":null,"npm":"node-redis-warlock","openapi_spec":null,"status_page":null,"smithery":null,"categories":["database"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-07","next_check":"2026-09-05","install_tag":null}}