Skip to content

feat(bt): BitTorrent 做种支持与做种限制 - #118

Closed
lingdiansr wants to merge 1 commit into
zerx-lab:developfrom
lingdiansr:feat/bt-seeding-refactor
Closed

feat(bt): BitTorrent 做种支持与做种限制#118
lingdiansr wants to merge 1 commit into
zerx-lab:developfrom
lingdiansr:feat/bt-seeding-refactor

Conversation

@lingdiansr

@lingdiansr lingdiansr commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

概述

实现 BitTorrent 下载完成后的做种(seeding)能力,参考 #74 的设计:

  • 下载完成后保留 torrent 句柄继续做种(librqbit session 复用)。
  • 做种限制:总分享率 / 做种后分享率(以完成时刻上传量为基准)/ 总做种时间 / 不活跃做种时间,支持 AND/OR 自由组合,达到限制后自动停止做种并转入完成态。
  • 做种状态机:做种中 / 已达分享率 / 已达时间 / 不活跃停止 / 用户暂停(复用现有 paused 语义,恢复后可继续做种)。
  • 上传量统计落库(uploaded_bytes / uploaded_at_completion 列,幂等迁移),UI 展示已上传量、总分享率与做种后分享率。
  • BT 上传纳入全局限速(speed_limit_bytes),任务条目同时显示上传/下载速度(无对应流量时自动隐藏)。
  • 做种设置页重设计:条件开关化、单位可选天/时/分、满足条件后动作可选「停止做种 / 删除任务 / 删除任务和文件」。

已跟进的上游变更

分支已合并最新的 upstream/main7e25bca),此前与 main 的冲突已解决。

设计反馈处理

感谢 @PythonShe 在 WIP 阶段提出的三点 review 意见:

  1. 上传量跨会话累计:已修复。下载阶段与做种阶段的上传量均改为增量累加写入 uploaded_bytes,暂停/恢复和重启后不再从 0 重计,总分享率限制因此更准确。
  2. 详情栏展示:已补充总分享率与做种后分享率的显示。
  3. 做种配置变更与会话重建:设置页中仅真正需要重建会话的选项会触发重建;分享率、时间限制等运行时读取的配置改为即时生效。

测试

  • cargo clippy -p fluxdown_engine -p hub -p fluxdown_server --lib -- -D warnings
  • cargo test -p fluxdown_engine -p hub -p fluxdown_server 全部通过 ✅
  • fvm flutter analyze lib test:仅 2 个 pre-existing info,无新增问题 ✅
  • fvm flutter test 全部通过 ✅

Closes #74

@CLAassistant

CLAassistant commented Jul 17, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@PythonShe

Copy link
Copy Markdown
Contributor

9a413d4(基于 042d88c)上读了一遍做种实现,也跑了下测试。趁还在 WIP 提三个 rebase 之后依然会存在的设计层面问题,行号以 9a413d4 为准,如有误读欢迎指正。

1. 重启后做种状态会残留,没有重置或恢复逻辑

启动时唯一的状态归一化是 UPDATE tasks SET status = 2 WHERE status IN (0,1,5)db.rs:688),seeding_status 不会被重置;clear_stale_session_state 会删掉 librqbit 的 session.json,register_seeder 也没有任何启动期调用方。所以退出时正在做种的任务,重启后会永远停在 seeding_status=1,UI 一直显示"做种中",但实际没有任何做种在跑。相关:SeedingStopReason::TaskDeleted(5) / SessionReleased(6) 有定义但全仓库没有任何写入点;做种时长/不活跃计时用的是 Instantbt_seeding.rs:121-123),同样不跨重启——"总做种时间"实际是"距上次注册的时间",resume 重新注册后还会再清零。这块可能需要持久化感知的生命周期设计:启动时恢复做种(或重置残留行),时间基线也落库。

2. uploaded_bytes 是按会话覆盖写,不是累计值

两个写入点存的都是 librqbit 的原始快照(stats.live...uploaded_bytes.unwrap_or(0)),SQL 是直接覆盖 UPDATE tasks SET uploaded_bytes = $1download_manager.rs:893-906bt_downloader.rs:4003-4044db.rs:470)。librqbit 的计数器在 TorrentStateLiveAtomicStats 里,每次 Paused→Live 都会重建——所以同会话内暂停/恢复就会清零,暂停期间 stats.live == None 会直接写入 0,重启则会覆盖掉之前累计的全部上传量。结果是"总分享率"限制实际度量的是单会话分享率,会系统性低估,任务会做种超过配置上限。改成增量累加(或至少 MAX 合并)应该就能解决。

3. 修改任意做种配置会重建整个 BT 会话

六个 bt_seed_* / bt_max_seeding_tasks 键都在会话失效列表里(download_actor.rs:1364-1376、server actor.rs:415-427),改一下分享率限制就会暂停所有活动 BT 下载、停掉所有做种(且没有任何状态写入——又落入问题 1 的残留态)。但限制值本身每个 tick 都是从 bt_config 实时读取的(evaluate_seeding_limitsdownload_manager.rs:941-947),六个键里五个只需 set_bt_config 即可生效;只有 max_seeding_tasks 是在会话构建时快照进 SeedingManager::newbt_downloader.rs:645),把它改成动态读取应该比重建会话代价小得多。

