Implement durable module recovery operations
This commit is contained in:
@@ -12,6 +12,7 @@ from govoplan_core.db.bootstrap import bootstrap_dev_data, create_all_tables
|
||||
from govoplan_core.db.session import get_database
|
||||
from govoplan_core.server.config import GovoplanServerConfig
|
||||
from govoplan_core.server.runtime_agent import RuntimeNodeAgent
|
||||
from govoplan_core.core.runtime_coordination import RuntimeIdentity, runtime_identity
|
||||
from govoplan_core.settings import Settings, settings
|
||||
|
||||
|
||||
@@ -49,11 +50,19 @@ async def lifespan(app: FastAPI):
|
||||
if registry is not None
|
||||
else ()
|
||||
)
|
||||
configured_identity = getattr(
|
||||
app.state,
|
||||
"govoplan_runtime_identity",
|
||||
None,
|
||||
)
|
||||
runtime_agent = RuntimeNodeAgent(
|
||||
settings=settings,
|
||||
software_version=app.version,
|
||||
module_ids=module_ids,
|
||||
metadata={"process": "api"},
|
||||
identity=configured_identity
|
||||
if isinstance(configured_identity, RuntimeIdentity)
|
||||
else None,
|
||||
)
|
||||
await runtime_agent.start()
|
||||
app.state.govoplan_runtime_agent = runtime_agent
|
||||
@@ -73,6 +82,16 @@ def register_health_details(
|
||||
active_settings = (
|
||||
config_settings if isinstance(config_settings, Settings) else settings
|
||||
)
|
||||
module_ids = tuple(manifest.id for manifest in registry.manifests())
|
||||
if not isinstance(
|
||||
getattr(app.state, "govoplan_runtime_identity", None),
|
||||
RuntimeIdentity,
|
||||
):
|
||||
app.state.govoplan_runtime_identity = runtime_identity(
|
||||
active_settings,
|
||||
software_version=app.version,
|
||||
module_ids=module_ids,
|
||||
)
|
||||
|
||||
@app.get("/health/details")
|
||||
def health_details(
|
||||
|
||||
@@ -17,6 +17,21 @@ from govoplan_core.db.session import get_database
|
||||
logger = logging.getLogger("govoplan.runtime")
|
||||
|
||||
|
||||
def application_runtime_identity(app: object) -> RuntimeIdentity:
|
||||
"""Return the registered identity used to fence request-owned effects."""
|
||||
|
||||
state = getattr(app, "state", None)
|
||||
agent = getattr(state, "govoplan_runtime_agent", None)
|
||||
identity = getattr(agent, "identity", None) or getattr(
|
||||
state,
|
||||
"govoplan_runtime_identity",
|
||||
None,
|
||||
)
|
||||
if not isinstance(identity, RuntimeIdentity):
|
||||
raise RuntimeError("The application runtime identity is not available")
|
||||
return identity
|
||||
|
||||
|
||||
class RuntimeNodeAgent:
|
||||
"""Register one process in the shared runtime directory and heartbeat it."""
|
||||
|
||||
@@ -30,9 +45,10 @@ class RuntimeNodeAgent:
|
||||
node_id: str | None = None,
|
||||
queues: tuple[str, ...] | None = None,
|
||||
metadata: dict[str, Any] | None = None,
|
||||
identity: RuntimeIdentity | None = None,
|
||||
) -> None:
|
||||
self.settings = settings
|
||||
self.identity: RuntimeIdentity = runtime_identity(
|
||||
self.identity: RuntimeIdentity = identity or runtime_identity(
|
||||
settings,
|
||||
software_version=software_version,
|
||||
module_ids=module_ids,
|
||||
@@ -126,4 +142,4 @@ class RuntimeNodeAgent:
|
||||
return True
|
||||
|
||||
|
||||
__all__ = ["RuntimeNodeAgent"]
|
||||
__all__ = ["RuntimeNodeAgent", "application_runtime_identity"]
|
||||
|
||||
Reference in New Issue
Block a user