---
title: "Comment by mno tao on \"Your Distributed Lock Expired. Your Code Didn't.\" | Hashnode"
description: "One thing worth adding for anyone adopting this: count rejected publications by cause. Zero rows because Generation moved means another worker took over, which"
url: "https://hashnode.com/posts/your-distributed-lock-expired-your-code-didn-t/6acde157ae82c4dc9a01de56/comment/6aced9ba79a9aae105350829"
---

[Discussion](https://hashnode.com/posts/your-distributed-lock-expired-your-code-didn-t/6acde157ae82c4dc9a01de56)

Comment [Your Distributed Lock Expired. Your Code Didn't.](https://hashnode.com/posts/your-distributed-lock-expired-your-code-didn-t/6acde157ae82c4dc9a01de56)

[mno tao](https://hashnode.com/@dancermno)

[Oct 14](https://hashnode.com/posts/your-distributed-lock-expired-your-code-didn-t/6acde157ae82c4dc9a01de56/comment/6aced9ba79a9aae105350829)

One thing worth adding for anyone adopting this: count rejected publications by cause. Zero rows because Generation moved means another worker took over, which is the design working. Zero rows with Generation unchanged means only the lease time ran out, so builds are outliving the lease and its length or renewal needs attention. The UPDATE alone cannot tell the two apart, so a follow-up read of the row is needed to log which one happened. Did you consider returning the reason from the adapter instead of a bool?

[Patrick Kearns](https://hashnode.com/@fullstackcity)

[Oct 14](https://hashnode.com/posts/your-distributed-lock-expired-your-code-didn-t/6acde157ae82c4dc9a01de56/comment/6aced9ba79a9aae105350829#reply-6acf274c9812fd909467949c)

You could do, there are a couple of subtleties, though. An unchanged generation can also mean that generation already published or ownership was released, so it doesnt establish expiry by itself. A follow up read can help diagnose the refusal, but another acquisition could happen between the UPDATE and that read. If the adapter promises an exact reason, Id determine and return it within a short transaction that holds the row lock across the check and conditional update. Otherwise, Id treat the read as diagnostic evidence and allow an unknown outcome rather than log a definitive cause.

[BomToBe](https://hashnode.com/@bomtobe-orke)

[Oct 14](https://hashnode.com/posts/your-distributed-lock-expired-your-code-didn-t/6acde157ae82c4dc9a01de56/comment/6aced9ba79a9aae105350829#reply-6acff6f11be7c4b932d8d0bd)

Agreed—the reason should be visible, not collapsed into one ‘rejected’ count. For a downstream queue, the generation token only prevents a stale publish if the receiver checks it; otherwise an idempotency key or reconciliation step is still needed. Does the sample report track these rejection causes separately?

[Patrick Kearns](https://hashnode.com/@fullstackcity)

[Oct 15](https://hashnode.com/posts/your-distributed-lock-expired-your-code-didn-t/6acde157ae82c4dc9a01de56/comment/6aced9ba79a9aae105350829#reply-6ad07c9351210ccf0ec3459a)

No, the sample currently logs a generic publication refusal with the report ID and generation, it doesnt track causes separately. A structured result would be a useful extension, provided it preserves the distinction between a reason and a later diagnostic observation. The thing to remember with a downstream receiver is an idempotency key prevents duplicate execution of the same operation, but doesnt necessarily reject a distinct operation from a stale owner. The receiver needs to enforce the generation check atomically with the protected change. Otherwise it wont provide that same prevention guarantee.

[mno tao](https://hashnode.com/@dancermno)

[Oct 16](https://hashnode.com/posts/your-distributed-lock-expired-your-code-didn-t/6acde157ae82c4dc9a01de56/comment/6aced9ba79a9aae105350829#reply-6ad1815833dcd04d662b19ae)

Fair point about another acquisition landing between the UPDATE and the read. Logging it as diagnostic evidence with an unknown outcome allowed seems like the honest version, and it keeps the adapter contract to what it can actually guarantee. Thanks for the detailed answer.
