Hello,
Looking at the readme, the library provides cache stampede, but it doesn't work in free threading.
Is this issue valid?
❯ uv run --python 3.14.6t --no-project cachebox_freethreading_repro.py
Installed 1 package in 2ms
burst 1: cached(lock=True) ran the body 2x, expected 1x
# /// script
# requires-python = "==3.14.6"
# dependencies = ["cachebox==6.1.2"]
# ///
import sys
import threading
import cachebox
THREADS = 32
BURSTS = 10 # one burst reproduces ~96% of the time; ten make a false negative unlikely
def cold_burst() -> int:
"""Race THREADS threads into one cold cached() key. Return how often the body ran."""
calls: list[int] = [] # list.append is atomic without the GIL; `calls += 1` would not be
barrier = threading.Barrier(THREADS)
@cachebox.cached(cachebox.LRUCache(maxsize=1), lock=True)
def build() -> dict[int, str]:
calls.append(1)
return {i: str(i) for i in range(20_000)} # slow enough that every thread misses
def worker() -> None:
barrier.wait()
build()
threads = [threading.Thread(target=worker) for _ in range(THREADS)]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
return len(calls)
if sys._is_gil_enabled():
print("note: the GIL hides this race; expect it to pass here", file=sys.stderr)
for burst in range(1, BURSTS + 1):
body_calls = cold_burst()
if body_calls > 1:
raise SystemExit(f"burst {burst}: cached(lock=True) ran the body {body_calls}x, expected 1x")
print(f"body ran exactly once in all {BURSTS} bursts of {THREADS} threads")
Hello,
Looking at the readme, the library provides cache stampede, but it doesn't work in free threading.
Is this issue valid?