Merge branch 'develop' of http://8.153.151.51:8888/team_group/model-develop into develop
# Conflicts: # schedule/src/schedule/orchestrator.py # schedule/src/schedule/worker.py
This commit is contained in:
+6
-1
@@ -3,7 +3,8 @@ FROM python:3.12-slim-bookworm
|
||||
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PYTHONPATH=/app \
|
||||
PATH="/app/.venv/bin:${PATH}"
|
||||
PATH="/app/.venv/bin:${PATH}" \
|
||||
TZ=Asia/Shanghai
|
||||
WORKDIR /app
|
||||
|
||||
RUN ( \
|
||||
@@ -24,6 +25,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
g++ \
|
||||
python3-dev \
|
||||
build-essential \
|
||||
tzdata \
|
||||
&& ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
|
||||
&& echo $TZ > /etc/timezone \
|
||||
&& dpkg-reconfigure --frontend noninteractive tzdata \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
|
||||
|
||||
@@ -13,6 +13,7 @@ dependencies = [
|
||||
"nbformat==5.10.4",
|
||||
"ipykernel==6.29.5",
|
||||
"gunicorn>=26.0.0",
|
||||
"loguru>=0.7.2",
|
||||
]
|
||||
|
||||
[tool.uv.sources]
|
||||
|
||||
@@ -13,10 +13,10 @@ post-back (see ``schedule.service.trigger_schedule``).
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
from typing import Any
|
||||
|
||||
from loguru import logger
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
|
||||
|
||||
@@ -36,13 +36,10 @@ from schedule.context import (
|
||||
TERMINAL_RUN_STATES,
|
||||
)
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SCHEDULE_RUN_REQUESTED_EVENT = schedule_event_type("schedule.run.requested")
|
||||
NODE_EXECUTE_EVENT = schedule_event_type("job.node.execute")
|
||||
NODE_FINISHED_EVENT = schedule_event_type("job.node.finished")
|
||||
|
||||
|
||||
class DispatchOrchestrator:
|
||||
"""Polls Outbox + advances DAG schedule runs.
|
||||
|
||||
@@ -133,7 +130,7 @@ class DispatchOrchestrator:
|
||||
except asyncio.CancelledError:
|
||||
raise
|
||||
except Exception:
|
||||
LOGGER.exception("database event loop failed")
|
||||
logger.exception("database event loop failed")
|
||||
await asyncio.sleep(1)
|
||||
|
||||
async def _execution_loop(self) -> None:
|
||||
@@ -145,7 +142,7 @@ class DispatchOrchestrator:
|
||||
except asyncio.CancelledError:
|
||||
raise
|
||||
except Exception:
|
||||
LOGGER.exception("node execute loop failed")
|
||||
logger.exception("node execute loop failed")
|
||||
await asyncio.sleep(1)
|
||||
|
||||
async def _claim_execution_events(
|
||||
@@ -233,7 +230,7 @@ class DispatchOrchestrator:
|
||||
.with_for_update()
|
||||
)
|
||||
if item is None:
|
||||
LOGGER.warning("execution event %s disappeared", event_id)
|
||||
logger.warning("execution event {} disappeared", event_id)
|
||||
return
|
||||
if exc is None:
|
||||
item.event_status = "published"
|
||||
|
||||
@@ -15,11 +15,12 @@ restarts.
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
from datetime import UTC
|
||||
from typing import Awaitable, Callable
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from loguru import logger
|
||||
|
||||
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
||||
from apscheduler.triggers.cron import CronTrigger
|
||||
from sqlalchemy import select
|
||||
@@ -31,8 +32,6 @@ from common.scheduler import build_sqlalchemy_jobstore
|
||||
|
||||
from schedule.context import naive_utc
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
# APScheduler's persistent SQLAlchemy job store pickles each job. A bound
|
||||
# ``CronScheduler`` method captures this instance (including SQLAlchemy engine
|
||||
# state) and therefore cannot be pickled. Keep the persisted callable at
|
||||
@@ -111,7 +110,7 @@ class CronScheduler:
|
||||
except asyncio.CancelledError:
|
||||
raise
|
||||
except Exception:
|
||||
LOGGER.exception("cron job synchronization failed")
|
||||
logger.exception("cron job synchronization failed")
|
||||
await asyncio.sleep(5)
|
||||
|
||||
async def _sync_once(self) -> None:
|
||||
|
||||
@@ -20,11 +20,11 @@ service shares the same MySQL via the Docker network).
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from datetime import UTC, datetime
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
from loguru import logger
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
|
||||
|
||||
from common.config import settings
|
||||
@@ -39,8 +39,6 @@ from schedule.orchestrator import DispatchOrchestrator
|
||||
from schedule.scheduler import CronScheduler
|
||||
from schedule.worker import NodeExecutor
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SchedulerService:
|
||||
"""Composes cron / orchestrator / worker into one bootable service.
|
||||
@@ -153,8 +151,8 @@ class SchedulerService:
|
||||
except TriggerError as exc:
|
||||
# Most likely: idempotency_key collision from a previous
|
||||
# tick in the same minute — silently no-op.
|
||||
LOGGER.info(
|
||||
"cron trigger no-op for schedule %s: %s", schedule_id, exc,
|
||||
logger.info(
|
||||
"cron trigger no-op for schedule {}: {}", schedule_id, exc,
|
||||
)
|
||||
|
||||
async def process_pending_events(
|
||||
|
||||
@@ -16,11 +16,11 @@ from __future__ import annotations
|
||||
import asyncio
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import traceback
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from loguru import logger
|
||||
from sqlalchemy import select
|
||||
|
||||
from common.db import session_scope
|
||||
@@ -43,12 +43,9 @@ from common.eventing import (
|
||||
from schedule.context import TERMINAL_NODE_STATES
|
||||
from schedule.execution import ExecutionResult, execute_artifact
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
NODE_EXECUTE_EVENT = schedule_event_type("job.node.execute")
|
||||
NODE_FINISHED_EVENT = schedule_event_type("job.node.finished")
|
||||
|
||||
|
||||
class NodeExecutor:
|
||||
"""Owns the actual execution of one schedule node (notebook / python)."""
|
||||
|
||||
@@ -376,7 +373,7 @@ class NodeExecutor:
|
||||
result_id = result_object["storage_object_id"]
|
||||
except Exception as exc:
|
||||
upload_error = f"result upload failed: {exc}"[:2000]
|
||||
LOGGER.exception("failed to upload node execution artifacts")
|
||||
logger.exception("failed to upload node execution artifacts")
|
||||
return log_id, result_id, upload_error
|
||||
|
||||
@staticmethod
|
||||
|
||||
Reference in New Issue
Block a user