Files
egg e2ce75b004 fix(hold): dedup equipment cache, fix portal iframe, improve Hold dashboards
- Equipment cache: add freshness gate so only 1 Oracle query per 5-min cycle
  across 4 gunicorn workers; sync worker waits before first refresh
- Portal: add frame-busting to prevent recursive iframe nesting
- Hold Overview: remove redundant TreeMap, add Product & Future Hold Comment
  columns to LotTable
- Hold History: switch list.sql JOIN from DW_MES_LOT_V (WIP snapshot) to
  DW_MES_CONTAINER (historical master) for reliable Product data; add
  Future Hold Comment column; fix comment truncation with hover tooltip
- Page status: reorganize drawer groupings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 09:01:02 +08:00

2.0 KiB
Raw Permalink Blame History

Why

.env 設定 GUNICORN_WORKERS=4,每個 worker 各自有獨立的 equipment sync thread共 4 個)。每 5 分鐘週期4 個 sync thread 輪流取得分散式鎖後都去查 Oracle產生 4 次完全相同的 SELECT ... FROM DW_MES_EQUIPMENTSTATUS_WIP_V~2700 rows其中 3 次是多餘的。分散式鎖只做序列化serialize沒有去重deduplicate。另外 init_realtime_equipment_cache() 存在 double-call 問題init 先呼叫一次 refresh_equipment_status_cache(),再啟動 sync thread 立即又呼叫一次。

What Changes

  • Freshness gaterefresh_equipment_status_cache() 取得分散式鎖後、查 Oracle 前,檢查 Redis equipment_status:meta:updated 時間戳。若距上次更新不到 sync_interval / 2 秒,跳過 Oracle 查詢並釋放鎖。force=True 繞過此檢查。
  • Wait-first sync worker_sync_worker() 改為先等 interval 再開始查詢(_STOP_EVENT.wait(timeout=interval) loop避免與 init 的首次 refresh 重複。
  • 模組級 _SYNC_INTERVAL 變數:由 init_realtime_equipment_cache() 設定,供 freshness gate 使用。

Capabilities

New Capabilities

(無新增 capability。此為既有 equipment cache sync 機制的去重優化。)

Modified Capabilities

(無 spec-level requirement 變更。改動純屬實作層最佳化,不影響快取對外行為、資料即時性或 API 契約。)

Impact

  • 檔案src/mes_dashboard/services/realtime_equipment_cache.py(唯一修改檔案)
  • Oracle 負載:每 5 分鐘週期從 4 次查詢降至 1 次
  • 資料即時性:無影響,每週期仍保證至少 1 次更新
  • force=True 調用:無影響,繞過 freshness gate
  • Process-level cache:無影響,_save_to_redis() 已呼叫 invalidate(),其他 worker 的 L1 cache 在 30s TTL 內自然過期
  • Worker 重啟gunicorn max_requests:改善——新 worker 的 init refresh 會被 freshness gate 擋住