@lingdiansr
lingdiansr force-pushed the feat/bt-seeding-refactor branch from 9a413d4 to 0bceb55 Compare July 23, 2026 12:37
@lingdiansr
lingdiansr marked this pull request as ready for review July 24, 2026 08:48
@lingdiansr lingdiansr changed the title feat(bt): BitTorrent 做种支持与做种限制(WIP) feat(bt): BitTorrent 做种支持与做种限制 Jul 24, 2026
@lingdiansr
lingdiansr changed the base branch from main to develop July 25, 2026 09:37
@lingdiansr
lingdiansr force-pushed the feat/bt-seeding-refactor branch from 22443ee to e965df3 Compare July 25, 2026 13:52
@lingdiansr

Copy link
Copy Markdown
Contributor Author

@zerx-lab 功能和 PR 清理工作已完成,请求审阅合并。

本次已:

  • 将分支重新基于 upstream/develop 清理,消除之前的 CRLF/LF 行尾符噪音;
  • 移除混入的 main 专属 CI 工作流文件;
  • 修复暂停/恢复后已上传字节重置、详情栏双分享率显示、BT 速度列同时展示上下行等问题;
  • 验证通过:cargo fmt --all --checkcargo clippy、engine 642 个单元测试、fvm flutter analyze 均无报错。

PR 现在是一个干净的单提交,diff 仅包含 BT 做种相关改动。请 owner 有空时审阅,如无问题可合并。谢谢!

- 做种限制:总分享率/做种后分享率/做种时间/不活跃时间,支持 AND/OR 组合
- 全局上传限速对 BT 上传生效
- BT 任务状态栏、详情栏、速度列显示上传/做种信息
- 做种达到限制后自动停止并转入已完成
- 暂停/恢复做种任务保留已上传字节
- 适配 develop 分支结构并清理 main 专属 CI 工作流文件

[maintainer edit] 行尾按 develop 基线逐文件还原(26 个还原 LF、settings_page.dart 还原 CRLF);与原提交 e965df3 相比内容零差异。
@zerx-lab
zerx-lab force-pushed the feat/bt-seeding-refactor branch from e965df3 to 8f7685e Compare July 30, 2026 01:10
zerx-lab added a commit that referenced this pull request Jul 30, 2026
* feat(bt): BT 下载完成后做种与做种限制

下载完成后保留 librqbit torrent 句柄继续做种;做种限制支持总分享率/做种后
分享率/做种时长/不活跃时长四条件 AND/OR 组合,达标后可停止做种、删除任务
或删除任务和文件。上传量增量累计落库(uploaded_bytes/uploaded_at_completion),
BT 上传纳入全局限速(speed_limit_bytes),任务列表与详情面板展示上传速度与
双分享率,做种设置页支持条件开关、时间单位与达标动作选择。

- 做种求值节拍经 aux 泵进主循环(主 select! 已满 64 分支,不新增分支)
- 启动时重置残留做种态;会话失效/任务删除写入对应停止原因(SessionReleased/TaskDeleted)
- 六个 bt.seed_* 配置键运行时热读,变更不再重建 BT 会话
- 云同步目录新增 6 键(bt.seed_*),44→50

基于 #118(作者 @lingdiansr)在最新 main 上重建,冲突一律以 main 现行代码为准。

Closes #74

* fix(bt): 旧库补做种列迁移,上传量统一增量落库

- 迁移清单补 uploaded_bytes / uploaded_at_completion / seeding_status /
  seeding_message / seeding_started_at 五列:旧库升级后 TASK_COLUMNS 查询
  会直接 no such column,任务列表加载失败,所有做种写库报错
- 删除下载期对 uploaded_bytes 的绝对值覆盖写:与 progress_reporter 的
  增量累计(add_task_uploaded_bytes)互斥,librqbit 计数器在暂停/恢复后
  归零时覆盖写会清掉已累计值;同步移除唯一调用方消失后的
  update_task_uploaded_bytes helper

* feat(bt): 做种语义重构——限制默认全关、活动做种上限与排队、时长跨会话累计

- 做种限制默认全部禁用(ratio/post_ratio/time/inactive 均 0),组合默认
  OR、达标动作默认停止;完成任务默认持续做种直到用户手动停止
- 新增活动做种数上限 seed_max_active(kv bt_seed_max_active,0=不限):
  超限完成任务进 FIFO 做种队列(librqbit 暂停、seeding_status=8),
  槽位释放或上限热调后由 5s tick 的 reconcile 升/降级;下载并发
  has_capacity 恢复只计 HTTP/FTP,做种与 BT 下载不再挤占下载槽
- 做种时长跨暂停/重启累计:新列 seeding_time_secs 存累计秒数,
  激活 stint 叠加计时,每 tick 快照落库、停止/降级时结算;排队与
  暂停期间不计时
