Skip to content

后台任务、检查点与发布回归:练习答案 ​

参考实现 ​

独立运行(包含完整最小状态机):

python
state = {"epoch":0, "status":"queued", "result":None}
def claim():
    state["epoch"] += 1
    state["status"] = "running"
    return state["epoch"]
def commit(epoch, value):
    if epoch != state["epoch"] or state["status"] != "running": return False
    state.update(status="completed", result=value)
    return True
x = claim()
state["status"] = "cancelled"
assert not commit(x,"late") and state["result"] is None
state["status"] = "queued"
y = claim()
assert y > x and commit(y,"ok")
print("cancel then restart")

重启不是恢复旧 worker 的提交权;epoch 必须增加。

返回正文

SQLite 取消后重启 ​

将正文账本完整块保存为同目录 jobs.py,本答案另存 cancel_answer.py 运行。真正启动第二个进程,不能用同一个字典模拟重启。

python
import subprocess,sys
from tempfile import TemporaryDirectory
from pathlib import Path
import jobs
with TemporaryDirectory() as folder:
    path=str(Path(folder)/'jobs.sqlite');db=jobs.database(path)
    with db:db.execute("INSERT INTO jobs VALUES ('j1',0,0,'queued','')")
    subprocess.run([sys.executable,jobs.__file__,path],check=True)
    with db:db.execute("UPDATE jobs SET status='cancelled',epoch=epoch+1 WHERE id='j1'")
    second=subprocess.run([sys.executable,jobs.__file__,path],capture_output=True,text=True)
    assert second.returncode!=0 and 'terminal task' in second.stderr
    assert db.execute("SELECT step,status,result FROM jobs WHERE id='j1'").fetchone()==(1,'cancelled','retrieved evidence')
    db.close()
print('cancelled task remains at persisted step 1 after process restart')

用心记录每一步成长