Files
2026-07-13 12:24:33 +08:00

77 lines
3.3 KiB
ReStructuredText

Fault Inject
============
A **test/diagnostic-only** adapter that wraps a real inner adapter and
deterministically drops keys on the load read, simulating partial L2 retrieve
failures. It exercises CacheBlend's **segmented-prefix** recovery path — a
gapped found-set (hit … miss … hit) that a healthy cache never produces —
without needing an actual faulty backend.
.. warning::
Never enable in production. It silently makes reads fail, so any KV it
serves is intentionally incomplete.
The wrapped backend is given as a full adapter spec under ``inner`` (any
registered ``type``), so it keeps its own configuration, eviction, persist, and
serde settings. Faulting applies to the load read only: a dropped key is
reported *present at lookup* but its *load fails* (the faithful "L2 retrieve
error"); the prefetch controller releases the load-failed locks via the trim
mask. Everything else (store, lookup, unlock, delete, usage) passes straight
through to the inner adapter.
**Fields:**
- ``inner`` (required): full adapter spec for the wrapped backend, e.g.
``{"type": "fs_native", "base_path": "/dev/shm/l2"}``.
- ``gap_tail_ratios``: positions to always drop, given as distance-from-tail
fractions of the load length in ``[0, 1]`` (``0.0`` = last chunk, ``0.5`` =
middle, ``1.0`` = first). Workload-agnostic and self-scaling across context
lengths. Default ``[]``.
- ``gap_indices``: exact head-relative task-positions to always drop.
Default ``[]``.
- ``rate``: per-key drop probability in ``[0, 1]`` via a stable seeded hash of
the key. Default ``0.0`` (pass-through).
- ``seed``: seed for the ``rate`` hash (deterministic given the seed).
Default ``0``.
Defaults are pass-through; set at least one of ``gap_tail_ratios``,
``gap_indices``, or ``rate`` to drop anything.
Drop a stable mid-prefix gap (the CacheBlend segmented-prefix repro), wrapping
an ``fs_native`` backend:
.. code-block:: bash
--l2-adapter '{"type": "fault_inject", "inner": {"type": "fs_native", "base_path": "/dev/shm/cb_l2"}, "gap_tail_ratios": [0.5]}'
To actually exercise CacheBlend's **segmented-prefix recovery**, pair the gap
with the server flag ``--enable-segmented-prefix`` (CacheBlend only —
``--engine-type blend``). The dropped mid chunk produces a gapped found-set;
with segmented-prefix enabled the prefix leg **retains the post-gap chunks**
(loads prefix + tail) and recomputes **only the dropped gap**, instead of
truncating the prefix at the gap:
.. code-block:: bash
lmcache server … \
--l2-adapter '{"type": "fault_inject", "inner": {"type": "fs_native", "base_path": "/dev/shm/cb_l2"}, "gap_tail_ratios": [0.5]}' \
--enable-segmented-prefix
Randomly drop ~10% of loads (deterministic given the seed):
.. code-block:: bash
--l2-adapter '{"type": "fault_inject", "inner": {"type": "fs", "base_path": "/data/l2"}, "rate": 0.1, "seed": 7}'
Drop an exact load position (precise single-gap repro):
.. code-block:: bash
--l2-adapter '{"type": "fault_inject", "inner": {"type": "fs_native", "base_path": "/dev/shm/cb_l2"}, "gap_indices": [12]}'
At startup the adapter logs ``FaultInjectL2Adapter ACTIVE (rate=… seed=…
gap_indices=… gap_tail_ratios=[…]) wrapping <inner> -- test/diagnostic use
only.``, and ``report_status()`` reports the active fault config under a
``fault_inject`` sub-dict.