HA stage 0: health reads workers registry, daily pg_dump timer, backup freshness in monitor (#48)

Co-authored-by: host <host@test.local>
This commit is contained in:
openqjandhost authored and GitHub committed 2026-10-26 23:51:54 +08:00
1 parent 275de39148
commit 455513dd33
6 files changed
+150 -10

No files matched your search

+31
View File
@@ -21,11 +21,13 @@ try:
from cloud.backup import restore_postgres
from cloud.server import create_server
from cloud.worker import Worker
from cloud.workers import heartbeat_worker, register_worker
except ImportError:
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
from cloud.backup import restore_postgres
from cloud.server import create_server
from cloud.worker import Worker
from cloud.workers import heartbeat_worker, register_worker
def _fake_result(returncode=0, stdout="", stderr=""):
@@ -187,6 +189,35 @@ class HealthWorkerFieldTestCase(unittest.TestCase):
self.assertIsNone(body["worker_last_seen_seconds_ago"])
self.assertFalse(body["worker_ok"])
def test_health_worker_db_registry_fresh_ok_without_file(self):
# 多机前提:文件心跳缺失时,DB 注册表的新鲜心跳同样算 ok。
register_worker(self.db_path, "w-db", executor="docker", capacity=1)
heartbeat_worker(self.db_path, "w-db", executor="docker")
self.server.worker_heartbeat_file = os.path.join(
self.tmp.name, "no-such-hb.json")
status, body = self._health()
self.assertEqual(status, 200)
self.assertTrue(body["worker_ok"])
self.assertIsNotNone(body["worker_last_seen_seconds_ago"])
self.assertLess(body["worker_last_seen_seconds_ago"], 5)
def test_health_worker_db_registry_stale_not_ok(self):
register_worker(self.db_path, "w-db", executor="docker", capacity=1)
import sqlite3
conn = sqlite3.connect(self.db_path)
try:
conn.execute("UPDATE workers SET last_seen = ?",
(time.time() - 1000,))
conn.commit()
finally:
conn.close()
self.server.worker_heartbeat_file = os.path.join(
self.tmp.name, "no-such-hb.json")
status, body = self._health()
self.assertEqual(status, 200)
self.assertFalse(body["worker_ok"])
self.assertGreater(body["worker_last_seen_seconds_ago"], 500)
class MonitorSelfTestCase(unittest.TestCase):
def test_monitor_self_test_passes(self):