Commit Graph

4 Commits

Author SHA1 Message Date
ThearchyHelios 11d3b24592 测试:conftest 把 AGENTLAB_SECRET_KEY、AGENTLAB_SCHEDULER 挪到任何 app.* 导入之前(PostgreSQL 分支先导入 app.db.base 装连接池,settings 那一刻就定下来了,以前单独跑 test_schedule_events_api.py 在 PostgreSQL 上 scheduler_on 是 True);test_trigger_options 按名字(q)查要核对的那几个对象,不再指望一页 100 个装得下同一个库里别的测试建的工作流和数据源 2026-10-19 14:06:20 +08:00
ThearchyHelios 656a550408 数据事件触发按复核意见修正:途经驳回、去抖积压、source.changed 补写、按期次分窗口、补算缺省不认、示例出口字段同一套过滤
M1 途经驳回(编排者已定):outbox.stage_run_finished 收可选的 rejected_via(缺省 None 即没途经驳回),事件内容带 rejected 和
rejected_via,说法接「(途经驳回)」,模板有 {{ event.rejected }}(true / false)。触发条件缺省只认没途经驳回的,trigger 加
include_rejected(界面「也认途经驳回的」勾选,说明照实写)。runner._finalize 把 _rejected_via(state) 传进来那一下留给编排者
在合并时接(runner 的 _rejected_via 在 W1-b 的分支上);测试直接调 stage_run_finished 传参覆盖。

C1 去抖积压:以前一拍只走一个窗口,积压时后面的越等越久、全过了宽限,而且每个窗口各记一条跳过,原因还说调度没在跑。
现在 _drain 按发生时刻把等着的事件切成窗口,一拍里把到点的处理完(最多 100 个窗口、5000 条);排在前面已过补发宽限的合成
一条 skipped_misfire(合并了几次事件、几个窗口、时间跨度,上传表格另写合掉的期次),派给任务时已经晚于宽限才说「调度未运行」,
否则照实说积压;宽限内的照常发起(照重叠规则跳过的照实记)。

C3 source.changed:这一处确实没法和变化记录同一个事务(一次探查、剖析的变化分好几批落库,一批只触发一次要等任务结束才知道),
改成说实话:models_triggers 的说明写清哪两种同事务、哪一种不是。trigger_events 加 dedupe_key(source.changed:<任务号>,唯一),
emit_source_changed 按它去重;调度的一拍(刚起的服务第一拍就补,之后每 10 分钟)由 backfill_source_changes 按任务号补写:2 天内
测到、还开着的要处理级变化,任务已结束却没有事件的补一条。分组在 Python 里做,不用各库写法不同的 JSON 取值。

C4 按期次分窗口:triggers.window_key 让上传表格按期次各自成窗口,9 月、10 月连着启用各有各的触发;同一期的重传照旧合并。
两个窗口结束在同一刻时后一个挪 1 微秒,fire_at 不撞唯一约束。

C5 应用补算:workflow.finished 缺省不认 app_backfill 发起的(升版补算连发好几条、各是某一期的历史输入),trigger 加
include_backfill(界面「也认应用补算的」),选了「只认应用补算」时本来就认;说法写「途经驳回、应用补算的不算」。

C6 示例出口字段:triggers.outputs_of 一处过滤「_」开头的键,真派发、预览、立即运行共用;示例事件也按 matches 跳过缺省不认的
途经驳回、应用补算,取合条件的最近一次。

测试:新加 test_schedule_events_review.py(11 项,先写、先看着失败;去掉 matches 的驳回判断、把每拍窗口数改回 1 回跑,对应用例
各自失败),test_schedule_events_api.py 加一项「也认」两项经接口存取和说法;check-schedules 加「上游工作流的请求体」一段、纯函数
几条、触发历史里合并跳过那一行的夹具。
验证:后端全量 14479 通过;tsc、check-copy;check-schedules 447 项、check-runs 327 项通过(拿锁、--stacks 1)。
2026-10-18 18:09:20 +08:00
ThearchyHelios 3f1eeff841 数据事件触发(界面):定时页新建时选「定时 / 事件触发」、事件那一节、列表与详情的等待状态、触发历史和运行详情的「由事件触发」
做了什么:
- 新建定时任务(目标是工作流时)先选怎么触发:定时 / 事件触发(TriggerEditor 的 TriggerModePicker);修改时只读地写出触发方式、
  说明建好之后不能改。选了事件触发,频率那一节换成事件(EventSection):三种事件、对象下拉(能选哪些、不能选的原因由新接口
  GET /api/schedules/trigger-options 给,界面照着画、选不了的置灰并写原因)、上传表格的期次(只认新增的一期)、上游工作流的
  只认应用 / 只认来源和触发链上限的说明、去抖、时区;换事件种类时对象和过滤清掉。
- 预览按一次事件渲染输入(对象最近一次的事件,没有时照实说是示例值),不列触发时间;变量按事件种类取(api.schedules.eventVariables),
  插得进 {{ event.* }};请求体带 trigger_kind、trigger,cron 交空串;修改时只交改了的触发条件。model.ts 加 TriggerForm 与
  triggerBody / switchEvent,表单问题里事件触发不查频率、要求选对象;服务端 422 指 trigger 时落到事件那一节。
