{ "database_then_delete_old_refill": { "cache": { "expires_at": null, "value": "old", "version": 1 }, "database": { "expires_at": null, "value": "new", "version": 2 }, "stale": true, "trace": [ "R miss then read DB version=1", "W commit DB version=2", "W delete empty cache", "R unconditional set version=1 after delete" ] }, "delayed_double_delete": { "refill_after_second_delete": { "cache": { "expires_at": null, "value": "old", "version": 1 }, "refill_at": 4, "second_delete_at": 3, "stale": true }, "refill_before_second_delete": { "cache": null, "refill_at": 2, "second_delete_at": 3, "stale": false } }, "invalidate_then_old_refill": { "cache": { "expires_at": null, "value": "old", "version": 1 }, "database": { "expires_at": null, "value": "new", "version": 2 }, "stale": true, "trace": [ "W delete cache; generation=1", "R miss then read DB version=1", "W commit DB version=2", "R unconditional set version=1" ] }, "lease_fence": { "cache": { "expires_at": null, "value": "new", "version": 2 }, "fresh_fill_accepted": true, "generation_after_invalidation": 1, "old_token": 0, "stale_fill_accepted": false }, "model": "deterministic cache-aside race model", "not_modeled": [ "a real memcached server or database", "network transport, process crash, or arbitrary schedules", "clock accuracy, eviction policy, or production performance" ], "per_key_serialization": { "cache": { "expires_at": null, "value": "new", "version": 2 }, "stale": false, "trace": [ "W acquire key lock", "W commit DB version=2", "W delete cache", "W release key lock", "R acquire key lock and observe miss", "R read DB version=2 and fill cache" ] }, "ttl": { "meaning": "TTL bounds this modeled stale interval; it does not prevent stale reads before expiry", "read_at_10": null, "read_at_9": { "expires_at": 10, "value": "old", "version": 1 } }, "version_fence": { "cache": { "expires_at": null, "value": "new", "version": 2 }, "fresh_fill_accepted": true, "minimum_version": 2, "stale_fill_accepted": false } }