Feature request
Please consider allowing Lock to be constructed with an existing UUID/token so a lock acquired in one process can be released safely from another process.
Use case
In serverless/workflow environments, the process that acquires the lock is not always the same process that knows when the protected work has finished. For example:
- A cron route acquires a lock before starting an async workflow/job.
- The route returns immediately after
start() succeeds.
- A later workflow step, worker, or finalizer needs to release the same lock.
@upstash/lock already releases owner-safely by checking the UUID value in Redis before deleting the key. The missing piece is a public way to seed that UUID into a new Lock instance so the finalizer can call release() without having called acquire() in that same process.
Proposed API
const lock = new Lock({
id: "cron:sync-tn-stock",
redis,
lease: 10 * 60 * 1000,
});
const uuid = crypto.randomUUID();
const acquired = await lock.acquire({ uuid });
if (!acquired) return;
// Persist/pass `uuid` to the async worker or workflow input/output.
Then later, in another process:
const lock = new Lock({
id: "cron:sync-tn-stock",
redis,
UUID: uuid,
});
await lock.release();
Patch shape
This is the minimal change we are currently carrying locally with patch-package:
type LockCreateConfig = {
redis: Redis;
id: string;
lease?: number;
retry?: RetryConfig;
+ UUID?: string;
};
this.lock = {
redis: config.redis,
id: config.id,
lease: config.lease ?? this.DEFAULT_LEASE_MS,
- UUID: null,
+ UUID: config.UUID ?? null,
retry: { ... }
};
Why this helps
This keeps the existing UUID-matched Lua release semantics intact while supporting async/serverless orchestration patterns without relying only on TTL expiry. It would also avoid downstream projects needing to patch node_modules for this small extension.
Feature request
Please consider allowing
Lockto be constructed with an existing UUID/token so a lock acquired in one process can be released safely from another process.Use case
In serverless/workflow environments, the process that acquires the lock is not always the same process that knows when the protected work has finished. For example:
start()succeeds.@upstash/lockalready releases owner-safely by checking the UUID value in Redis before deleting the key. The missing piece is a public way to seed that UUID into a newLockinstance so the finalizer can callrelease()without having calledacquire()in that same process.Proposed API
Then later, in another process:
Patch shape
This is the minimal change we are currently carrying locally with
patch-package:type LockCreateConfig = { redis: Redis; id: string; lease?: number; retry?: RetryConfig; + UUID?: string; }; this.lock = { redis: config.redis, id: config.id, lease: config.lease ?? this.DEFAULT_LEASE_MS, - UUID: null, + UUID: config.UUID ?? null, retry: { ... } };Why this helps
This keeps the existing UUID-matched Lua release semantics intact while supporting async/serverless orchestration patterns without relying only on TTL expiry. It would also avoid downstream projects needing to patch
node_modulesfor this small extension.