- 列表、详情:「事件触发」标签,频率处写触发说明;下次运行写在等什么(去抖中收到几次、何时合成一次触发;有事件等待派发;调度
  没开时照实说不会派发)。触发历史:类型「事件」,写「由事件触发:…」、合并了几次、第几层;立即运行按最近一次事件发起的写
  「按事件:…」并标示例值。运行详情页头写「由事件触发:…(定时任务「X」)」(RunDetailView 只多传一个 trigger 属性),立即运行
  按事件发起的写「立即运行定时任务「X」,按事件:…」,不说成由事件触发;应用页印章同样不算。
- 文案进 lib/termsTrigger.ts;SCHEDULE_TEXT 只补触发类型「事件」和「还需处理」里的「触发事件」。立即运行按示例事件的说法
  不再在服务端加「(示例值)」后缀,是不是示例值看 real。

为什么:总方案 §4 要求定时页能建事件触发的任务、列表 / 详情 / 触发历史 / 记录页照实显示;能不能选、为什么由服务端判,界面不放逻辑。

验证:tsc、check-copy;check-schedules 加纯函数一段(表单 ⇄ 请求体)和三段页面(新建的请求体、列表 / 详情 / 触发历史、运行详情
页头,含 390px 浅色),假接口加了触发选项、事件预览、事件变量、事件触发任务的夹具,写请求断言请求体;原有各段照过;check-runs 照过。
2026-10-18 16:11:55 +08:00
ThearchyHelios a1ab3247f9 数据事件触发(后端):待派发事件表、调度循环派发与去抖、防环、{{ event.* }} 模板变量、接口收 trigger_kind / trigger
做了什么:
- 新表 trigger_events(待派发事件)、trigger_deliveries(一个事件派给一个定时任务、等去抖),放在 db/models_triggers.py,
  models.py 末尾整模块导入。事件在发生处、和那件事同一个事务里写一行:上传表格按期累积的新一期启用(table_versions 的
  publish_build / publish_snapshot 切指针那一下,移除、作废、回滚不算)、正式运行成功收尾(runner._finalize 写终态的事务里
  加两行调用 outbox.stage_run_finished)、探查 / 剖析新记了要处理的变化(source_changes.notify_after_job,一个任务一条)。
  发生处不发起运行:事务边界、重复与重启都在派发这边说清,也为第 2 波多进程做准备(认领靠条件 UPDATE)。
- scheduler/outbox.py:调度循环每一拍(fire_due 之后)派发:pending 事件条件 UPDATE 认领成 routed,同一事务里给合条件、启用着的
  事件触发任务写 delivery;窗口从最早一条的发生时刻起算 debounce_s(缺省 60 秒),过了就合成一次触发,内容取最新的那条,
  fire_at 取窗口结束的时刻(同一窗口永远同一个时刻,触发记录唯一约束兜住重复派发);照 fire_once 发起正式运行,ScheduleFire
  kind=event、inputs 写 {event: 事件说明, inputs: 渲染出的输入};上一次没结束记 skipped_overlap;派发太晚(超出补发宽限)
  记 skipped_misfire;任务停用、改了触发条件时等着的标 dropped。AGENTLAB_SCHEDULER 关着时没有这一拍,事件留着,接口照实说。
- scheduler/triggers.py:三种事件的触发条件(table.version 可选只认新增的一期;workflow.finished 可选只认某个应用 / 某种来源;
  source.changed)、核对对象(表格是按期累积的上传表格、上游工作流已发布、应用在)、说法、{{ event.* }} 变量(table、version、
  period、activated_at;workflow_id、run_id、outputs.<字段>;source、counts)、示例事件(预览、立即运行用对象最近一次真实的事件)、
  防环:保存时查 workflow.finished 串成的环(停用的也算,A→B→A、自己触发自己都拒,422 写出经过的工作流),运行时按 origin 里的
  触发深度兜底(超过 5 层记未能发起)。
- service:fire_once / _fire_workflow 接事件(模板按事件种类校验、渲染 {{ event.* }},运行来源 origin.trigger 带种类、对象、
  事件 id、深度、经过的运行和一句说法);check_template / render_inputs / variables 加可选的 event 参数,cron 任务一字不变。
- api/schedules.py:收 trigger_kind(cron 缺省)/ trigger,event 时目标只能是工作流、cron 存空串、下一次触发为空;返回带
  trigger_kind、trigger、trigger_text(也是 description_text)、trigger_state(几条事件在等、去抖到何时、调度开没开);触发
  历史带 event;预览按示例事件渲染;变量清单按事件种类给;新增 GET /api/schedules/trigger-options(各事件能选的对象及不能选的
  原因、来源、应用,界面不自己判);立即运行按示例事件发起;触发方式建好之后不能改。Webhook 照旧可配,通知写「事件触发」那一行。
- 应用页印章的来源(apps/resolve._from_text)照实写「由事件触发:…」。

为什么:总方案 §4 已拍板接这三种事件、不接口径发布,一套定时机制(X4);派发放在调度循环里而不是发生处,事务和重复都说得清。

测试:test_schedule_events.py(三种事件各触发一次、去抖合并与窗口外另起、重叠跳过、停用 / 改条件丢弃、调度关着时事件留着、
超出宽限、触发链深度与上限、模板校验与渲染、期次写法、通知、印章)、test_schedule_events_api.py(建、核对、防环、改、预览、
变量、立即运行、触发状态、可选对象);test_schedules_api.py 的约定键集合补上新加的几项。
2026-10-18 15:53:08 +08:00