Fix workers time columns to DOUBLE PRECISION on Postgres
SQLite REAL is 8-byte double, but Postgres REAL is 4-byte float4 (~7 significant digits). Epoch seconds (10 digits) were rounded to 128-second steps, so worker liveness ages were off by up to +-64s and could even go negative (observed live on the host: last_seen ahead of NOW() by 20s). New tables use DOUBLE PRECISION; existing Postgres tables are upgraded only when information_schema actually reports REAL, so the ALTER does not run on every heartbeat (it would take an ACCESS EXCLUSIVE lock each time). SQLite path is unchanged (its REAL is already double precision). Regression test asserts new tables use DOUBLE PRECISION.
This commit is contained in:
1 parent
3bc9d49d0c
commit
e2d6a454bf
2 files changed
+64
-3
No files matched your search
@@ -458,5 +458,26 @@ class ProjectTaskFieldTestCase(_ServerCase):
|
||||
self.assertEqual(body["executor"], "docker")
|
||||
|
||||
|
||||
class WorkerTablePrecisionTestCase(unittest.TestCase):
|
||||
def test_workers_time_columns_are_double_precision(self):
|
||||
# 回归:2026-10-26 主机实测,workers.last_seen 用 REAL 时,
|
||||
# Postgres 的 float4 把 epoch 秒舍入到 128 秒一档,存活判断
|
||||
# 误差可达 ±64 秒、甚至出现负 age。新表必须是 DOUBLE PRECISION。
|
||||
import sqlite3 as _sqlite3
|
||||
tmp = tempfile.TemporaryDirectory()
|
||||
db_path = os.path.join(tmp.name, "w.db")
|
||||
from cloud.workers import ensure_workers_table
|
||||
ensure_workers_table(db_path)
|
||||
conn = _sqlite3.connect(db_path)
|
||||
try:
|
||||
rows = conn.execute("PRAGMA table_info(workers)").fetchall()
|
||||
finally:
|
||||
conn.close()
|
||||
tmp.cleanup()
|
||||
by_name = {r[1]: r[2] for r in rows}
|
||||
self.assertIn("DOUBLE", by_name["last_seen"])
|
||||
self.assertIn("DOUBLE", by_name["created_at"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user