Gross new-edge quotas belong to a durable sweep, not a worker lifetime.
GrowthDeferred
Bases: BaseException
Named control outcome; legacy except Exception must not swallow it.
edge_or_defer
async
edge_or_defer(graph: Any, scope: Any, edge: Any, *, upsert: bool = False) -> Any
Single-edge atomic group: no invented edge on an explicitly deferred write.
Source code in src/symfonic/capabilities/memory/growth.py
| async def edge_or_defer(graph: Any, scope: Any, edge: Any, *, upsert: bool = False) -> Any:
"""Single-edge atomic group: no invented edge on an explicitly deferred write."""
try:
return await (graph.upsert_edge(scope, edge) if upsert else graph.add_edge(scope, edge))
except GrowthDeferred:
return None
|
reserve
async
reserve(overlay: Any, scope: Any, edge: Any, operation: str, limit: int) -> str | None
Reserve one genuinely new row before mutation; caller releases on failure.
Source code in src/symfonic/capabilities/memory/growth.py
| async def reserve(overlay: Any, scope: Any, edge: Any, operation: str, limit: int) -> str | None:
"""Reserve one genuinely new row before mutation; caller releases on failure."""
if not hasattr(overlay, "progress"):
raise MemoryContractError("a growth budget requires durable bounded worksets")
path = materialise_scope_path(scope)
_, expected, _ = overlay.progress[path]
if expected.upper is not None and expected.edge_limit != limit:
raise MemoryContractError("cannot change the edge ceiling during a sweep")
edges = overlay._edges[scope.tenant_id] # noqa: SLF001 - owned journal projection
existing = edges.get(str(edge.id))
if operation == "upsert_edge":
existing = next((row for row in edges.values() if
(row.source, row.target, row.relationship) ==
(edge.source, edge.target, edge.relationship)), existing)
if existing is None:
existing = await overlay.durable.workset_edge(
scope, str(edge.source), str(edge.target), edge.relationship,
identifier=str(edge.id) if operation == "add_edge" else None,
)
if existing is not None and any(
(scope.tenant_id, str(n)) in overlay.cascaded_nodes
for n in (existing.source, existing.target)
):
existing = None
if existing is not None and (scope.tenant_id, str(existing.id)) not in overlay.deleted_edges:
return None
used = expected.edges_created + overlay.growth_created.get(path, 0)
if used >= limit:
overlay.growth_deferred += 1
raise GrowthDeferred("new-edge sweep budget exhausted")
overlay.growth_created[path] = overlay.growth_created.get(path, 0) + 1
return path
|