Jobs: with keep_completed, success and error records outlive the rows they describe
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 3/5
- 预计耗时
- 半天
- 新手友好度
- 65/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- mysql, python
调研方向
Start from Job.refresh(), specifically step 3, which removes stale job records only when they are older than stale_timeout and their keys are missing from key_source. Run the reproduction in the issue to see that success rows for deleted keys survive refresh(stale_timeout=0). Done means those orphaned success and error rows are removed without waiting for the timeout, while pending rows keep the age check. The issue also offers an alternative change to the meaning of stale_timeout=0, so check with maintainers which one they want.
由索引模型根据 Issue 内容生成。
描述
Summary
With config.jobs.keep_completed = True, a table's jobs table keeps a success record for every computed key. When upstream rows are deleted and the cascade removes the computed rows, their success records stay. jobs.refresh() does not remove them until they are older than stale_timeout (3600 s by default). Passing stale_timeout=0 skips the cleanup entirely instead of forcing it. For up to an hour, then, status counts read from the jobs table overstate what the table holds. Records with status='error' for keys that no longer exist behave the same way.
Reproduction
DataJoint 2.3.5.dev2 (master), MySQL 8.0:
import datajoint as dj
dj.config.jobs.keep_completed = True
schema = dj.Schema("scratch_jobs")
@schema
class Raw(dj.Manual):
definition = """
raw_id : int32
---
v : float32
"""
@schema
class Proc(dj.Computed):
definition = """
-> Raw
---
w : float32
"""
def make(self, key):
self.insert1(dict(key, w=2 * (Raw & key).fetch1("v")))
def counts():
j = Proc.jobs
return {s: len(j & f"status='{s}'") for s in ("pending", "reserved", "success", "error")}
Raw.insert([dict(raw_id=i, v=float(i)) for i in range(3)])
Proc.populate(reserve_jobs=True)
print("after populate:", "rows", len(Proc()), "jobs", counts())
(Raw & "raw_id = 0").delete(prompt=False)
print("after deleting raw_id=0:", "rows", len(Proc()), "key_source", len(Proc.key_source), "jobs", counts())
print("refresh:", Proc.jobs.refresh())
print("refresh(stale_timeout=0):", Proc.jobs.refresh(stale_timeout=0), "jobs", counts())
Output:
after populate: rows 3 jobs {'pending': 0, 'reserved': 0, 'success': 3, 'error': 0}
after deleting raw_id=0: rows 2 key_source 2 jobs {'pending': 0, 'reserved': 0, 'success': 3, 'error': 0}
refresh: {'added': 0, 'removed': 0, 'orphaned': 0, 're_pended': 0}
refresh(stale_timeout=0): {'added': 0, 'removed': 0, 'orphaned': 0, 're_pended': 0} jobs {'pending': 0, 'reserved': 0, 'success': 3, 'error': 0}
Two rows exist and three successes are recorded. After a larger delete (removing a parameter set, say), anything that reports progress from the jobs table shows completed work that no longer exists, for an hour.
Where it comes from
Job.refresh() step 3 removes only records older than stale_timeout whose keys are no longer in key_source. The age condition makes sense for pending records, which can race a key_source that is still being filled, and the setting's description says so: "Seconds before pending job is checked for staleness". It is applied to every status except ignore, though, including success and error. And stale_timeout=0 means "skip this step", so there is no way to request the cleanup now.
Proposal
In refresh(), remove success and error records whose keys are in neither key_source nor the target, regardless of age. Keep the age condition for pending, which it was written for. Neither kind of record describes anything that exists, and neither is retried. Alternatively, make stale_timeout=0 mean "no grace period" rather than "skip", and give the skip its own value (None).
- 主要语言
- Python
- 星标
- 197
- 派生
- 98
- 平均合并
- 15 小时 31 分钟
- 30 天内合并 PR
- 9
环境准备
- 提供 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
datajoint/datajoint-python 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 70/100
datajoint/datajoint-python#1581 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 76/100
datajoint/datajoint-python#1539 · 3 条评论 ·
维护者通常 1 天内回复
-
_job_start_time records the populating host's local time, with no zone可能已有人在做 @dimitri-yatsenko 今天认领。 未关闭
datajoint/datajoint-python#1584 · 已指派 1 人 ·
维护者通常 1 天内回复
-
database.name should namespace schema names on MySQL, as it does on PostgreSQL可能已有人在做 @dimitri-yatsenko 于 3 天前认领。 未关闭feature
难度 4/5 3-5 天 新手友好度 15/100
datajoint/datajoint-python#1582 ·
维护者通常 1 天内回复
-
难度 3/5 1-2 天 新手友好度 40/100
datajoint/datajoint-python#1580 ·
维护者通常 1 天内回复
查看 datajoint/datajoint-python 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 78/100
huggingface/peft#3955 ·
维护者通常 1 天内回复
-
author-page correction
难度 2/5 1-3 小时 新手友好度 60/100
acl-org/acl-anthology#10313 ·
维护者通常 1 天内回复
-
anime duplicate exception request-theme
难度 1/5 1 小时以内 新手友好度 82/100
LizardByte/ThemerrDB#8926 · 1 条评论 ·
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 76/100
huggingface/transformers#49556 ·
维护者通常 1 天内回复
-
area/security bug
难度 2/5 1-3 小时 新手友好度 82/100
mozilla-ai/otari#2245 ·
维护者通常 1 天内回复