- 分享率分母兜底:downloaded < total_size/100 时改用 total_size,
  0 分母且有上传按无穷大处理,避免 recheck 恢复的任务比率失真
- 契约补齐:server WS TaskProgress 增补 uploadedBytes/seedingStatus/
  seedingMessage 并保留做种期 live_speeds;REST TaskDto 同步增补
  四字段并重新生成 openapi.json;hub/server bt_config_from_map 解析
  seed_max_active(热读键,不触发会话重建)

* feat(bt): 做种设置对齐新语义——默认关闭、最大活动做种数、排队状态展示

- 设置页/Provider:四个做种限制默认关闭;新增「最大活动做种数」
  数字选择器(0=不限制);云同步 enable 语义修复——对外值为
  enabled ? value : 0,应用 0 即禁用且保留本地缓存值,关闭状态
  不再被其他设备同步回开
- 云同步目录新增 bt.seed_max_active,44→51 键;同步行为测试覆盖
  禁用上报 0 / 应用 0 禁用 / 应用正值启用与往返
- SeedingStatus 新增 queued(8):做种 Tab 归类可见、独立文案
  (排队做种/Queued for seeding),i18n en/zh 成对补齐

* feat(bt): 任务级做种限制覆盖(跟随全局/不限制/自定义)

每任务 4 项覆盖:总分享率/做种后分享率(千分比整数存储,1500=1.5)、
做种时长/不活跃时长(分钟)。哨兵:-2 跟随全局、-1 不限制、>=0 自定义
(0 视同不限制);组合方式与达标动作恒取全局。

- tasks 表新增 4 列(DEFAULT -2,幂等迁移),TaskInfo/TASK_COLUMNS 同步
- 做种求值改为逐任务生效配置:SeedLimitOverrides::apply 解析后进
  evaluate_limits,全局全关时任务自定义值仍可生效
- 写入路径热生效:桌面走 SetTaskSeedLimits 信号(经 aux 泵,不占主
  select! 分支),headless 走 WS setTaskSeedLimits → ActorCmd
- REST/WS 快照 TaskDto 增补同名 4 字段并重新生成 openapi.json
- 补齐 api crate 测试夹具历史缺口(aria2/jsonrpc/mcp/tests 的 TaskDto、
  task_referrer 的 TaskInfo 缺做种字段,此前测试目标无法编译)

* feat(bt): 任务详情新增做种限制编辑(三态对话框)

详情面板 BT 做种区新增「做种限制」行:三态摘要(跟随全局/不限制/
自定义)+ 编辑对话框;自定义模式按条件逐行开关,分享率小数输入
(内部千分比取整)、时长按分钟。确认后乐观更新本地任务并发
SetTaskSeedLimits 信号。copyWith 透传 4 个覆盖字段,避免进度更新
把值重置。i18n en/zh 成对新增 4 键。

* fix(bt): 终审修复——批量路径接入做种状态机、分享率基线尺度、竞态与死代码清理

引擎(review 发现 1 blocker + 2 major + 6 minor,全部修复):
- batch_pause 补做种/排队任务收集(status=3 且 seeding_status∈{1,8} 不在
  active_tasks/pending_queue,此前「暂停全部」对做种者完全无效)
- batch_resume 经 try_resume_seeding 走做种恢复,不再把已完成种子重新
  拉回下载流水线;单任务与批量共用同一分支,停止态(2..=7)均可重新做种
- uploaded_at_completion 基线改用跨会话累计尺度(DB 累计与会话计数器
  取大者):下载期暂停/续传过的任务完成瞬间 post-ratio 不再虚高误停
- last_uploaded_bytes 统一 DB 累计尺度,apply_upload_snapshot 只按
  正增量/速度刷新不活跃计时器,消除双尺度误重置
- promote/恢复 unpause 失败回滚注册并保持停止态,不再谎报做种中
- 完成注册与 reconcile 的跨运行时竞争自愈:暂停后以 SeedingManager
  内存态为准复核,消除 DB=排队/内存=活跃/torrent=暂停 的永久失配
- 删除前的 TaskDeleted 状态写入是死写(行随即被删),移除
- reset_stale_seeding 查询失败改 break,保留已收集行的重置
- progress_reporter 不再为做种任务保留状态表项(做种统计不经 reporter,
  保留只会常驻泄漏);删除无调用方的 TaskInfo::is_seeding/seed_ratio
  与 SeedingManager::active_count

桌面端:
- 补「继续做种」入口:停止态任务的悬浮操作与右键菜单显示恢复按钮,
  resumeTask 乐观守卫从仅 userStopped 扩展到全部停止态,限制达标的
  任务不再被误标为 resuming;i18n en/zh 新增 seedingResume

---------

Co-authored-by: lingdianshiren <ldsrwu@foxmail.com>
@zerx-lab

Copy link
Copy Markdown
Owner

参考本pr的实现在 #226 实现,此pr关闭

@zerx-lab zerx-lab closed this Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

✨ [Feature] BT 做种功能完整实现

4 participants