Files
analysis_claude_code/s12_cron_scheduler/images/cron-scheduler-overview.svg
2026-08-12 03:02:42 +08:00

126 lines
8.8 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 760 480" font-family="system-ui, -apple-system, sans-serif">
<defs>
<linearGradient id="header" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#1e3a5f"/><stop offset="100%" stop-color="#4f46e5"/>
</linearGradient>
<marker id="arrow" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#555"/>
</marker>
<marker id="arrow-indigo" viewBox="0 0 10 10" refX="10" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#4f46e5"/>
</marker>
</defs>
<rect width="760" height="480" fill="#fafbfc" rx="8"/>
<!-- Title -->
<rect x="0" y="0" width="760" height="44" fill="url(#header)" rx="8"/>
<rect x="0" y="36" width="760" height="8" fill="url(#header)"/>
<text x="380" y="28" fill="#fff" font-size="15" font-weight="700" text-anchor="middle">Cron Scheduler — 独立调度线程 + cron_queue 注入点</text>
<!-- Legend -->
<rect x="40" y="56" width="12" height="10" rx="2" fill="#f8fafc" stroke="#94a3b8" stroke-width="1"/>
<text x="58" y="66" fill="#64748b" font-size="10" font-weight="600">S04 工具与 Hooks</text>
<rect x="160" y="56" width="12" height="10" rx="2" fill="#eef2ff" stroke="#4f46e5" stroke-width="1"/>
<text x="178" y="66" fill="#4f46e5" font-size="10" font-weight="600">S12 新增</text>
<!-- ===== Row 1: Full Agent Loop Chain ===== -->
<!-- consume_cron_queue (S12 new, indigo) -->
<rect x="30" y="100" width="95" height="48" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="77" y="120" fill="#312e81" font-size="9" font-weight="700" text-anchor="middle">consume</text>
<text x="77" y="134" fill="#312e81" font-size="9" font-weight="700" text-anchor="middle">cron_queue</text>
<text x="77" y="144" fill="#94a3b8" font-size="7" text-anchor="middle">★ S12 注入点</text>
<line x1="125" y1="124" x2="143" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- messages 基础指令 -->
<rect x="146" y="100" width="80" height="48" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="186" y="128" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">messages</text>
<line x1="226" y1="124" x2="244" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- system prompt 基础指令 -->
<rect x="247" y="94" width="115" height="60" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="304" y="116" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">system prompt</text>
<text x="304" y="130" fill="#94a3b8" font-size="8" text-anchor="middle">SYSTEM</text>
<text x="304" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">基础指令</text>
<line x1="362" y1="124" x2="380" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- LLM call -->
<rect x="383" y="94" width="100" height="60" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="433" y="116" fill="#1e3a5f" font-size="9" font-weight="600" text-anchor="middle">LLM call</text>
<text x="433" y="130" fill="#94a3b8" font-size="8" text-anchor="middle">client.messages.create</text>
<text x="433" y="142" fill="#94a3b8" font-size="8" text-anchor="middle">model request</text>
<line x1="483" y1="124" x2="501" y2="124" stroke="#555" stroke-width="1.5" marker-end="url(#arrow)"/>
<!-- TOOL DISPATCH (expanded) -->
<rect x="504" y="88" width="220" height="72" rx="8" fill="#f8fafc" stroke="#94a3b8" stroke-width="1.2"/>
<text x="614" y="106" fill="#1e3a5f" font-size="10" font-weight="600" text-anchor="middle">TOOL DISPATCH</text>
<text x="519" y="122" fill="#2563eb" font-size="8">基础工具 → bash, read, write, edit, glob</text>
<text x="519" y="134" fill="#ea580c" font-size="8">PreToolUse → permission + log</text>
<text x="519" y="146" fill="#4f46e5" font-size="8" font-weight="600">cron → schedule_cron, list, cancel (S12)</text>
<text x="519" y="156" fill="#2563eb" font-size="8">PostToolUse → output check</text>
<!-- Loop back arrow -->
<path d="M 724 124 L 748 124 L 748 170 L 77 170 L 77 148" fill="none" stroke="#94a3b8" stroke-width="1" marker-end="url(#arrow)" stroke-dasharray="5,4"/>
<text x="400" y="183" fill="#94a3b8" font-size="9" text-anchor="middle">loop back: tool_results → next turn</text>
<!-- ===== Row 2: Cron Scheduler Thread (indigo) ===== -->
<rect x="30" y="206" width="250" height="90" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="155" y="226" fill="#312e81" font-size="11" font-weight="700" text-anchor="middle">cron_scheduler_loop独立 daemon 线程)</text>
<text x="48" y="244" fill="#4f46e5" font-size="9">wait(1s) → poll_due_jobs(datetime.now())</text>
<text x="48" y="258" fill="#4f46e5" font-size="9">匹配 → 持久化状态 → 加入队列</text>
<text x="48" y="272" fill="#6b7280" font-size="8">last_fired 防止同一分钟重复入队</text>
<text x="48" y="286" fill="#6b7280" font-size="8">模型接收 prompt 后删除一次性任务</text>
<!-- Arrow: scheduler → cron_queue -->
<path d="M 155 296 L 155 330" fill="none" stroke="#4f46e5" stroke-width="1.5" marker-end="url(#arrow-indigo)"/>
<!-- cron_queue (indigo) -->
<rect x="60" y="333" width="200" height="38" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="160" y="352" fill="#312e81" font-size="10" font-weight="700" text-anchor="middle">cron_queue</text>
<text x="160" y="364" fill="#4f46e5" font-size="8" text-anchor="middle">cron_lock 保护 · scheduler 写 · processor 交付</text>
<!-- Arrow: cron_queue → consume_cron_queue (connects to top row) -->
<path d="M 77 333 L 77 318 L 18 318 L 18 124 L 30 124" fill="none" stroke="#4f46e5" stroke-width="2" marker-end="url(#arrow-indigo)"/>
<text x="72" y="313" fill="#4f46e5" font-size="8" font-weight="600" text-anchor="middle">Agent 空闲后交付</text>
<!-- ===== Row 2 Right: CronJob + Storage ===== -->
<rect x="320" y="206" width="410" height="90" rx="8" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
<text x="525" y="226" fill="#312e81" font-size="11" font-weight="700" text-anchor="middle">CronJob + 持久化</text>
<text x="338" y="244" fill="#4f46e5" font-size="9" font-weight="600">CronJob 核心字段:</text>
<text x="455" y="244" fill="#6b7280" font-size="8">id, cron, prompt, recurring, durable</text>
<text x="338" y="260" fill="#4f46e5" font-size="9" font-weight="600">Durable → .scheduled_tasks.json</text>
<text x="560" y="260" fill="#6b7280" font-size="8">重启后 load_durable_jobs 恢复</text>
<text x="338" y="276" fill="#4f46e5" font-size="9" font-weight="600">Session-only → 内存 only</text>
<text x="530" y="276" fill="#6b7280" font-size="8">进程关闭即丢</text>
<text x="338" y="292" fill="#ef4444" font-size="9" font-weight="600">⚠ 进程关闭 = 调度停止(不是 OS 级 crontab</text>
<!-- ===== Row 3: 5-field cron reference ===== -->
<rect x="30" y="390" width="700" height="76" rx="6" fill="#f8fafc" stroke="#e2e8f0" stroke-width="1"/>
<text x="60" y="412" fill="#1e3a5f" font-size="11" font-weight="600">五段式 Cron 表达式</text>
<rect x="60" y="422" width="52" height="16" rx="3" fill="#eef2ff" stroke="#4f46e5" stroke-width="1"/>
<text x="86" y="434" fill="#4f46e5" font-size="9" text-anchor="middle">*</text>
<rect x="118" y="422" width="52" height="16" rx="3" fill="#eef2ff" stroke="#4f46e5" stroke-width="1"/>
<text x="144" y="434" fill="#4f46e5" font-size="9" text-anchor="middle">*</text>
<rect x="176" y="422" width="52" height="16" rx="3" fill="#eef2ff" stroke="#4f46e5" stroke-width="1"/>
<text x="202" y="434" fill="#4f46e5" font-size="9" text-anchor="middle">*</text>
<rect x="234" y="422" width="52" height="16" rx="3" fill="#eef2ff" stroke="#4f46e5" stroke-width="1"/>
<text x="260" y="434" fill="#4f46e5" font-size="9" text-anchor="middle">*</text>
<rect x="292" y="422" width="52" height="16" rx="3" fill="#eef2ff" stroke="#4f46e5" stroke-width="1"/>
<text x="318" y="434" fill="#4f46e5" font-size="9" text-anchor="middle">*</text>
<text x="60" y="455" fill="#94a3b8" font-size="8">分钟</text>
<text x="130" y="455" fill="#94a3b8" font-size="8">小时</text>
<text x="194" y="455" fill="#94a3b8" font-size="8"></text>
<text x="254" y="455" fill="#94a3b8" font-size="8"></text>
<text x="310" y="455" fill="#94a3b8" font-size="8">星期</text>
<text x="380" y="434" fill="#475569" font-size="9">*/5 * * * * → 每 5 分钟</text>
<text x="380" y="450" fill="#475569" font-size="9">0 9 * * 1-5 → 工作日 9:00</text>
<text x="560" y="434" fill="#475569" font-size="9">0 9 * * * → 每天 9:00</text>
<text x="560" y="450" fill="#475569" font-size="9">支持: *, */N, N, N-M, N,M,...</text>
</svg>