isSessionless() || !function_exists('get_transient') || !function_exists('set_transient')) { return self::NO_SLOT; } $key = $scope->transientKey(); $stored = ABJ_404_Solution_DetachAbResolutionTracer::traceTransientOperation( 'get_transient', $key, static function () use ($key) { return get_transient($key); } ); $slot = self::storedSlot($stored); // allow-cache-empty: locally computed attempt counter (always a valid // non-negative int), not a fetched query result. $persisted = ABJ_404_Solution_DetachAbResolutionTracer::traceTransientOperation( 'set_transient', $key, static function () use ($key, $slot) { // The raw write, not TransientStore::store(): that treats "the // store already holds $slot + 1" as success, which is right for // an idempotent write and wrong for a reservation. Here it means // a concurrent request read the same $slot and took it first. // allow-cache-empty: the locally computed attempt counter is a // valid non-negative integer, never a fetched result. return set_transient($key, $slot + 1, self::DEFAULT_TTL_SECONDS); } ); return $persisted ? $slot : self::NO_SLOT; } /** * Interpret a stored counter, accepting only a canonical non-negative integer. * * is_numeric() plus an int cast accepted '2.9' and '1e3' and turned them * into 2 and 1000, so a corrupted or foreign value under this key was * promoted into a real-looking slot and journalled as A/B coordinates -- * fabricated evidence, which is worse for a diagnostic than no evidence. * Anything that is not a counter starts the sequence over; the write that * follows immediately replaces it with a canonical value, so a garbled * store self-heals on the next request instead of resetting forever. * * ABJ_404_Solution_ExactInteger is that rule, already generalised: its own * docblock names this experiment's attempt ordinal as one of the two places * that discovered the defect independently. This counter is the third, and * hand-rolling a fourth narrow pattern here is how there would be a fifth. * * @param mixed $stored */ private static function storedSlot($stored): int { return ABJ_404_Solution_ExactInteger::readOr($stored, 0, 0); } }