One in-process ordering point for review decisions and generic graph writes.
The lock is shared by wrappers over the same backend. Cross-process ordering
still requires a backend compare-and-set operation; this is not that claim.
durable_backend_for
durable_backend_for(candidate: Any) -> Any
Resolve graph/store/journal/fence wrappers to the same backend identity.
Source code in src/symfonic/memory/layers/procedural/review_lock.py
| def durable_backend_for(candidate: Any) -> Any:
"""Resolve graph/store/journal/fence wrappers to the same backend identity."""
seen: list[Any] = []
for _ in range(8):
if any(candidate is item for item in seen):
break
seen.append(candidate)
for attribute in ("unfenced", "durable", "backend", "graph"):
wrapped = getattr(candidate, attribute, None)
if wrapped is not None and wrapped is not candidate:
candidate = wrapped
break
else:
break
return candidate
|
review_lock_for
review_lock_for(backend: Any) -> asyncio.Lock
Return the task-reentrant review/write lock for one backend identity.
Source code in src/symfonic/memory/layers/procedural/review_lock.py
| def review_lock_for(backend: Any) -> asyncio.Lock:
"""Return the task-reentrant review/write lock for one backend identity."""
backend = durable_backend_for(backend)
try:
lock = _LOCKS.get(backend)
if lock is None:
lock = _TaskOwnedLock()
_LOCKS[backend] = lock
return lock
except TypeError:
held = _STRONG_LOCKS.get(id(backend))
if held is None:
held = (backend, _TaskOwnedLock())
_STRONG_LOCKS[id(backend)] = held
return held[1]
|