cloud: worker dispatch, DB abstraction, packaging 0.1.0, repo CI workflow

This commit is contained in:
host committed 2026-10-26 01:44:15 +08:00
1 parent 076ba01c74
commit 07ef869267
13 files changed
+1916 -9

No files matched your search

+50 -2
View File
@@ -20,6 +20,8 @@ cloud/server.py(控制面,ThreadingHTTPServer)
├─ OAuth:cloud/oauth.py(state + 授权 URL + 回调,脚手架)
├─ 推送订阅与分发:cloud/push.py(订阅表 + 偏好过滤)
├─ 认证 / 权限 / 审计:cloud/auth.py(AuthStore)
├─ 数据库接口:cloud/db.py(Database 接口 + SQLite 实现,
│ WAL + busy_timeout + 有限重试;Postgres 只是骨架,见下)
├─ 并发:cloud/db.py(WAL + busy_timeout + 有限重试)
└─ webhook 入站:cloud/webhooks.py(验签 + 解析,只解析不执行)
```
@@ -110,6 +112,51 @@ server 的连接统一走 `cloud/db.py`:WAL 模式、busy_timeout 5000ms、
写仍是单写者串行,写密集或跨机器时必须换 Postgres,这是下一阶段,
不是本轮假装解决。
### 数据库后端选择(接口层)
`cloud/db.py` 已抽成接口层,不改旧调用:
- `Database` 接口的方法就是原有 SQLite 实现对外提供的全部方法,
按实际代码为准:`connect`(连接 + WAL 设置)、
`execute_with_retry`(执行)、`read_all`(查询)、
`transaction`(事务)、`is_locked_error`(锁冲突判定)。
- `SQLiteDatabase`:现有实现改名后的类封装,原样保留
WAL / busy_timeout / 有界重试;模块级函数 `connect` /
`execute_with_retry` / `read_all` / `transaction` /
`is_locked_error` 仍可用,行为不变。
- `PostgresDatabase`:骨架,不是可用后端。即使驱动已装,其
`connect` / 执行 / 查询 / 事务方法仍抛 `NotImplementedError`。
- 工厂 `create_database(backend, db_path)` / `database_from_env()`:
两个后端提供同一组接口方法与签名,见
`cloud/tests/test_db_backend.py` 的接口契约测试。
后端选择环境变量(server 启动时生效,默认仍是 SQLite):
| 环境变量 | 说明 | 默认 |
| --- | --- | --- |
| `CLOUD_DB_BACKEND` | `sqlite` 或 `postgres`(`postgresql` 同义);其它值启动即报 `ValueError`,不静默当 sqlite | `sqlite` |
| `CLOUD_DB_HOST` | Postgres 主机,全部走环境变量,不硬编码地址 | 无(未设即 None) |
| `CLOUD_DB_PORT` | Postgres 端口,须为整数 | 无(未设即 None,走驱动默认) |
| `CLOUD_DB_NAME` | Postgres 库名 | 无 |
| `CLOUD_DB_USER` | Postgres 用户名 | 无 |
| `CLOUD_DB_PASSWORD` | Postgres 密码,只走环境变量,绝不写文件、绝不进日志与 `repr` | 无 |
选 `postgres` 且驱动缺失时启动即明确报错:`PostgresDatabase`
初始化时探测 `psycopg`(优先)/ `psycopg2`,两者都缺就抛
`PostgresDriverMissingError`(`RuntimeError` 子类,文案含
psycopg,写明“需安装 psycopg”),绝不静默回落到 SQLite,
也绝不假装已接通 Postgres。`create_server` 在建表之前就做这
一步校验,所以失败时不会先建出一个 SQLite 库假装可用。
> 高并发换 Postgres 是下一阶段的运维项,不是本轮代码一改就
> 自动变生产。接口层 + 骨架只解决了“以后能换”,真正上生产还
> 需要:真实 Postgres 部署(含备份、连接数与权限)、安装
> psycopg 驱动、写迁移脚本并把现有 SQLite 表结构与数据迁过去、
> 把 server / AuthStore / MemoryStore / KBStore / CostStore 等
> 目前仍直连 SQLite 的调用点逐一接到新后端并重测。在这些完成
> 之前,即使把 `CLOUD_DB_BACKEND` 设成 `postgres`,server 也只会
> 在启动时明确报错,不会跑起来——这是有意为之的诚实边界。
| 方法与路径 | 权限 | 说明 |
| --- | --- | --- |
| `GET /health` | 无需认证 | `200 {"ok": true, "service": "cloud-control-plane"}` |
@@ -225,5 +272,6 @@ interrupted 且终态任务 cancel 返回 400、心跳后 sweep 不扫刚心跳
端点(state + 授权 URL + 回调),但真实应用注册、回调公网地址、
已有账号绑定仍缺;推送已接成订阅 + 分发端点,但 Web Push /
APNs / FCM 的真实凭证与发送端仍缺;单机 SQLite 在高并发写下
仍有上限,生产量上来后需换 Postgres;worker 执行、云端执行、
真实通知与真实模型回合均未接通。
仍有上限,生产量上来后需换 Postgres(接口层与骨架已就绪,
但真实部署、驱动安装与迁移脚本仍缺,见上文“数据库后端选择”);
worker 执行、云端执行、真实通知与真实模型回合均未接通。