diff --git a/xiaobai-datahub/datahub/pipeline.py b/xiaobai-datahub/datahub/pipeline.py index 9c9fa81..c6c5d8c 100644 --- a/xiaobai-datahub/datahub/pipeline.py +++ b/xiaobai-datahub/datahub/pipeline.py @@ -813,8 +813,32 @@ class Pipeline: try: self._switch_release_group(day, staged) except Exception as exc: + reason = f"release group switch failed: {exc}" for item in staged.values(): - self._abandon_batch(item["batch_id"], f"release group switch failed: {exc}") + self._abandon_batch(item["batch_id"], reason) + LOGGER.warning( + "release group switch failed, previous official version keeps serving", + extra={ + "hub": { + "trade_date": day, + "datasets": sorted(staged), + "reason": reason, + "event": "release_group_switch_failed", + } + }, + ) + self.audit( + "pipeline", "release-group", f"eod:{day}", + json.dumps( + { + "state": "failed", + "reason": reason, + "switched": [], + "force": bool(force), + }, + ensure_ascii=False, + ), + ) raise for dataset, item in staged.items(): results[dataset] = { diff --git a/xiaobai-datahub/tests/test_atomic_release.py b/xiaobai-datahub/tests/test_atomic_release.py index 8bccf7d..4274b0b 100644 --- a/xiaobai-datahub/tests/test_atomic_release.py +++ b/xiaobai-datahub/tests/test_atomic_release.py @@ -184,6 +184,13 @@ class ReleaseGroupSwitchTests(unittest.TestCase): for table in ("eod_bars", "eod_valuation", "eod_moneyflow", "eod_auction", "eod_stocks"): rows = self.db.fetchall(f"SELECT * FROM {table} WHERE trade_date = ?", (TRADE_DATE,)) self.assertEqual(rows, [], table) + audit = self.db.fetchone( + "SELECT * FROM audit_log WHERE action = 'release-group' ORDER BY id DESC" + ) + self.assertIsNotNone(audit) + detail = str(audit["detail"]) + self.assertIn("killed mid-switch", detail) + self.assertIn("failed", detail) def test_duplicate_runs_are_idempotent(self) -> None: self.pipe.run_eod_batch_a(TRADE_DATE) @@ -389,6 +396,12 @@ class ForceBoundaryEntryTests(unittest.TestCase): self.assertIn("killed mid-switch", ctx.exception.message) # previous complete A/B versions keep serving self.assertEqual(publications_map(self.db, TRADE_DATE), before) + audit = self.db.fetchone( + "SELECT * FROM audit_log WHERE action = 'release-group' ORDER BY id DESC" + ) + self.assertIsNotNone(audit) + self.assertIn("failed", str(audit["detail"])) + self.assertIn("killed mid-switch", str(audit["detail"])) if __name__ == "__main__":