AniUI Academy

Serialise work per key

hardAsync & Promises+350 XPPractice

A shared lock over all writes is simple and slow: saving document A blocks saving document B for no reason. What you usually want is one lock per record.

Implement createKeyedLock(), returning a function run(key, task). task takes no arguments and returns a promise, and run returns a promise settling with that task's own result. Tasks sharing a key run one at a time, in the order run was called for that key, and a task never starts before the previous task for its key has settled. Tasks with different keys are independent and run concurrently. If a task rejects, only its own promise rejects — the next task for that key still runs.

Arguments

keyany
The lock key — tasks sharing a key run serially.
task() => Promise<T>
The work to run under the key's lock.

Returns

Promise<T> — Resolves with the task's own result. A rejection only rejects that call's promise — the next task for the key still runs.

Examples

const run = createKeyedLock();

// Writes to document A run one at a time...
run("doc:A", () => saveDoc("A", edit1));
run("doc:A", () => saveDoc("A", edit2));

// ...but doc:B doesn't wait on doc:A.
run("doc:B", () => saveDoc("B", edit3));

Per-key serialisation without a global write lock.

What it has to do

  • Never run two tasks with the same key at the same time.
  • Start same-key tasks in call order.
  • Let different keys run concurrently.
  • Settle each run with its own task's result.
  • Keep the key's queue moving after a task rejects.

Notes

  • Keep a Map from key to that key's tail promise, and chain each new task onto it with an error-swallowing tail so one rejection doesn't poison the key.
  • Delete the entry when the queue drains so the Map doesn't grow unboundedly across the session.

Stuck? The javascript course covers everything this challenge needs.

Try it yourself
Loading playground...
5 tests · +350 XP

Discussion

Sign in to post
Sign in to join the conversation.Sign in

No comments yet. Be the first to say something.