feat(ttp): E.1.11 RuleStore contract — base ABC, factory, filesystem + database stubs
Adds decnet/ttp/store/ subpackage: - base.py: RuleState frozen dataclass, RuleChange NamedTuple, RuleStore ABC - factory.py: get_rule_store() reading DECNET_TTP_RULE_STORE_TYPE - impl/filesystem.py: FilesystemRuleStore with sys.platform=='linux' fail-fast guard, allowlist filename regex, raw inotify mask bits (lib import deferred to E.3 so contract phase compiles without the asyncinotify dep installed) - impl/database.py: DatabaseRuleStore stub (no platform guard) TTPRule + TTPRuleState SQLModels were already shipped at E.1.1; this commit closes the type-only TYPE_CHECKING forward-ref in rule_engine.py via real runtime imports through the new package.
This commit is contained in:
60
decnet/ttp/store/impl/database.py
Normal file
60
decnet/ttp/store/impl/database.py
Normal file
@@ -0,0 +1,60 @@
|
||||
"""Database-backed rule store — ``ttp_rule`` + ``ttp_rule_state``.
|
||||
|
||||
Contract step E.1.11. Bodies raise ``NotImplementedError``; the
|
||||
backing tables (:class:`TTPRule`, :class:`TTPRuleState`) shipped at
|
||||
E.1.1.
|
||||
|
||||
Right for swarm: master syncs filesystem changes into ``ttp_rule``,
|
||||
workers tail the DB, state in ``ttp_rule_state`` survives restart and
|
||||
propagates to every worker. Pick via
|
||||
``DECNET_TTP_RULE_STORE_TYPE=database``.
|
||||
|
||||
No platform guard — works on macOS / Windows where the filesystem
|
||||
backend's inotify dependency is unavailable.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import AsyncIterator
|
||||
|
||||
from decnet.ttp.impl.rule_engine import CompiledRule
|
||||
from decnet.ttp.store.base import RuleChange, RuleState, RuleStore
|
||||
|
||||
|
||||
class DatabaseRuleStore(RuleStore):
|
||||
"""``ttp_rule`` content + ``ttp_rule_state`` operational state.
|
||||
|
||||
Contract phase: every method raises ``NotImplementedError``. The
|
||||
impl step (E.3) implements DB-tail subscription + master-side
|
||||
filesystem→DB sync. Worker-side tailing reads via the existing
|
||||
repository pattern; the master's filesystem-watch sync is
|
||||
structurally a delta from :class:`FilesystemRuleStore` plus a
|
||||
``ttp_rule`` upsert.
|
||||
"""
|
||||
|
||||
async def load_compiled(self) -> list[CompiledRule]:
|
||||
raise NotImplementedError(
|
||||
"DatabaseRuleStore.load_compiled lands at E.3",
|
||||
)
|
||||
|
||||
async def get_state(self, rule_id: str) -> RuleState:
|
||||
raise NotImplementedError(
|
||||
"DatabaseRuleStore.get_state lands at E.3",
|
||||
)
|
||||
|
||||
async def set_state(
|
||||
self,
|
||||
rule_id: str,
|
||||
state: RuleState,
|
||||
set_by: str,
|
||||
) -> None:
|
||||
raise NotImplementedError(
|
||||
"DatabaseRuleStore.set_state lands at E.3",
|
||||
)
|
||||
|
||||
def subscribe_changes(self) -> AsyncIterator[RuleChange]:
|
||||
raise NotImplementedError(
|
||||
"DatabaseRuleStore.subscribe_changes lands at E.3",
|
||||
)
|
||||
|
||||
|
||||
__all__ = ["DatabaseRuleStore"]
|
||||
Reference in New Issue
Block a user