Skip to content

Commit 1fe5953

Browse files
author
Joe Roberts
committed
Merge fix/cloud-snapshot-restore-dispatch into main
Apply v3.1.4 share/read_shared cloud-dispatch pattern to snapshot/restore. Cloud-mode snapshot+restore now actually round-trips state instead of silently no-opping (was AUDIT §7.1). Local-mode path unchanged. Verified on Windows 11 + Python 3.13 and Ubuntu Linux + Python 3.12: both modes, both platforms identical results. See 5fb7147 for details.
2 parents 6031b44 + 5fb7147 commit 1fe5953

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

synrix_runtime/api/runtime.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1616,6 +1616,27 @@ def snapshot(self, label: str = None) -> SnapshotResult:
16161616
if label is None:
16171617
label = f"snap_{int(time.time()*1000000)}"
16181618

1619+
# Cloud mode: route through REST API (audit §7.1 fix — applies the
1620+
# same pattern share/read_shared use as of v3.1.4).
1621+
# Previously read from self.backend (local SQLite even in cloud mode),
1622+
# so a cloud-mode snapshot captured 0 cloud keys.
1623+
if self._cloud_agent is not None:
1624+
start = time.perf_counter_ns()
1625+
try:
1626+
result = self._cloud_agent.snapshot(label) or {}
1627+
latency_us = (time.perf_counter_ns() - start) / 1000
1628+
return SnapshotResult(
1629+
label=result.get("label", label),
1630+
keys_captured=int(result.get("keys_captured", 0) or 0),
1631+
latency_us=float(result.get("latency_us", latency_us) or latency_us),
1632+
size_bytes=int(result.get("size_bytes", 0) or 0),
1633+
)
1634+
except Exception as e:
1635+
latency_us = (time.perf_counter_ns() - start) / 1000
1636+
logger.error("Cloud snapshot failed: %s", e)
1637+
return SnapshotResult(label=label, keys_captured=0,
1638+
latency_us=latency_us, size_bytes=0)
1639+
16191640
start = time.perf_counter_ns()
16201641

16211642
# Get all current memory keys
@@ -1655,6 +1676,29 @@ def snapshot(self, label: str = None) -> SnapshotResult:
16551676

16561677
def restore(self, label: str = None) -> RestoreResult:
16571678
"""Restore from a named snapshot or the latest one."""
1679+
# Cloud mode: route through REST API (audit §7.1 fix — same pattern as
1680+
# snapshot above). Previously this would not restore cloud memories.
1681+
if self._cloud_agent is not None:
1682+
start = time.perf_counter_ns()
1683+
try:
1684+
# Cloud client signature is `restore(snapshot_id)`. The server
1685+
# endpoint accepts the user-supplied label as the snapshot_id.
1686+
# If label is None, cloud client will treat as latest.
1687+
result = self._cloud_agent.restore(label or "") or {}
1688+
latency_us = (time.perf_counter_ns() - start) / 1000
1689+
return RestoreResult(
1690+
label=result.get("label", label or "latest"),
1691+
keys_restored=int(result.get("keys_restored", 0) or 0),
1692+
recovery_time_us=float(
1693+
result.get("recovery_time_us", latency_us) or latency_us
1694+
),
1695+
)
1696+
except Exception as e:
1697+
latency_us = (time.perf_counter_ns() - start) / 1000
1698+
logger.error("Cloud restore failed: %s", e)
1699+
return RestoreResult(label=label or "none", keys_restored=0,
1700+
recovery_time_us=latency_us)
1701+
16581702
start = time.perf_counter_ns()
16591703

16601704
if label:

0 commit comments

Comments
 (0)