Context
PR #639 의 `generate_ig_carousel` 노드가 PIL 로 1024x1280 6슬라이드 + carousel preview grid 합성. 한 article 처리 시 메모리 점유 약 50MB 추정 (이미지 download + PIL canvas + intermediate buffers).
현재 ARQ worker config:
```python
packages/ai-server/src/managers/queue/worker.py
max_jobs = 1 # 동시 실행 1개
job_timeout = 600 # 10분
```
`max_jobs=1` 이라 현재는 안전. 향후 multi-worker 또는 max_jobs 늘릴 때 메모리 모니터링 필요.
Proposed approach
- observability:
- `prometheus_client` Gauge `ig_carousel_node_memory_mb` 추가 (resident set size 측정)
- `logger.info` 에 노드 종료 시 메모리 사용량 dump (debugging)
- safety:
- PIL Image 객체 명시적 `.close()` 또는 `with Image.open(...) as img:` 패턴 강제 (현재는 GC 의존)
- tempfile.TemporaryDirectory 정리 보장 (이미 with 블록 사용 중)
- limits:
- worker container 의 memory limit (Fly.io / docker) 가 PIL job 동시 실행 시 OOM 안 나는지 확인
- load test:
- 10 article 연속 처리 시 메모리 leak 없는지 (잘림 PNG / partial download case 포함)
Acceptance
- 노드 종료 후 메모리 사용량 baseline 으로 복귀 (RSS delta < 5MB)
- max_jobs=2 또는 4 로 늘려도 OOM 없음
- Grafana / 로그에서 ig_carousel job 별 메모리 사용량 추적 가능
References: PR #639
Context
PR #639 의 `generate_ig_carousel` 노드가 PIL 로 1024x1280 6슬라이드 + carousel preview grid 합성. 한 article 처리 시 메모리 점유 약 50MB 추정 (이미지 download + PIL canvas + intermediate buffers).
현재 ARQ worker config:
```python
packages/ai-server/src/managers/queue/worker.py
max_jobs = 1 # 동시 실행 1개
job_timeout = 600 # 10분
```
`max_jobs=1` 이라 현재는 안전. 향후 multi-worker 또는 max_jobs 늘릴 때 메모리 모니터링 필요.
Proposed approach
Acceptance
References: PR #639