Commit Graph

8 Commits

Author SHA1 Message Date
ThearchyHelios eb9af51abb 复核 R-b14(PostgreSQL 单进程墙钟一跳就隔离自己):取得到计入休眠的钟(SLEEP_AWARE)时 stale() 只看它,墙钟只在取不到时当后备(两只里走得多的那只);两只钟对不上(jumped)不再直接隔离,先续一次租——续租那一句按库的时钟核对「自己的租约还没过期」,以它为准:续上了只记一条日志照常,续不上才隔离。README「多进程」补一句:库服务器自己的时钟往前跳超过一个租约时所有进程一起隔离、怎么恢复,往回跳时真没了的进程要多等,本机墙钟跳了不隔离。补测试:墙钟往前往后跳一小时不算续晚了、只算对不上,计入休眠的钟走过两个租约照样算,取不到时墙钟当后备;PostgreSQL 单进程墙钟 ±1 小时续租照常续上、不隔离,真过期仍隔离;执行到一半墙钟 ±1 小时,运行照常跑完、世代不变(改前的写法往前跳那条不过) 2026-10-19 15:07:17 +08:00
ThearchyHelios 1e6f0554fe 复核 R-b10(隔离换身份后旧身份的名额、请求没人收拾):要名额时把当时的身份记在 holder 上,放的时候按它删,换了身份也删得到;新身份登记上之后收拾旧身份(tidy_retired)——它的执行都已停下、写不了了,不必等它的租约过期:删掉它的登记(发 gone,别的进程马上按属主不在了接手它认领的运行、任务)、它占着的运行名额和同源队的位置,交出它拿着的当班租约,发给它的请求转到新身份名下照办,照实记一条日志;停止请求对不在本进程执行的运行也照停止的规矩办(cancel 自己看属主:转给正在执行它的进程、属主不在了就接手放弃、停在断点上的收成 cancelled)。补测试:拿着名额时换了身份照样放得掉(改前的写法这条不过);新身份登记上之后旧身份的登记、名额、队里的位置、当班租约都收拾掉,转过来的停止请求把停在断点上的那次运行收成 cancelled 2026-10-19 14:36:19 +08:00
ThearchyHelios ba22b82b3d 复核 R-b9(Fenced 打到不该打的地方):check() 续晚了谁问到都隔离,但只对绑定了世代的执行(运行的一段执行、后台任务)抛 Fenced,HTTP 处理、调度那一拍、进程间请求问到时只隔离不抛;调度循环、心跳、办进程间请求也接住 Fenced;续租的任务不再因为一下出错就退出——续租、隔离之后重新登记都包住,照实记日志、退避着重试(最长一个租约时长)。隔离时马上换身份(之后新建的行记新身份),新身份登记上之前心跳不争当班、不接手,新开始的运行、后台任务在 fence.ready() 上等(最多一个租约时长,等不到就不开始,那几行由别的进程按属主不在了处理,这边同时放弃这个一直没登记上的身份、再换一个)。日志写出新旧完整身份。补测试:没绑定的调用者只隔离不抛、绑定在隔离之前的抛、新身份登记上之前 ready 等着;调度循环被 Fenced 打到一拍之后照常;重新登记先被版本守卫拦、再碰上库连不上,续租任务都不退出,登记上之后照常续租 2026-10-19 14:33:45 +08:00
ThearchyHelios 7fcce90f95 复核 R-b7(休眠、时钟偏差下隔离失灵):租约改用库的时钟——续租、登记写 lease_until = 库的 clock_timestamp() + 租约,判活、清理过期登记、版本守卫看谁活着都比库的时钟,调度当班的租约同样按库的时钟接班、续租,本地判还当不当班改看计入休眠的单调钟,机器之间墙钟差多少都不起作用;隔离改用计入休眠的钟(Linux CLOCK_BOOTTIME,macOS clock_gettime(CLOCK_MONOTONIC),取不到退回 monotonic),并且一律同时比墙钟,两只钟里走得多的那只说过了一个租约就算续晚了;续租时两只钟差出一个租约(墙钟跳了、休眠没计)也隔离;续租那一句带上「库里自己的租约还没过期」的条件,过期了或者登记不见了就不再续这个身份、隔离换身份(以前登记不见了是用旧身份重新登记)。补测试:单调钟不走而墙钟过了两个租约、墙钟往回拨,都算续晚了;本机墙钟快一小时,别的进程照样活着、当班租约抢不走;库的时钟过了自己的租约时续租不续、隔离一次 2026-10-19 14:27:55 +08:00
ThearchyHelios 35ab097b45 复核 R-b1(卡住但没死的进程被当成没了):续租约挪到单独的任务、专用连接(不走连接池,不被同一拍别的活拖住);进程间请求另起任务办,不在心跳里等收尾;新增 cluster/fence 自我隔离——离上次续上租约超过一个租约时长,或者这段执行属于上一次隔离之前,执行在写事件、写断点、开审批、发外部写入、后台任务写库之前就停手(Fenced 是 BaseException,节点里的 except Exception 拦不住),续租时发现续晚了就隔离:停掉手上的运行和后台任务、不写终态,换一个身份重新登记;运行收尾先占住那一行、属主不是自己就不写;别的进程按租约过期再多等一个租约时长才算不在了(两边中间留一段);run_events 的 (run_id, seq) 改成唯一索引(存量库先数重复,有就照实记日志、这一次不建,不让启动失败)。补测试:卡住期间被接手之后不盖终态、不写事件、序号不重;被接手的那次在别处接着跑完只结束一次、后面那一步只跑一次;收尾按属主写;撞号被库拒绝;多进程端到端加 6b、6c(真 SIGSTOP / SIGCONT) 2026-10-19 13:15:56 +08:00
ThearchyHelios 01af07b193 出具、按需视图的每日上限改成先占额度再发起(用户拍板):新增 cluster/quota——额度记在库里(rate_counters 按名字 + 本地日期一行),占一份是一句带条件的 UPDATE(没到上限才加一),两种库上都是原子的,这一天第一次占按库里已有的记录起算,发起被拒或出错就退回。出具去掉全站一把锁,只留同一(运行、工作流、版本)的去重锁,几份不同的出具可以同时发起;按需视图的锁缩回按缓存键(视图 + 参数)去重,每日上限改用这个应用的额度。补测试:20 个协程同时占正好到上限、按已有记录起算、退回再占;两个进程同时占正好到上限;三份不同的答案同时出具正好到上限、多出来的回 429 2026-10-19 12:57:38 +08:00
ThearchyHelios 1acf960312 多进程端到端验收:scripts/test-multiprocess.sh 用本机 postgres:16 起临时库,tests/test_multiprocess_e2e.py(缺省跳过,AGENTLAB_MULTIPROCESS_E2E=1)在上面起两个 uvicorn 工作进程,用演示模型跑七个场景——两个进程都登记、一个当班;运行由接到请求的进程认领,另一个进程上的流收得到实时事件和流式增量,同一个审批决定同时发给两边只执行一次,两边事件流不重不漏、封存核对得上;跨进程停止;定时只触发一次;全站一个名额时评测的作答运行排着队,后来的问数据运行先拿到名额;两个进程同时记同一本每日账不越过上限;强杀一个进程后在跑的运行被照实标中断、停在审批上的照常在另一个进程上批完、当班交接。顺带修:等名额时被停止也照实收成已取消(以前停在排队中);当班的本地余量不超过租约的四分之一(租约调短时一直不当班);启动清理上传半成品时没有别的活着的进程就全清;文件锁守卫的几项测试只在 SQLite 跑;问数据事件日志清理那一拍不带时刻时按现在算 2026-10-19 12:03:35 +08:00
ThearchyHelios 87f0d62f9b 多进程协调(W2-b)第一步:新增 app/cluster——工作进程在库里登记、心跳续租约(属主随进程,进程没了它认领的行一起到期),调度当班的租约,发给属主进程的停止 / 记事件请求,PostgreSQL 的 LISTEN/NOTIFY 叫醒,跨进程的互斥锁(咨询锁),SQLite 单进程守卫(第二个进程拒绝启动);运行、问数据一轮、起草 / 剖析 / 探查 / 评测 / 影子起草、文档、发布单记 owner,启动整理改成只接手属主不在了的行,当班进程隔一会儿再接手一次;运行的并发名额改成库里按交互 / 应用 / 定时 / 系统四类发(各有全站上限和优先级,设置里可调),替掉进程内的信号量;同源队记在库里;运行停止、记事件跨进程交给属主;运行事件、问数据事件跨进程转发(库里按 seq 追,不落库的流式增量和保活心跳只转给在看的进程);每日花费账先占住那一行再读写;访问密钥限流、登录失败计数在 PostgreSQL 时记在库里;登录设置、对外地址、向量模型、能力快照、数据源连接池、应用页面缓存跨进程失效;上传版本库、记录表、按需探查、出具、召回、补算、按需视图、个人刷新、定时发起的锁换成跨进程的锁 2026-10-19 11:40:33 +08:00