Commit Graph

1055 Commits

Author SHA1 Message Date
ThearchyHelios 68da5795b8 合入 nr8/d 的复核修复 R-d1–R-d6(内置库按部署编号与记下的名字认、起不来的库容器回退后不再重启、卸载只删自己建的网络、升级备份含记录表、dev.sh 读 .env 的写法与数据目录、sudo 下的 ~ 按 SUDO_USER 展开) 2026-10-19 16:19:44 +08:00
ThearchyHelios 71b83195ac 复核 R-d6(sudo ./deploy.sh 时 DATA_DIR=~/… 展开成 /root 下):有 SUDO_USER 时 ~ 按它的家目录展开(getent passwd 取,取不到退回 $HOME),「不能是家目录本身」也按它查;install、upgrade、migrate 开头打印展开后的绝对路径(DATA_DIR 用了 ~ 时注明 ~ 是哪个目录)。deploy/README 写一句(agentlab.env 已有的行没动)。假 docker 单测:SUDO_USER 的家目录、取不到时退回 $HOME 2026-10-19 16:15:21 +08:00
ThearchyHelios 49118eeef2 复核 R-d5(dev.sh 读 .env 不全):认 KEY = value(等号两边有空格,和后端的 dotenv 一致);放开发库密码的数据目录也照「环境变量 > backend/.env > .env」读 AGENTLAB_DATA_DIR,相对路径按后端的工作目录 backend/ 算,.postgres-dev 落在后端实际用的数据目录下。单测:等号带空格、export、行尾注释、backend/.env 优先、相对的数据目录 2026-10-19 16:13:35 +08:00
ThearchyHelios 65d35f6c97 复核 R-d4(升级前的 SQLite 备份只拷了应用库和断点库):填报的记录表 records/**/*.db 也用 SQLite 的备份接口拷进同一份备份,相对路径照旧,目录 0700、文件 0600;库在 PostgreSQL 时不做这份(记录表跟着整目录备份)。deploy/README 写清这份备份含什么、不含什么(上传原件和版本库、工件库、附件、知识库、沙箱工作区、.secret_key 要整目录备份),恢复步骤加上记录表 2026-10-19 16:12:07 +08:00
ThearchyHelios 676c546cbb 复核 R-d3(卸载时不看网络是不是自己建的就删):建网络时打上 agentlab.role=network 和这个部署的 agentlab.deployment 标签;卸载时标签和部署编号对得上才删,早先建的没有标签的按数据目录里记着的网络名认,都不是就只打印一句、不删。假 docker 单测:别人的同名网络、没标签又没记着的不删,自己的(含早先没标签的)删掉 2026-10-19 16:10:25 +08:00
ThearchyHelios 8b5b7f86b2 复核 R-d2(起不来的库容器回退后还在一遍遍重启):stop_pg 对在跑的和在重启的(restarting)都停;migrate-to-postgres 回退时先 docker update --restart=no 再停,再起库时(start_pg)恢复 --restart unless-stopped;./deploy.sh stop 用同一个函数一起好。假 docker 单测:镜像起不来、容器一直 restarting 时回退后停在 exited、重启策略是 no,换回能起的镜像重跑照常,stop 也停得下在重启的 2026-10-19 16:09:19 +08:00
ThearchyHelios 35bb634460 复核 R-d1(认库是不是自己的不够严):状态文件第一次记 migrating / builtin 时一并记下库的容器、数据卷、网络的名字和一个部署编号(app.ops state --container/--volume/--network,--get 取一项),库容器、数据卷带 agentlab.deployment=<编号> 标签(数据卷先 docker volume create 再起容器)。agentlab.env 的名字和记着的对不上就拒绝(install、upgrade、migrate、起停、状态、卸载都先核对),早先只记了模式的状态文件按当时的名字补记、照实打一行;库容器要标签和部署编号对得上(没编号的老容器看挂的密码文件是不是这个数据目录的)、挂的数据卷就是 POSTGRES_VOLUME,清空库之前数据卷还要带这个部署的编号(没编号的不清空);卸载碰上别人的库容器只提示不删。假 docker 单测:同一台机器上两个部署,改名指向对方、老状态文件补记之后,对方的库不被清空、不被删、不被重建 2026-10-19 16:07:03 +08:00
ThearchyHelios badcc2f6aa README:编排完善第 2 波的升级说明(缺省仍是 SQLite 单进程、新列与运行事件唯一索引、数据目录标记;应用库可换 PostgreSQL 与导入、deploy.sh 内置库与 migrate-to-postgres、dev.sh --postgres;PostgreSQL 下多进程、升级要先停全部进程;运行按类别排队与交互留底;升级前自动备份、restart 缺省只重启服务;bubblewrap 沙箱不再继承环境变量;循环里的子工作流编号与幂等键;问数据心跳不落库与事件日志清理、接手时重新核对身份;行序不定;驳回去向的说法) 2026-10-19 15:46:49 +08:00
ThearchyHelios af919a88aa 合入编排完善第 2 波(集成):应用库可移植到 PostgreSQL(nr8/a)、第 1 波与下一轮遗留收口(nr8/l)、多进程协调(nr8/b)、部署时 PostgreSQL 一起起(nr8/d) 2026-10-19 15:45:16 +08:00
ThearchyHelios d117237bbc 配置模板补上 PostgreSQL 和多进程的几项:.env.example 的应用库一节分成应用库、连接池、PgBouncer、多进程、开发用 PostgreSQL 五组,补上 AGENTLAB_DATABASE_DIRECT_URL、AGENTLAB_DB_PGBOUNCER、AGENTLAB_DB_POOL_TIMEOUT、AGENTLAB_DB_POOL_RECYCLE、AGENTLAB_DB_STARTUP_TIMEOUT、AGENTLAB_WORKERS、AGENTLAB_WORKER_LEASE_S、AGENTLAB_WORKER_HEARTBEAT_S、AGENTLAB_SCHEDULER、AGENTLAB_SCHEDULER_TICK_S、AGENTLAB_BUILD 和 dev.sh --postgres 的 AGENTLAB_DEV_PG_*(都注释着,名字、缺省值照 core/config.py 和脚本);dev.sh 的 AGENTLAB_DEV_PG_* 也认 .env / backend/.env(环境变量优先,和后端的配置同一个规矩,不 source)。deploy/agentlab.env 末尾再追加「外接 PostgreSQL 与多进程(可选)」一段(地址写宿主机网桥 172.17.0.1、放行容器网段,和内置库二选一;断点库、PgBouncer、直连地址、工作进程、租约、连接池、启动时等库),已有的行一行没动。deploy.sh:AGENTLAB_DATABASE_DIRECT_URL 也算外接的库(和内置互斥),只设直连地址不设 AGENTLAB_DATABASE_URL、内置库开 AGENTLAB_DB_PGBOUNCER、SQLite 时 AGENTLAB_WORKERS 大于 1 都在起容器之前照实拦下(migrate-to-postgres 在停服务之前查)。单测:这些 AGENTLAB_* 经 --env-file 进容器、几条拦截、模板两段的项和缺省值、dev.sh 从 .env 读设置,以及守卫——config.py 里应用库、连接池、多进程、调度几类配置每一项都要在 .env.example 里有 2026-10-19 15:41:37 +08:00
ThearchyHelios e8743aa8c4 更新 agentlab.env 配置:将 HOST_PORT 修改为 8080,DATA_DIR 修改为 ~/agentlab_data 2026-10-19 15:30:45 +08:00
ThearchyHelios b52a67b18d 后台任务的 drain 不再空转:notify.service、eval.cleanup 的 drain 改用新增的 core/background.drain——做完了的任务直接从集合里摘掉,只等本事件循环上没做完的,别的循环上没做完的不等、循环关了的摘掉。以前 while _background: await gather(...) 碰上别的事件循环上做完、discard 回调永远不跑的任务,gather 立刻返回、不让出事件循环,在那里空转(CPU 打满、进程卡死):PostgreSQL 全量里 test_personal_apps 的收尾两次卡在这里。单测在另一个线程里跑 drain、按线程等(空转时事件循环转不动,wait_for 救不了) 2026-10-19 15:29:00 +08:00
ThearchyHelios 39bc76494e 测试:随机名字不带数字——新增 tests/fixtures/names.letters(uuid4 的十六进制里数字换成字母,同 test_run_data_versions 的写法),dual_check_shop 的数据源名、盲算的调用编号,评测、应用说明检查、导入、遮罩、通知几处测试里拼进文本的随机名字都改用它(以前带着「330」「300」「48」这类数时撞上「文本里不许出现这个数」的断言);test_eval_schedule 查通知里有没有数时先去掉 32 位编号和发送时间(随机的编号带过「310」);test_null_not_null_values_fall_back_to_the_model_default 显式导入 app.db.models(单独跑时 schedules 还没登记进元数据,KeyError)。deploy.sh 注明内置库不用 copy-to-postgres 的 --direct-url 2026-10-19 15:16:54 +08:00
ThearchyHelios 27237623c5 合入 nr8/b 的 45513c90(复核 R-b7–R-b15 和 R-b12 的尾巴:租约按库的时钟、隔离用计入休眠的钟、PostgreSQL 单进程墙钟跳变不再隔离自己、Fenced 只对绑定世代的执行抛、隔离后等不到重新登记的运行照实收尾、续租任务不退出、换身份后收拾旧身份、quota.take 交回日期、check_pgbouncer 同一主机端口(本机回环规范化)也拒绝、copy-to-postgres 抽出 checkpoint_conninfo 加 --direct-url、版本指纹算进 requirements.lock、run_events 重号记进设置);没有冲突,README、db/base.py、db/to_postgres.py 自动合并:to_postgres.main 里 nr8/b 的 --direct-url 和这边连不上时一句话报错的分支都在 2026-10-19 15:14:25 +08:00
ThearchyHelios 45513c90b7 R-b12 的尾巴:check_pgbouncer 判同一个主机端口时把主机名规范化——localhost、127.x.x.x、::1 都算本机回环,IP 按地址比(::ffff:10.0.0.5 和 10.0.0.5 相同),解析不成 IP 的按字面(小写)比、不查 DNS。补测试:localhost 对 127.0.0.1、127.0.0.1 对 ::1、IPv4 映射地址同端口都拒绝,本机另一个端口、名字不同的放行 2026-10-19 15:09:10 +08:00
ThearchyHelios c0f7aae8ad 复核 R-b15(隔离后等不到重新登记的运行原因记错、任务没摘):_drive 里 fence.ready() 等不到时照实收尾——排队中的(一步都没执行过)收成失败,写明「本进程隔离后没能重新登记,这次运行没有开始执行」并记 run.failed;要接着执行的(继续、批了审批)收成中断、断点完好可继续运行;条件更新,状态、属主变了(别的进程先接手)就不动;执行任务从 run_manager._tasks 里摘掉。补测试:隔离后新身份一直没登记上,新发起的运行收成失败、原因写对、run.failed 记下、任务摘掉 2026-10-19 15:08:39 +08:00
ThearchyHelios eb9af51abb 复核 R-b14(PostgreSQL 单进程墙钟一跳就隔离自己):取得到计入休眠的钟(SLEEP_AWARE)时 stale() 只看它,墙钟只在取不到时当后备(两只里走得多的那只);两只钟对不上(jumped)不再直接隔离,先续一次租——续租那一句按库的时钟核对「自己的租约还没过期」,以它为准:续上了只记一条日志照常,续不上才隔离。README「多进程」补一句:库服务器自己的时钟往前跳超过一个租约时所有进程一起隔离、怎么恢复,往回跳时真没了的进程要多等,本机墙钟跳了不隔离。补测试:墙钟往前往后跳一小时不算续晚了、只算对不上,计入休眠的钟走过两个租约照样算,取不到时墙钟当后备;PostgreSQL 单进程墙钟 ±1 小时续租照常续上、不隔离,真过期仍隔离;执行到一半墙钟 ±1 小时,运行照常跑完、世代不变(改前的写法往前跳那条不过) 2026-10-19 15:07:17 +08:00
ThearchyHelios 68c1f4143e 复核 R-b13(版本拦截与零碎):preflight 报错列出全部活着的、版本不同的进程,各标明心跳在走还是停着、等租约过期(以前只点名先看到心跳的那个,人停掉它再起还会被另一个拦下);源码指纹把依赖锁文件 requirements.lock 的内容也算进去,只升了依赖也算版本不同,锁文件取不到时换成几个关键包的版本,Docker 镜像里留一份锁文件;存量库 run_events 撞了号时把结果记一次(settings 表 cluster:run_events_seq_duplicates,记下撞号的那几处,最多 200 处),之后启动不再整表 GROUP BY、只按索引核对那几处还撞不撞,都处理掉了才再数一遍、建唯一索引、删掉记录。隔离后换身份那几条日志写出新旧完整身份已在 R-b9 那一笔里改了。README「升级」一段跟着补一句。补测试:一个心跳在走、一个心跳停着,报错两个都列出、各标状态;锁文件变了指纹跟着变、取不到时用包版本;撞号第一次整表数、第二次只核对不扫、处理掉之后建上索引并删掉记录 2026-10-19 14:45:54 +08:00
ThearchyHelios d55ae68e7d 复核 R-b12(直连地址其实还是 PgBouncer、搬断点走了事务模式):check_pgbouncer 除了没给直连地址,直连地址和应用库地址连的是同一个主机端口(规范化之后比,端口不写按 5432)也拒绝启动,报错说清直连要绕过 PgBouncer;copy-to-postgres 搬断点抽成 checkpoint_conninfo:给了断点库地址用它,否则进目标库、给了直连地址就走直连,命令行加 --direct-url,不给而目标就是应用库时用 AGENTLAB_DATABASE_DIRECT_URL。补测试:同一个主机端口(大小写、用户、参数不同)拒绝、同主机另一个端口放行;搬断点缺省走直连、单给的断点库地址优先、目标是别的库不套用应用库的直连地址 2026-10-19 14:42:33 +08:00
ThearchyHelios ed3bb943df 复核 R-b11(跨零点退回额度退到第二天那一行):quota.take 交回占在了哪一天(本地日期),占不到交回 None;出具、按需视图发起失败时按这个日期退回——23:59:59 占、00:00:01 失败,退的是前一天那一份,第二天的不动。补测试:跨零点占了两份、退回前一天那一份,前一天归零、第二天那份不动 2026-10-19 14:40:11 +08:00
ThearchyHelios 19ffa1fa17 测试:隔离之后重新登记、收拾旧身份的两条用虚构的旧身份(不拿本进程真的身份当旧身份收拾,免得删到同一个测试进程里前面留下的、属主是它的行) 2026-10-19 14:40:10 +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 d6ecaaa7a3 复核 R-b8(隔离时 asyncio 记一条回调异常):断点写入的守卫改成协程包装、在协程里查 fence——LangGraph 在节点的完成回调里调 aput_writes 拿协程交给后台任务,以前同步包装在回调里就抛 Fenced,每次隔离都打一条「Exception in callback … FuturesDict.on_done」加 traceback;现在异常留在写断点的那个任务里,由 LangGraph 照常收走。补测试:卡住被接手那一条里 asyncio 不记回调异常、不记没人取的任务异常(改前的写法这条不过) 2026-10-19 14:29:12 +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 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 322ba5969b 合入 nr8/b 之后的配合:启动时先等库再做版本检查(cluster/version.preflight 是第一次连库,放在等库之前的话库的容器晚一步起来服务就直接崩),单测核对先后;deploy/README 多进程一段写明内置 PostgreSQL 是直连、不用 AGENTLAB_DATABASE_DIRECT_URL,upgrade 先停掉旧容器(全部工作进程)、备份、再起新版本,正合不许新旧版本同时运行的拦截 2026-10-19 14:06:20 +08:00
ThearchyHelios 5318c33f57 合入 nr8/b 的 ac8b194c(复核 R-b1–R-b6、交互留底的运行名额、先占额度再出具、直连地址 AGENTLAB_DATABASE_DIRECT_URL 和 AGENTLAB_DB_PGBOUNCER、不许新旧版本混跑、prod.sh 和 Docker 入口问 python -m app.cluster workers、镜像带构建号);没有冲突,README、config.py、db/base.py 自动合并 2026-10-19 14:01:07 +08:00
ThearchyHelios c842b536f6 内置 PostgreSQL 的四条取舍:agentlab.env 模板末尾追加注释掉的「内置 PostgreSQL(可选)」一段(POSTGRES_IMAGE、POSTGRES_CONTAINER、DOCKER_NETWORK、POSTGRES_VOLUME、BACKUP_KEEP,缺省值写在注释里,已有的行一行没动);升级前的备份收紧权限——backups/ 起每一层目录 0700、备份文件 0600,属主同数据目录(SQLite 的在 umask 077 下先以 0600 建空文件再交给备份接口写,pg_dump 在 umask 077 下写、目录由 app.ops backup-dir 建和收紧),恢复步骤里写清哪一步要 sudo、内置库的恢复改成在以 10001 运行的临时容器里读备份(不用 sudo);restart 缺省只重启服务(库停着时先把库起来),restart --postgres 连库一起重启,没用内置库时加 --postgres 照实报错;离线包缺省带 PostgreSQL 镜像不变,deploy/README 写清多出约 160 MB、导入后约 0.7 GB;deploy/README 加「首次在 Linux 上切换前的检查」(docker 版本、属主、权限、磁盘空间、整目录备份)。单测核对权限位、restart 两种用法、模板里的注释和 deploy.sh 的缺省值一致 2026-10-19 13:58:00 +08:00
ThearchyHelios 320fd69af2 镜像大小照实写:内置 PostgreSQL 的镜像导出约 160 MB、导入后约 0.7 GB(postgres:16.15,arm64 上量的) 2026-10-19 13:47:38 +08:00
ThearchyHelios ac8b194ca8 评测时限不算排队(续):within 看得更勤(不超过时限的 1/20),一段的头尾有一头在暂停就整段不算——以前一段只看尾巴,拿到名额后的头一段整段算进去,PostgreSQL 全量满载时那条测试偶发超时;测试改成排 2 秒、时限 1 秒,给拿到名额之后的几次写库留够余地 2026-10-19 13:46:09 +08:00
ThearchyHelios 237850f6c9 部署说明:deploy/README「用 PostgreSQL」改成三种放法(缺省 SQLite、内置 PostgreSQL、外接 PostgreSQL)各自的用法和数据在哪里,内置的怎么起、能改的几项、备份和恢复(pg_dump / pg_restore 的完整步骤)、从 SQLite 切过来的六步和出错时的样子、SQLite 库文件什么时候能删、卸载;包里多了 postgres-image.tar,升级前自动备份、升级时自动迁移,停止和卸载按顺序管两个容器。仓库 README:离线包一段补内置 PostgreSQL,「用 PostgreSQL」补启动时等库和「和库一起起」(deploy.sh install --postgres / migrate-to-postgres、dev.sh --postgres),快速开始提一句 --postgres 2026-10-19 13:43:52 +08:00
ThearchyHelios 9e6a6db406 deploy.sh 带内置 PostgreSQL:install --postgres 在旁边再起一个 PostgreSQL 容器(镜像小版本固定 postgres:16.15、可用 POSTGRES_IMAGE 改;同一个 docker 网络、端口不对外;数据在 docker 数据卷;密码第一次自动生成在数据目录的 .postgres/、0600,按 POSTGRES_PASSWORD_FILE 和 PGPASSFILE 传,不进镜像、日志和 docker inspect;agentlab.env 什么都不用填)。用过一次的数据目录记在 .postgres/state,之后 install / upgrade / start 不用再加。start、restart 先起库等 pg_isready 再起服务,stop 先停服务再停库,status 显示两个容器,logs --postgres 看库的,uninstall 连库的容器和网络一起删、数据卷和数据目录留着。和外接 PostgreSQL(agentlab.env 里的 AGENTLAB_DATABASE_URL)互斥,照实报错;已有 SQLite 库的数据目录不许 install --postgres(指向 migrate-to-postgres),别的数据目录留下的数据卷不拿来用。upgrade 先停旧服务、自动备份(SQLite 用备份接口拷到 backups/sqlite/,内置库 pg_dump 到 backups/postgres/,各留最近 BACKUP_KEEP 份),备份没做成就把旧服务起回来不升级;POSTGRES_IMAGE 换了时库的容器按新镜像重建、起不来就换回原来的。新增 migrate-to-postgres:停服务 → 备份 → 起库 → copy-to-postgres 先 --dry-run 再正式导入、核对 → 记下已切换 → 按内置库起服务;记下之前哪一步出错都退回 SQLite(服务原样恢复、库的容器停掉、状态记成 migrating),重跑先清空上次导了一半的再导,已切过的什么都不做,不是这个数据目录留下的数据卷不清空。容器、网络、数据卷、端口等可用 DEPLOY_<名字> 环境变量盖过(测试、并排部署)。package-docker.sh 把同一个标签的 PostgreSQL 镜像导出成 postgres-image.tar 一起打包(--no-postgres 不带),标签只在 deploy.sh 里定一处。单测用假的 docker(tests/fake_docker.py)核对先后顺序、生成的参数、互斥和各条回退 2026-10-19 13:43:52 +08:00
ThearchyHelios bf74423651 dev.sh 加 --postgres:起(已经有就复用、停着就起)一个本地开发用的 PostgreSQL 容器,端口只开在 127.0.0.1(缺省 55432),数据在 docker 数据卷,密码第一次自动生成在数据目录的 .postgres-dev/ 里,后端按 PGPASSFILE 读、照它设 AGENTLAB_DATABASE_URL;容器名、端口、数据卷、镜像可用 AGENTLAB_DEV_PG_* 改,同名容器不是这个脚本起的、端口和已有容器的不一致都照实报错。不加就和原来一样:SQLite,不用 docker 2026-10-19 13:43:33 +08:00
ThearchyHelios 93cd32bc97 启动时等库:PostgreSQL 还连不上(和库的容器一起起、库还在初始化)时按退避重试(1、2、4、5、5… 秒),每次照实打一条「应用库还没就绪」,最多等 AGENTLAB_DB_STARTUP_TIMEOUT(缺省 90)秒再把最后一次的错抛出去;密码不对、库不存在这种等也没用的(SQLSTATE 28、3D、42 类)立刻抛;SQLite 不等。新增 python -m app.ops(部署脚本在容器里以镜像用户调的几件小事,只用标准库):内置 PostgreSQL 的密码文件和 pgpass(0600,已有就沿用,密码不打印)、数据目录用哪种库的状态(sqlite / builtin / migrating)、SQLite 库的一致备份(备份接口,含 -wal 里的)和只留最近 N 份。copy-to-postgres 连不上目标库、库报错时一句话说清楚、退出码 1,不再甩一屏调用栈 2026-10-19 13:43:32 +08:00
ThearchyHelios 94fd36027b 测试:隔离那两条先等 slow 前面那一步的断点落库再装「卡住、被接手」——LangGraph 存断点和下一步并行,PostgreSQL 全量满载时 slow 已经开始、断点还在写,一隔离那次写入就被拦下,接手的一边找不到断点(偶发「没有可继续的断点」) 2026-10-19 13:42:10 +08:00
ThearchyHelios 451c05aacb 文案检查:应用库、断点库地址写错时报错里给的地址示例(postgresql+asyncpg://用户:密码@主机:5432/库名 等)登记进 copy-allow.json——://、:、@ 是地址语法,用户照着改环境变量,不能换成全角
(cherry picked from commit 3403a0b2cc)
2026-10-19 13:40:54 +08:00
ThearchyHelios bf9e4d4811 测试:额度并发那条同时占的个数降到 10(不超过连接池直接能给的连接数)——全量 -n auto 时 SQLite 的池子各测试共用,排队等连接会把池子的队列绑到前一个测试的事件循环上,这条偶发报 bound to a different event loop 2026-10-19 13:35:17 +08:00
ThearchyHelios 5b24480268 版本守卫拒绝启动的那句话改掉「混跑」(check-copy:「跑」不作动词):不支持新旧版本同时运行,先停掉这些进程再启动新版本 2026-10-19 13:33:07 +08:00
ThearchyHelios 62089f2849 复核「另外两处」:评测每题的时限、算期望的时限都不算排队等运行名额的那一段(within 代替 asyncio.wait_for,作答那次运行在 slots 里还排着队时不走表;算期望的运行排着队时把截止时刻往后挪),满载时不再被记成超时、触发止损;同源队(SourceLanes)跟发名额一样,拿这个源的咨询锁之前备好「哪些别的属主确实不在了」,持锁期间只用持锁的那条连接,拿锁之后才出现的属主这一次当活着。slots 加 waiting(run_id, here=):本进程里的直接看、不查库。补测试:排队 0.8 秒、时限 0.3 秒照样答完不记超时(改前的写法这条不过);within 暂停的那几段不算、不暂停照样超时;同源队持锁期间不查「谁还活着」、没了的进程照样让位、拿锁之后才出现的属主不删 2026-10-19 13:31:46 +08:00
ThearchyHelios f3ff5b9c18 复核 R-b5、R-b6:转发运行事件、读缓存失效通知都从游标往回留一小段重读(运行 64 条、缓存 200 条),按发布过的 seq / 处理过的 id 去重——号先取后提交、号大的先提交时,号小的那一条后到也照样转、照样失效,不越过回放已经发过的那一段;合成之后超长的正文增量按字切成几条(二分找每段最长的前缀,不切坏 UTF-8),不再截掉。补测试:号小的后提交照样转出来、不重复;缓存失效 id 大的先到、小的后到都处理;超长增量切开拼回来一字不少 2026-10-19 13:24:44 +08:00
ThearchyHelios 5578cf137d 复核 R-b4(prod.sh、Docker 入口读不到 .env 里的配置):新增 python -m app.cluster workers——照后端自己的配置(环境变量和 .env 一起读)说起几个工作进程,SQLite 而大于 1 时照实报错、退出码 2;prod.sh 只在命令行给了 --workers 时写进环境变量,进程数一律问后端,Docker 的入口同样问它。补测试:SQLite 而大于 1 拒绝、PostgreSQL 照给的数 2026-10-19 13:23:02 +08:00
ThearchyHelios 5f7100906f 复核 R-b3(SQLite 单进程多出来的写库):SQLite 时守卫已经确认只有本进程——登记只写一次、不续租约、本进程直接当班(不写库)、接手只在启动时做,心跳只做本进程自己攒着的活;运行的名额在 SQLite 下放在进程里(规矩同一套:优先级、类别上限、交互留底,只是不落库),一段运行不再为要名额多写三次库。顺带(复核「另外两处」之二):PostgreSQL 发名额持着全站的锁时不再另取连接查「谁还活着」,拿锁之前备好,不认识的属主这一次当活着。补测试:SQLite 空闲十来拍心跳、要一次名额放一次,PRAGMA data_version 不变(名额落库的写法这条不过);库里的名额行那两条只在 PostgreSQL 上跑 2026-10-19 13:22:05 +08:00
ThearchyHelios 96bb372ef3 复核 R-b2(单进程下周期整理退回判定中的待办):当班进程隔一会儿的那一次接手(trust_mine)不论有没有别的进程,停在 resolving 的待办只收拾停了两个租约时长以上的,启动时又没有别的进程的那一次照旧全收拾;顺带把其余周期调用的整理过一遍——结果未知的写入只补停了两个租约时长以上的(收尾和安排核实之间的不碰),问数据没有任务行的老轮次只在启动时整理(老页面开的轮次建图时也是这个样子)。补测试:判定到一半当班进程来一次,待办照样记已处理、那一票不撤回(改前的写法这条不过) 2026-10-19 13:18:23 +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 75ab3678cb 代码里拦住新旧版本混跑(用户拍板):新增 cluster/version——代码版本(包版本 + 构建号 AGENTLAB_BUILD 或 git 提交 + app/ 下源码指纹,比较按源码指纹)、库结构版本(各表各列加迁移清单的哈希),进程登记时一并记下(cluster_workers 两列,add-only 迁移)。PostgreSQL 时补列之前先看一眼(preflight):库里还有活着的、版本不同的进程,心跳在走就拒绝启动、照实写明是哪几个进程什么版本、要先停掉再升级,心跳停着的(强杀留下的)等租约过期再起;登记那一下在事务级咨询锁里再查一遍,两个不同版本同时启动只有先登记上的起得来。Docker 镜像带上构建号;README 写明升级步骤。补测试:版本不同的活进程被点名拒绝、同版本照常加入、过期的不算、只比源码指纹;PostgreSQL 上心跳在走的拒绝、心跳停着的等过期、登记时再拦一次 2026-10-19 13:04:07 +08:00
ThearchyHelios d68ca9774f 加直连地址 AGENTLAB_DATABASE_DIRECT_URL 和 PgBouncer 事务模式开关 AGENTLAB_DB_PGBOUNCER(用户拍板):依赖会话状态的连接——收发进程间通知的那一条(LISTEN)、跨进程的锁(会话级咨询锁,另建一个直连的小池子)、断点库(缺省)——走直连地址,普通查询走 AGENTLAB_DATABASE_URL,不设就全用同一个;开关打开时普通地址不用客户端连接池、关掉 SQLAlchemy 和 asyncpg 的预备语句缓存、预备语句用随机名字(照 SQLAlchemy 文档),事务级咨询锁照常成立;开关打开却没给直连地址时拒绝启动。README 写三种部署(直连、PgBouncer 会话模式、事务模式加直连地址)和要配的 server_reset_query,照实说没在真的 PgBouncer 上跑过。补测试:地址解析和规范化、断点库缺省走直连、事务模式关掉的几样、LISTEN 和跨进程锁走直连、事务模式没给直连地址拒绝启动 2026-10-19 13:01:21 +08:00
ThearchyHelios 01af07b193 出具、按需视图的每日上限改成先占额度再发起(用户拍板):新增 cluster/quota——额度记在库里(rate_counters 按名字 + 本地日期一行),占一份是一句带条件的 UPDATE(没到上限才加一),两种库上都是原子的,这一天第一次占按库里已有的记录起算,发起被拒或出错就退回。出具去掉全站一把锁,只留同一(运行、工作流、版本)的去重锁,几份不同的出具可以同时发起;按需视图的锁缩回按缓存键(视图 + 参数)去重,每日上限改用这个应用的额度。补测试:20 个协程同时占正好到上限、按已有记录起算、退回再占;两个进程同时占正好到上限;三份不同的答案同时出具正好到上限、多出来的回 429 2026-10-19 12:57:38 +08:00
ThearchyHelios 6ed782a84b 运行名额改成给交互留底、其余可借(用户拍板):交互留底缺省全站上限的 1/4、至少 1、至多全站上限减 1,应用、定时、系统三类合起来永远用不到留底;三类各自的上限缺省 = 全站上限 − 留底(设置里可调小),没人问数据时评测能开满;交互上限缺省 = 全站上限;等名额照旧按优先级、同级先来先得。存着的设置原样存、缺省按全站上限和留底现算;留底不小于全站上限时 422。设置页「运行并发」加「给交互留底」一项,写明留底和借用是什么,README 同步。补测试:缺省值、空闲时系统类借满到 全站 − 留底、留底不借给应用类、问数据一来马上拿到留底;多进程端到端加 5b(评测借满时问数据拿留底、不等评测跑完) 2026-10-19 12:53:28 +08:00
ThearchyHelios 319b787688 合入 nr8/l 的 e1ff1c90(问数据事件日志清理不给时间时按当前时间算)
# Conflicts:
#	backend/app/chat/log.py
2026-10-19 12:48:42 +08:00