feat: add group cooldown and parallel actions
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
# 0.1.6:大号组共享 UID 冷却与关注/私信并行
|
||||
|
||||
## 需求与已确认口径
|
||||
|
||||
用户要求:
|
||||
|
||||
1. 同一个 UID 可配置冷却时长,默认 4 小时,期间不重复打扰。
|
||||
2. 同一通知同时配置关注和私信时,两项并行执行,不等待默认 30 秒动作间隔。
|
||||
3. 开始本轮修改前先推送已有版本。
|
||||
|
||||
已先将完整 0.1.5 快照提交并推送至 `origin/main`:
|
||||
|
||||
```text
|
||||
fee3951 feat: add Windows multi-account assistant
|
||||
```
|
||||
|
||||
通过交互确认的业务口径:
|
||||
|
||||
- 冷却按**大号组共享**:一个大号组内所有执行小号共用;不同大号组互不影响。
|
||||
- 同时开启关注和私信时**强制并行**。旧“私信前必须关注成功”不再控制新任务;两个结果分别保存,互不取消。
|
||||
|
||||
## 冷却生命周期
|
||||
|
||||
### 为什么不在通知入库时立即开始
|
||||
|
||||
通知可能刚入队就因用户停止业务、切换小号归属或删除小号而取消。如果通知入库即开始 4 小时冷却,会在没有实际请求平台时消耗冷却期。
|
||||
|
||||
因此冷却从任务被执行小号**实际领取、即将发起平台请求**时开始。领取批次和写入冷却记录处于同一个 SQLite 事务中;进程重启后仍然有效。
|
||||
|
||||
### 冷却开始前的重复保护
|
||||
|
||||
同一大号组、同一目标 UID 如果已经存在以下任一状态的任务,新通知不再创建重复任务:
|
||||
|
||||
- `pending`:已排队;
|
||||
- `running`:正在执行;
|
||||
- `unknown`:结果不确定,必须人工核对。
|
||||
|
||||
这样可以关闭“第一条还没执行,短时间又来了多条点赞/评论”的重复排队窗口。只排队后被取消且从未领取的任务不会写入冷却表。
|
||||
|
||||
`unknown` 比普通冷却更保守:即使配置冷却时间已经过去,只要结果仍未人工核对,仍不自动创建同 UID 的新任务。这延续了项目原有的“结果不确定绝不自动重发”约束。
|
||||
|
||||
### 冷却期行为
|
||||
|
||||
任务领取后,不论最终状态为:
|
||||
|
||||
- 成功;
|
||||
- 明确失败;
|
||||
- 结果不确定;
|
||||
|
||||
该大号组在配置时长内都不会因为新通知再次创建同 UID 的任务。日志会写出“冷却开始”或“冷却跳过”、本地大号名称及剩余秒数,但不写完整 UID。
|
||||
|
||||
默认值:
|
||||
|
||||
```text
|
||||
14400 秒 = 240 分钟 = 4 小时
|
||||
```
|
||||
|
||||
规则 UI 使用分钟配置:
|
||||
|
||||
- 范围 0–525600 分钟;
|
||||
- 0 表示关闭;
|
||||
- 内部继续使用整数秒存储;
|
||||
- 数据层允许 0–31536000 秒。
|
||||
|
||||
新通知使用其入库时的规则快照判断冷却时长。如果用户修改规则,之后收到的通知使用新时长;历史事件和任务不被重写。
|
||||
|
||||
### 持久化结构
|
||||
|
||||
新增表:
|
||||
|
||||
```sql
|
||||
CREATE TABLE cooldowns (
|
||||
source TEXT NOT NULL REFERENCES accounts(id),
|
||||
target TEXT NOT NULL,
|
||||
last_at REAL NOT NULL,
|
||||
event INTEGER NOT NULL REFERENCES events(id),
|
||||
PRIMARY KEY(source, target)
|
||||
);
|
||||
```
|
||||
|
||||
主键 `(source, target)` 使冷却天然按大号组和目标 UID 共享。执行小号不在主键中,因此组内轮询切换到另一个小号不会绕过冷却。另一个大号组使用不同 `source`,不会互相影响。
|
||||
|
||||
表只保留每组每 UID 最近一次实际领取时间,采用覆盖更新,不为同一组合无限追加历史行。详细历史仍由每日运行日志和任务表保存。
|
||||
|
||||
## 关注和私信并行
|
||||
|
||||
### 任务创建
|
||||
|
||||
同一事件、同一目标、同一执行小号同时开启关注和私信时,仍创建两个独立任务,但两者:
|
||||
|
||||
- `dependency=NULL`;
|
||||
- 保存同一规则快照;
|
||||
- 属于同一事件和目标;
|
||||
- 不再创建“私信依赖关注任务”的关系。
|
||||
|
||||
UI 删除了“必须关注成功后才发送私信”复选框。兼容字段 `require_follow` 暂时保留在 JSON 中,但规则验证、保存和旧库升级都会强制归一化为 `false`,避免旧界面配置继续产生新依赖。
|
||||
|
||||
升级不会重写历史任务。0.1.5 之前已经入队且带 dependency 的旧任务,领取逻辑仍保留兼容处理:按旧快照等待或取消,不将旧私信突然并行发送。
|
||||
|
||||
### 批次领取
|
||||
|
||||
新增 `Store.claim_batch(worker)`:
|
||||
|
||||
1. 使用 `BEGIN IMMEDIATE` 串行化领取事务;
|
||||
2. 拒绝账号未绑定、归属不符、规则关闭或已有 running 任务;
|
||||
3. 选出最早可执行任务;
|
||||
4. 若同一 worker/source/event/target 下还有无依赖的 pending 兄弟任务,一并改为 running;
|
||||
5. 在同一事务写入共享冷却时间;
|
||||
6. 返回一个或两个任务。
|
||||
|
||||
旧数据库中的 `worker_single_running` 部分唯一索引会删除,因为合法并行批次需要同一小号同时有两个 running 任务。重复领取仍由 `BEGIN IMMEDIATE`、running 检查和状态更新保证;另一个 Store 连接在前一个事务提交后只能看到 running,不会再次领取。
|
||||
|
||||
保留 `Store.claim()` 供单任务测试和兼容调用;产品 Worker 使用 `claim_batch()`。
|
||||
|
||||
### 同时执行和独立结果
|
||||
|
||||
`Engine.perform_batch()` 使用:
|
||||
|
||||
```python
|
||||
await asyncio.gather(..., return_exceptions=True)
|
||||
```
|
||||
|
||||
关注和私信协程同时启动。单项抛出异常时:
|
||||
|
||||
- 该项记为 `unknown / INTERRUPTED_CHECK_MANUALLY`;
|
||||
- 另一项不会被取消,继续完成;
|
||||
- 两项分别调用 `Store.finish()` 保存状态和耗时;
|
||||
- unknown 仍需用户人工核对,不自动重发。
|
||||
|
||||
默认 30 秒设置改名为“不同任务批次间隔”。Worker 只在领取下一个通知批次前检查它;同一批次内部不插入 sleep,也不等待关注结果。
|
||||
|
||||
停止业务仍等待在途并行批次完成,再退出循环和保留浏览器,避免关闭过程中把两项静默丢失。程序意外中断时,启动恢复会把仍为 running 的两项都改为 unknown。
|
||||
|
||||
## 可观察日志
|
||||
|
||||
0.1.5 的按日日志新增:
|
||||
|
||||
- `[冷却开始]`:任务已实际领取、组共享冷却开始、冷却秒数;
|
||||
- `[冷却跳过]`:仍在冷却期及剩余秒数;
|
||||
- `[冷却跳过]`:已有 pending/running/unknown 时不重复排队;
|
||||
- `[并行批次]`:同一通知的关注和私信同时开始;
|
||||
- 两条独立 `[任务开始]` 和两条独立 `[任务结果]`。
|
||||
|
||||
日志继续不保存 Cookie、签名、私信正文、原始响应、完整通知 ID 或完整目标 UID。UI 仍只展示最近 2000 条,完整日志按本地日期保留在:
|
||||
|
||||
```text
|
||||
%LOCALAPPDATA%\DouyinAccounts\logs\YYYY-MM-DD.log
|
||||
```
|
||||
|
||||
## 数据库升级
|
||||
|
||||
0.1.6 启动时:
|
||||
|
||||
1. `CREATE TABLE IF NOT EXISTS cooldowns`;
|
||||
2. `DROP INDEX IF EXISTS worker_single_running`;
|
||||
3. 所有账号规则缺少 `cooldown` 时补为 14400;
|
||||
4. 旧 `require_follow` 统一改为 false。
|
||||
|
||||
旧账号、UID 绑定、归属、通知、任务、日志和浏览器目录均保留。旧任务的 params 快照不批量改写。
|
||||
|
||||
## 测试
|
||||
|
||||
### Python 回归
|
||||
|
||||
Linux 和 Windows 完整 pytest 均:
|
||||
|
||||
```text
|
||||
64 passed
|
||||
```
|
||||
|
||||
新增或调整的核心验证:
|
||||
|
||||
- 缺少 cooldown 的旧规则升级为 14400 秒;
|
||||
- 旧 require_follow 升级为 false;
|
||||
- cooldowns 表自动创建;
|
||||
- bool 等非法类型被拒绝,0 可关闭冷却;
|
||||
- 通知入队但未领取时不写冷却;
|
||||
- 同 UID 已有 pending 任务时,新通知不重复创建;
|
||||
- 领取关注/私信批次后只写一条组共享冷却;
|
||||
- 同组第二个小号不能绕过冷却;
|
||||
- 不同大号组对同 UID 互不影响;
|
||||
- SQLite 重开后冷却仍有效;
|
||||
- 4 小时到期后新通知可再次创建任务;
|
||||
- cooldown=0 时前一批完成后新事件可再次创建;
|
||||
- 双动作批次同时变成 running;
|
||||
- 一个动作 failed、另一个 unknown 时结果独立,不生成自动重试;
|
||||
- 程序中断后两个 running 任务均恢复为 unknown;
|
||||
- Worker 测试使用闸门:关注和私信必须都进入协程后才放行,证明不是串行;
|
||||
- 点击停止时,在途并行批次完成后才返回;关注和私信各调用一次且均落库成功。
|
||||
|
||||
### Windows 浏览器与打包
|
||||
|
||||
- Windows pytest:64 项通过。
|
||||
- fingerprint-chromium/Patchright 离线矩阵全部通过:端口/目录隔离、固定指纹种子、SDK 详情请求、64 位通知 ID、登录回填、重连、错误身份拒绝、小号删除和兄弟账号隔离等均保持。
|
||||
- 矩阵 `real_write_actions=0`,未使用真实账号执行关注或私信。
|
||||
- 打包后 GUI smoke:Qt、核心模块、SQLite、Patchright 和内置浏览器路径均通过;临时账号数 0、真实写动作 0。
|
||||
- 6 个相关 Python 文件 LSP error 检查为 0。
|
||||
- 本地 23 个 Python 源文件 SHA256 与 Windows `build-manifest.json` 全部一致。
|
||||
|
||||
本次没有使用真实账号验证并行写操作,避免产生未授权关注或私信。并发调度通过可控制的异步闸门测试验证,关注与私信各自的 SDK 适配继续由原有独立测试覆盖。
|
||||
|
||||
## 发布
|
||||
|
||||
```text
|
||||
C:\Users\rogee\Desktop\抖音账号助手-0.1.6\
|
||||
DouyinAccounts-0.1.6-Windows-x64-Setup.exe
|
||||
SHA256SUMS.txt
|
||||
使用说明.txt
|
||||
```
|
||||
|
||||
- 安装包大小:222,651,315 字节。
|
||||
- SHA256:`6ab893fc2c7de8dbad4dcca43339eb2a2919d340f7b3ef6fe6b4a84cf2c038bc`。
|
||||
- 桌面副本已重新计算校验和。
|
||||
- 浏览器与依赖版本不变:fingerprint-chromium 148.0.7778.215、Patchright 1.62.3、Python 3.12.10。
|
||||
|
||||
未代用户安装或启动真实业务。覆盖安装后,建议先打开大号规则确认“同组同 UID 冷却”为 240 分钟,再手动启动账号组。旧版已排队任务仍按原历史快照处理;新通知使用并行与冷却规则。
|
||||
Reference in New Issue
Block a user