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

1.4 KiB

1. Freshness Gate

  • 1.1 Add module-level _SYNC_INTERVAL: int = 300 variable in realtime_equipment_cache.py
  • 1.2 In init_realtime_equipment_cache(), set _SYNC_INTERVAL from config.get('EQUIPMENT_STATUS_SYNC_INTERVAL', 300) before starting sync worker
  • 1.3 In refresh_equipment_status_cache(), after acquiring distributed lock and before Oracle query: if force is False, read Redis equipment_status:meta:updated, compute age, skip if age < _SYNC_INTERVAL // 2

2. Wait-First Sync Worker

  • 2.1 Rewrite _sync_worker() loop from while not stop: refresh(); wait() to while not _STOP_EVENT.wait(timeout=interval): refresh() so sync thread waits one full interval before first refresh

3. Tests

  • 3.1 Add test: test_refresh_skips_when_recently_updated — mock meta:updated as 10s ago, verify Oracle not called
  • 3.2 Add test: test_refresh_proceeds_when_stale — mock meta:updated as 200s ago, verify Oracle called
  • 3.3 Add test: test_refresh_proceeds_when_force — set meta:updated as 10s ago with force=True, verify Oracle called
  • 3.4 Add test: test_sync_worker_waits_before_first_refresh — verify sync worker does not call refresh immediately on start
  • 3.5 Run python -m pytest tests/test_realtime_equipment_cache.py -x -q — existing + new tests pass
  • 3.6 Run python -m pytest tests/ -x -q — full test suite pass