OoO
e862a9040c
CD Pipeline / deploy (push) Successful in 9m14s
fix(ollama): 解「111 關機 → GCP 也斷」三主機 retry 鏈 + lazy host
統帥 2026-05-04 反饋:「111 關機後,兩台 GCP Ollama 也跟著斷線不可用」
根因(雙 bug 連動):
1. OllamaService.__init__ 凍結 self.host:
`self.host = host or resolve_ollama_host()` 是 instance 級凍結
容器啟動時若 GCP cold start 觸發 fallback 111 → self.host 永遠卡 111
即使 cache 過期,instance 不會重新 resolve
2. generate() 失敗無 retry 鏈:
原邏輯只 mark_unhealthy(self.host) + return failure
沒有「換下一台主機再試」邏輯 → 111 死則全死
修補(雙管齊下):
A. self.host 改 @property:每次存取走 resolve_ollama_host()
- caller 顯式指定(_explicit_host)才凍結
- 內部 _RESOLVE_TTL 120s cache 控制 HTTP probe 成本
B. generate() 三主機 retry 鏈:
for attempt in range(3):
current_host = self.host # property lazy resolve
if attempted → break (避免無限迴圈)
post → success ? return : mark_unhealthy + retry
mark_unhealthy 自動清空 resolve cache,下次 self.host 取新主機
行為對比:
戰前:GCP cold start 卡 111 → 111 關機 → 全部失敗
戰後:GCP cold start 卡 111 → 111 關機 → mark_unhealthy(111) →
self.host 重 resolve → GCP Primary(已暖機)→ 成功
generate_embedding 同類修補延後(caller 多走 explicit host 路徑風險較低)
regression: 36 unit tests 全綠(test_ollama_resolve + test_ai_call_logger)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 08:42:52 +08:00
..
2026-04-28 15:26:20 +08:00
2026-05-03 13:10:15 +08:00
2026-04-19 01:21:13 +08:00
2026-05-01 14:02:37 +08:00
2026-04-29 23:41:03 +08:00
2026-04-29 23:57:36 +08:00
2026-05-03 23:31:30 +08:00
2026-04-19 01:21:13 +08:00
2026-04-29 22:56:00 +08:00
2026-05-01 16:34:13 +08:00
2026-04-25 03:30:14 +08:00
2026-05-03 23:05:11 +08:00
2026-05-03 23:31:30 +08:00
2026-04-29 23:41:03 +08:00
2026-05-01 16:34:13 +08:00
2026-04-29 21:35:56 +08:00
2026-05-02 14:34:30 +08:00
2026-05-03 23:31:30 +08:00
2026-05-01 20:56:17 +08:00
2026-04-19 01:21:13 +08:00
2026-04-28 13:57:44 +08:00
2026-04-28 15:37:07 +08:00
2026-04-27 21:28:23 +08:00
2026-05-02 13:07:30 +08:00
2026-04-22 01:12:23 +08:00
2026-05-02 13:09:34 +08:00
2026-05-03 23:26:18 +08:00
2026-05-03 23:06:08 +08:00
2026-04-30 13:59:12 +08:00
2026-04-30 09:33:39 +08:00
2026-05-02 15:01:55 +08:00
2026-04-19 01:21:13 +08:00
2026-04-27 21:11:52 +08:00
2026-05-03 23:56:12 +08:00
2026-05-03 13:10:55 +08:00
2026-04-28 19:42:05 +08:00
2026-05-03 23:56:12 +08:00
2026-04-27 21:28:23 +08:00
2026-05-03 23:06:08 +08:00
2026-04-25 01:42:40 +08:00
2026-04-19 01:21:13 +08:00
2026-04-19 01:21:13 +08:00
2026-05-03 23:28:45 +08:00
2026-04-29 22:48:24 +08:00
2026-04-29 22:37:20 +08:00
2026-05-04 08:42:52 +08:00
2026-04-29 23:10:27 +08:00
2026-05-02 13:04:18 +08:00
2026-05-03 23:56:12 +08:00
2026-04-19 01:21:13 +08:00
2026-04-20 06:09:33 +08:00
2026-04-19 01:21:13 +08:00
2026-04-22 01:12:23 +08:00
2026-05-03 13:10:15 +08:00
2026-05-02 12:00:34 +08:00
2026-05-03 23:56:12 +08:00
2026-04-27 21:28:23 +08:00
2026-05-03 00:03:38 +08:00
2026-05-03 23:56:12 +08:00
2026-05-02 12:01:04 +08:00
2026-05-03 23:04:58 +08:00
2026-04-19 01:21:13 +08:00
2026-04-19 01:21:13 +08:00
2026-04-27 20:34:15 +08:00
2026-04-19 01:21:13 +08:00
2026-05-01 14:20:09 +08:00