Skip to content
Back to skills

2480 Design 574ae00a

ASecurity

当前系统有两套互相独立的调度机制,且均未真正生效:

  • 9 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 31, 2026
developmentpythongoapi

Works with

  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned May 31, 2026

npx -y skills add tools-only/X-Skills --skill 2480-design_574ae00a --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2480 Design 574ae00a?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2480 Design 574ae00a
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2480-design-574ae00a/badge)](https://www.skillsdirectory.com/skills/tools-only-2480-design-574ae00a)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
## Context

当前系统有两套互相独立的调度机制,且均未真正生效:

| 调度器 | 文件 | 技术栈 | 状态 |
|--------|------|--------|------|
| `DataSyncScheduler` | `tasks/data_sync_scheduler.py` | `schedule` 库 + threading | 默认 `enabled=False`;应用启动时未调用 `start()`;需手动 API 触发 |
| `ScheduleService` | `modules/datamanage/schedule_service.py` | 无定时机制 | 仅提供 `trigger_now()` 手动触发;有完善的执行记录/重试/停止能力 |

此外 `enhance-data-management` 遗留了"每日16:00缺失检测(APScheduler)"的未完成任务。

### 架构问题

1. **旧调度器职责过窄**:`DataSyncScheduler` 直接调用 `sync_task_manager.create_task()`,绕过了 `ScheduleService` 的依赖排序、执行记录、插件级开关等能力。
2. **新调度服务无定时驱动**:`ScheduleService` 功能完善但没有定时引擎驱动,只能被 API 手动触发。
3. **全量同步无差别重跑**:当用户触发全量同步时,所有数据从头拉取,没有先检测缺什么再精准补数的智能策略。
4. **启动时无自动调度**:`http_server.py` 的 `lifespan` 只启动了 `SyncTaskManager`,未启动任何定时调度器。

## Goals / Non-Goals

### Goals
- 统一为一套调度系统,以 `ScheduleService` 为核心,APScheduler 为定时引擎
- 应用启动时自动启动定时调度,无需手动 API 触发
- 实现智能补数:每日调度前先检测 DB 缺失,精准补数而非全量重跑
- 实现每日 16:00 定时缺失检测任务
- 删除旧版 `DataSyncScheduler` 和 `schedule` 库依赖

### Non-Goals
- 不实现分布式调度(单进程 APScheduler 即可)
- 不修改现有的任务执行引擎(`SyncTaskManager` + Redis Queue)
- 不修改前端调度配置 UI(复用现有 `ScheduleService` 的 API)
- 不实现自动修复(仅检测+创建补数任务,不做数据纠正)

## Decisions

### Decision 1: 以 ScheduleService 为核心,APScheduler 为定时引擎

**选择**:保留 `ScheduleService` 作为核心调度服务,引入 APScheduler `BackgroundScheduler` 作为定时触发引擎。

**替代方案**:
- A) 保留旧版 `DataSyncScheduler` + `schedule` 库 → 功能过于简单,无法支持智能补数和执行记录
- B) 使用 Celery Beat → 过重,引入 broker 依赖,当前规模不需要
- C) 使用 `asyncio` 定时循环 → 需要手动管理任务调度,不如 APScheduler 成熟

**理由**:`ScheduleService` 已有完善的插件级开关、依赖排序、执行记录、重试/停止等能力。APScheduler 轻量且功能完备(cron 触发、misfire 处理、持久化支持),是 Python 生态中成熟的定时调度库。

### Decision 2: 统一调度器 UnifiedScheduler

新建 `tasks/unified_scheduler.py`,职责:

```
UnifiedScheduler
├── 定时任务1: daily_sync_job (默认 18:00)
│   └── 调用 ScheduleService.trigger_now(is_manual=False)
├── 定时任务2: missing_data_check_job (默认 16:00)
│   └── 调用 data_manage_service.detect_missing_data()
├── 定时任务3: smart_backfill_job (默认 18:30, daily_sync 完成后)
│   └── 检测缺失 → 判断策略 → 创建 backfill 任务
└── 配置同步: 从 ScheduleService.get_config() 读取时间/频率/开关
```

### Decision 3: 智能补数策略

在 `ScheduleService.trigger_now()` 中增加前置缺失扫描步骤:

```
trigger_now(smart_backfill=True)
  ├── Step 1: 调用 detect_missing_data() 获取各插件缺失日期
  ├── Step 2: 对每个启用的插件
  │   ├── 无缺失 → 创建 incremental 任务(仅当天)
  │   ├── 缺失 ≤ 3天 → 创建 backfill 任务(精准补缺失日期)
  │   └── 缺失 > 3天 → 标记为异常,记录告警日志,不自动全量
  └── Step 3: 记录执行记录,含补数详情
```

**阈值配置**(可在 `runtime_config.json` 的 `scheduler` 段中配置):
- `auto_backfill_max_days`: 3(自动补数最大天数,超过则需人工干预)
- `smart_backfill_enabled`: true(是否启用智能补数)

### Decision 4: 应用启动时自动启动

在 `http_server.py` 的 `lifespan` 中,`SyncTaskManager.start()` 之后,自动启动 `UnifiedScheduler`。调度器读取 `ScheduleService.get_config()` 中的 `enabled` 开关,如果为 `true` 则注册定时任务。

**启动顺序**:
1. SyncTaskManager(延迟 8s)
2. UnifiedScheduler(延迟 15s,确保 SyncTaskManager 就绪)

### Decision 5: 配置统一管理

所有调度配置统一存储在 `runtime_config.json` 的 `scheduler` 段:

```json
{
  "scheduler": {
    "enabled": true,
    "execute_time": "18:00",
    "frequency": "weekday",
    "skip_non_trading_days": true,
    "missing_check_time": "16:00",
    "smart_backfill_enabled": true,
    "auto_backfill_max_days": 3
  }
}
```

现有的 `ScheduleService.update_config()` API 继续作为配置入口,`UnifiedScheduler` 监听配置变更并动态调整定时任务。

## Risks / Trade-offs

| 风险 | 缓解措施 |
|------|----------|
| APScheduler 进程内运行,重启后定时任务丢失 | 启动时自动重新注册所有任务;使用 `misfire_grace_time` 处理错过的任务 |
| 智能补数误判(如数据源本身无当天数据) | 设置 `auto_backfill_max_days` 阈值,超过阈值不自动补数;增量同步使用交易日历校验 |
| 删除旧调度器可能影响依赖旧 API 的代码 | 旧调度器 API(`/scheduler/start`、`/scheduler/status`)重定向到新系统;保留 `get_data_sync_scheduler()` 函数作为兼容层 |
| 缺失检测和补数同时运行造成资源竞争 | 16:00 只做检测;18:00 做同步+补数;时间错开避免竞争 |

## Migration Plan

1. **Phase 1**:新增 `UnifiedScheduler`,同时保留旧版 `DataSyncScheduler`(标记为 deprecated)
2. **Phase 2**:修改 `http_server.py` 启动 `UnifiedScheduler`,旧调度器 API 返回 deprecated 提示
3. **Phase 3**:确认新调度器稳定后,删除 `DataSyncScheduler` 和 `schedule` 库依赖

## Open Questions

1. 是否需要在前端增加"智能补数"的独立入口按钮?(建议:Phase 2,先通过调度器自动执行)
2. 是否需要将缺失检测结果推送到通知系统(如邮件/webhook)?(建议:Phase 2)

Files in this skill

  • README.md898 B
  • skill.md6.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.