diff --git a/services/task-watcher/.env.example b/services/task-watcher/.env.example new file mode 100644 index 0000000..77a9777 --- /dev/null +++ b/services/task-watcher/.env.example @@ -0,0 +1,11 @@ +# Plan-B-Infra — task-watcher + +# NAS Redis +REDIS_URL=redis://192.168.45.54:6379 + +# NAS stock holidays endpoint +STOCK_BASE_URL=http://192.168.45.54:18500 + +# 트레이딩 윈도우 (KST, HH:MM) — 이 시간대에만 queue:paused +TRADING_START=07:00 +TRADING_END=16:30 diff --git a/services/task-watcher/Dockerfile b/services/task-watcher/Dockerfile new file mode 100644 index 0000000..959ca84 --- /dev/null +++ b/services/task-watcher/Dockerfile @@ -0,0 +1,16 @@ +FROM python:3.12-slim-bookworm +ENV PYTHONUNBUFFERED=1 + +WORKDIR /app + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates tzdata \ + && rm -rf /var/lib/apt/lists/* + +COPY requirements.txt . +RUN pip install --no-cache-dir --timeout 600 --retries 5 -r requirements.txt + +COPY . . + +EXPOSE 8000 +CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "1"] diff --git a/services/task-watcher/main.py b/services/task-watcher/main.py new file mode 100644 index 0000000..00b6876 --- /dev/null +++ b/services/task-watcher/main.py @@ -0,0 +1,36 @@ +"""task-watcher FastAPI entry — health + lifespan (watcher loop spawn).""" +from __future__ import annotations + +import asyncio +import logging +from contextlib import asynccontextmanager + +from fastapi import FastAPI + +import watcher + +logging.basicConfig(level=logging.INFO, format="%(asctime)s %(name)s %(levelname)s %(message)s") +logger = logging.getLogger(__name__) + + +@asynccontextmanager +async def lifespan(app: FastAPI): + watcher_task = asyncio.create_task(watcher.watcher_loop()) + logger.info("task-watcher lifespan 시작") + try: + yield + finally: + watcher_task.cancel() + try: + await watcher_task + except asyncio.CancelledError: + pass + logger.info("task-watcher lifespan 종료") + + +app = FastAPI(lifespan=lifespan) + + +@app.get("/health") +def health(): + return {"ok": True, "service": "task-watcher"} diff --git a/services/task-watcher/requirements.txt b/services/task-watcher/requirements.txt new file mode 100644 index 0000000..1b3639e --- /dev/null +++ b/services/task-watcher/requirements.txt @@ -0,0 +1,5 @@ +fastapi==0.115.6 +uvicorn[standard]==0.34.0 +redis>=5.0 +httpx>=0.27 +pytest>=8.0