协同办公

Odoo 任务依赖为什么重点不在“连线”,而在防环与复制边界:dependency 机制讲透

很多团队做任务依赖时只盯着甘特图连线,但 Odoo 官方测试更在意三件事:能不能防止循环依赖、复制项目时依赖关系如何映射、跨项目依赖是否应该原样保留。

协同办公
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说结论

Odoo 的任务依赖不是画一条线那么简单。

project.task 和官方 test_task_dependencies.py 看,系统真正关心的是三件事:

  • 依赖关系不能形成环
  • 复制项目或任务树时,依赖要尽量映射到新的副本上
  • 如果另一端不在当前复制范围内,依赖关系就不该被粗暴改写

所以最准确的总结是:

Odoo 任务依赖的核心不是“显示关系”,而是“保证关系仍然可执行”。


为什么循环依赖必须被硬性阻止

_check_no_cyclic_dependencies() 里直接调用 _has_cycle('depend_on_ids'),发现环就抛 ValidationError

这一步不能妥协。

因为一旦允许:

  • A 依赖 B
  • B 又依赖 A

任务系统就无法再可靠判断:

  • 谁先做
  • 谁被阻塞
  • 哪个状态变化应触发谁

在协同系统里,环路不是小瑕疵,而是把执行顺序彻底打烂的结构性错误。


为什么 is_blocked_by_dependences() 只盯 closed states

源码里判断阻塞时,并不是看“依赖任务有没有开始”,而是看依赖任务是否都进入 closed states。

这背后的语义很清楚:

  • 依赖任务只要没关闭,就仍然算前置未完成
  • 阻塞关系关注的是“能不能开始下一步”,不是“对方看起来忙没忙”

这种定义虽然朴素,但非常稳定。


复制项目时,为什么依赖要尽量指向新副本

官方测试 test_duplicate_project_with_task_dependencies() 明确要求:

  • 原项目里 task1 依赖 task2
  • 复制整个项目后,副本里的 task1_copy 应依赖 task2_copy

也就是说,复制范围内的依赖关系应尽量闭合在新世界里。

这是对的。

否则复制项目的结果会非常别扭:

  • 新项目任务还依赖旧项目任务
  • 两个项目的执行链被粘在一起
  • 后续统计和责任边界全部混乱

为什么跨复制边界的依赖不能乱改

同一组测试也验证了另一件事:

如果依赖另一端根本不在这次复制范围里,就不要强行重定向。

这说明 Odoo 的策略不是“见依赖就全部重写”,而是:

  • 在复制闭包内部,尽量映射到新副本
  • 超出复制闭包的,保留原关系

这个边界判断非常成熟,因为它保住了语义真实。


为什么子任务树复制时也要重建依赖链

test_duplicate_project_with_subtask_dependencies() 展示了一个很实际的场景:

  • 父任务下面有节点树
  • 节点之间有 dependency
  • 复制整棵树后,依赖要重建在新节点之间

这说明 Odoo 不是只会复制层级关系,还会尽量把执行关系一起带过去。

对 SOP 类任务模板尤其关键。

否则你得到的只是看起来像的结构,真正的先后约束却全丢了。


最容易踩的误区

误区一:把依赖当视觉装饰

真正麻烦的是后端语义,不是前端画线。

误区二:复制项目时忘记检查依赖是否仍指向旧任务

如果自定义 copy 逻辑破坏了映射,项目会出现隐性跨项目耦合。

误区三:允许环路,只想靠人工约定解决

一旦规模上来,人工约定几乎一定失效。


排错顺序

如果用户说“任务一直被阻塞”或“复制后依赖乱了”,建议查:

  1. 项目是否启用了 allow_task_dependencies
  2. 依赖链里是否存在环路或被自定义数据写坏
  3. 复制范围内任务是否都生成了新副本
  4. 新副本依赖是否正确指向 copy,而不是旧项目原任务
  5. 跨项目残留依赖是否本来就应该存在

一句话记忆

Odoo 任务依赖的难点从来不是连线,而是让依赖在校验、复制和执行中始终保持真实。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。