LabHub
배우기 러닝패스 코스

멱등성 — 두 번 눌러도 한 번만 결제되게 · 멈췄던 워커가 돌아와 결과를 덮어썼다 · 실습

멈췄던 워커가 돌아와 결과를 덮어썼다

LabHub 에서 이어서 보기

목표

SQLite에서 소유권 임대와 증가하는 fencing token을 구현합니다.

왜 중요한가

워커 A가 일을 가져간 뒤 멈췄다. 임대가 만료되자 B가 같은 일을 가져가 완료했지만 뒤늦게 살아난 A도 완료 결과를 썼다. 임대 시간을 정하는 것만으로 오래된 작업자의 쓰기를 막을 수 없다. 저장 시점에도 소유자와 세대 번호를 확인해야 한다.

단계

1. /root/work/idem-fencing-lab/service.py에서 init_db(path)는 jobs(id TEXT PRIMARY KEY, owner TEXT, until REAL NOT NULL DEFAULT 0, fence INTEGER NOT NULL DEFAULT 0, result TEXT, done INTEGER NOT NULL DEFAULT 0)를 멱등 생성합니다.

처음 한 번 준비하세요. 기존 파일은 덮어쓰지 않습니다.

mkdir -p /root/work/idem-fencing-labtest -e /root/work/idem-fencing-lab/service.py || cp /opt/fixtures/ten_labs/idem-fencing-lab/service.py /root/work/idem-fencing-lab/service.pycd /root/work/idem-fencing-lab

2. /root/work/idem-fencing-lab/service.py에서 enqueue(path, job_id)는 없는 id를 기본 상태로 넣고 True, 이미 있으면 상태를 바꾸지 않고 False입니다.

3. /root/work/idem-fencing-lab/service.py에서 state(path, job_id)는 행을 id, owner, until, fence, result, done 키의 dict로 반환하고 없으면 None입니다.

4. /root/work/idem-fencing-lab/service.py에서 claim(path, job_id, owner, now, ttl)는 ttl<=0이면 ValueError입니다. 없는 작업·완료된 작업·until>now인 작업은 None입니다. 나머지는 owner와 until=now+ttl을 저장하고 fence를 1 올려 새 fence를 반환합니다.

5. /root/work/idem-fencing-lab/service.py에서 renew(path, job_id, owner, fence, now, ttl)는 ttl<=0이면 ValueError입니다. owner·fence가 일치하고 done=0, until>now일 때만 until=now+ttl로 바꾸어 True, 아니면 False입니다.

6. /root/work/idem-fencing-lab/service.py에서 complete(path, job_id, owner, fence, now, result)는 현재 임대(owner·fence 일치, done=0, until>now)일 때만 result와 done=1을 저장해 True입니다. 나머지는 False이며 기존 결과를 보존합니다.

7. /root/work/idem-fencing-lab/service.py에서 release(path, job_id, owner, fence)는 owner·fence가 같고 done=0인 행의 owner=NULL, until=0으로 바꾸고 True입니다. fence는 보존합니다. 나머지는 False입니다.

8. /root/work/idem-fencing-lab/service.py에서 claim_many(path, job_id, owners, now, ttl)는 ThreadPoolExecutor로 각 owner의 claim을 동시에 호출해 입력 순서의 반환값 리스트를 돌려줍니다. 새 작업은 딱 하나만 fence를 얻고 나머지는 None이어야 합니다.

참고

8단계

  1. 임대 상태 테이블을 만든다
  2. 최초 작업만 등록한다
  3. 현재 상태를 읽는다
  4. 만료된 임대를 원자적으로 가져간다
  5. 현재 세대만 임대를 갱신한다
  6. 오래된 완료를 거절한다
  7. 현재 워커만 임대를 반납한다
  8. 동시 claim에 승자는 하나다