Three APIs take a lifetime in seconds, and all of them read a non-positive value as a different operation: "this hold or lock carries no deadline, and nothing will ever reclaim it".
So a caller whose computed lifetime comes out zero, from a subtraction, an empty configuration field or a cast, gets no error. It gets places held for ever, or an order frozen in checkout that no sweep will reopen. Of the three outcomes the parameter can produce that is the most expensive, and it is the one reached by accident.
The same parameter carries a third meaning on extendHold(), where NULL restarts the resource own TTL. One argument, three operations, told apart by arithmetic.
Proposed fix: one verb per operation, and a lifetime that has to be a lifetime.
extendHold($booking, $ttl)gives a live hold a new lifetime, and refuses a non-positive one.renewHold($booking)restarts the resource own TTL: what NULL used to mean.suspendHold($booking)takes the hold off the clock: what a zero used to mean.lockTransaction($order, $ttl)requires a positive checkout timeout.lockTransactionIndefinitely($order)takes a lock whose caller owns the lifecycle, which is what the "Lock order for checkout" workflow action wants.
A resource configured for manual validation said the same thing with a zero hold TTL. That field is now left empty instead, and getHoldTtl() returns NULL, so "no deadline" has one spelling everywhere.
No path behaves differently: the two in-tree callers that passed a zero are updated to the verb that says what they meant. Pre-1.0, there is no upgrade path to keep for a caller that passed one.
Issue fork yoyaku-3614464
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
mably commentedComment #5
mably commented