Consistent TTL Pre-check

When handling TTL/expiration, decide “already expired?” (and validate expiry inputs) before performing DB mutations or expensive work, and then keep DB changes, stats/counters, and keyspace notifications consistent with the real outcome. For conditional variants (NX/XX, ENX/FNX/FXX), short-circuit behavior must match the condition.

copy reviewer prompt

Prompt

Reviewer Prompt

When handling TTL/expiration, decide “already expired?” (and validate expiry inputs) before performing DB mutations or expensive work, and then keep DB changes, stats/counters, and keyspace notifications consistent with the real outcome. For conditional variants (NX/XX, ENX/FNX/FXX), short-circuit behavior must match the condition.

Practical checklist:

  • Parse/validate expiration arguments early.
  • If TTL is already expired:
    • Do not insert/overwrite new data (unless semantics require it); delete only if an old key existed/was actually overwritten.
    • Update expired-key counters and keyspace notifications consistently with the effective DB outcome.
    • Honor conditional flags (e.g., only perform the “expired short-circuit” path when the operation would otherwise proceed per NX/XX rules).
  • If you use TTL-aware fast paths/optimizations (prefetch/batching/cached pointers), ensure cache/resource lifetimes are safe across mutations that can delete/free entries; refresh per batch when necessary.
  • Add tests for expire-then-insert across batch boundaries and for conditional short-circuiting.

Pattern:

// Pseudocode pattern
if (expire && checkAlreadyExpired(milliseconds)) {
    if (found_existing_key) {
        // delete with correct delete semantics (e.g., overwrite deletion vs expired deletion)
        dbDeleteOrExpireSemantics(db, key);
        emit_del_ksn_and_update_stats();
    } else {
        // for “missing key” cases: short-circuit without creating state
        // but still update counters if spec requires it
        emit_required_counters_only();
    }
    return;
}
// otherwise: proceed with normal insert/update and set TTL
apply_set_or_increment_and_set_expire();

Source discussions