Skip to content
isdnetworks
Go back

작업 완료와 대상 상태의 분리

(수정됨)

주소 해제 작업이 여러 건 멈춰 있었고 대상은 이미 위탁 지갑 쪽에서 영구 폐기된 것들이었다. 다시 보내도 실패할 것이 뻔했으므로 jobs 를 UPDATE 로 완료 처리하고 끝내려 했다.

UPDATE jobs SET completed_at = NOW() WHERE id IN (...);

Table of contents

Open Table of contents

멈춘 작업과 완료 처리

넣기 전에 대상 쪽을 봤다.

SELECT status FROM wallet_addresses WHERE id IN (...);

release_fail 과 rotate_fail 이었다. jobs 를 완료로 바꾸면 이 status 도 바뀌는지가 물음이었다.

grep 으로 코드를 따라가니 실행기의 완료 콜백에서만 그 기록이 일어났다.

// AddressJobExecutor.php
private function jobCompleted($job, $result)
{
    $this->addAddressStatus($coin, $addressId, $job, $result);
}

private function addAddressStatus($coin, $addressId, $job, $result)
{
    $addr->status = "{$job}_{$result}";   // release_success
    $this->addresses->save($addr);
}

jobs 를 직접 UPDATE 하면 jobCompleted 가 안 돌아 이 체인이 통째로 건너뛴다.

상태를 기록하는 자리

status 를 쓰는 자리를 grep 으로 찾아보니 addAddressStatus 하나뿐이고 다른 데서는 읽기만 했다.

값의 형식은 "{$job}_{$result}" 로 작업 종류와 결과를 밑줄로 붙인 것이었다. 직접 넣으려면 그 형식을 정확히 맞춰야 하고 안 맞추면 읽는 쪽에서 걸린다.

작업만 손대면 상태가 엇갈린다

작업 행만 완료로 바꾸면 작업은 끝났는데 대상 상태는 처리 전 값으로 남는다. 두 값이 엇갈린 채로 남으면 나중에 어느 쪽을 믿을지가 문제가 된다.

이 엇갈림은 오류로 드러나지 않고 SELECT 했을 때만 보인다. 그래서 시간이 지난 뒤에 다른 사람이 발견하고 원인을 다시 찾게 된다.

두 선택지와 실패 경로의 길이

선택지는 job 과 대상을 함께 직접 UPDATE 하는 것과 실행기를 태워서 정상 경로로 끝내는 것 둘이었다. 앞의 것은 빠르고 뒤의 것은 부수 처리까지 함께 돈다.

실패 경로를 따라가 보니 성공 경로보다 단계가 하나 더 있었는데 실패 사유를 분류하는 단계였다. 이 건은 실행기 대신 직접 갱신 쪽을 골랐다. 이유는 그 분류값까지 맞추기 어려워서다. 대신 두 표를 한 트랜잭션에서 함께 UPDATE 하기로 했다.

조치 전에 정해야 하는 이유

이 결정은 첫 쿼리를 돌리기 전에 해야 했다. 작업 행을 먼저 완료로 바꾸면 실행기로 태우는 선택지가 사라지기 때문이다.

같은 모양의 판단이 이후에도 반복됐는데 확인 방법은 매번 같았다. 그 상태 컬럼을 누가 쓰는지 코드에서 찾아보면 조치 전에 알 수 있다.

정리


Share this post on:

Previous Post
승인이 거른 열두 건
Next Post
급할 때의 경로