- 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>
1.4 KiB
1.4 KiB
1. Freshness Gate
- 1.1 Add module-level
_SYNC_INTERVAL: int = 300variable inrealtime_equipment_cache.py - 1.2 In
init_realtime_equipment_cache(), set_SYNC_INTERVALfromconfig.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: ifforceis False, read Redisequipment_status:meta:updated, compute age, skip if age <_SYNC_INTERVAL // 2
2. Wait-First Sync Worker
- 2.1 Rewrite
_sync_worker()loop fromwhile not stop: refresh(); wait()towhile 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— mockmeta:updatedas 10s ago, verify Oracle not called - 3.2 Add test:
test_refresh_proceeds_when_stale— mockmeta:updatedas 200s ago, verify Oracle called - 3.3 Add test:
test_refresh_proceeds_when_force— setmeta:updatedas 10s ago withforce=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