Skip to content
isdnetworks
Go back

후처리를 어디에 넣나

(수정됨)

출고 이후에 shipped_at 을 읽어 다른 곳에 반영하는 처리를 붙여야 했다. addShipment() 의 끝에 넣었더니 읽으려던 값이 null 이거나 옛 값이었다.

Table of contents

Open Table of contents

원인 — 한 동작이 두 단계로 나뉜 구조

코드를 따라가니 출고가 한 번에 끝나지 않고 두 단계로 나뉘어 있었다. 운송장을 등록하고 CompleteShipmentJob 을 dispatch() 하는 것이 앞 단계이고 출고 완료 처리는 그 잡에서 돌고 있었다.

내가 넣은 자리는 앞 단계의 끝이라 외부가 아직 최종 처리를 하기 전이었다. 읽으려던 값은 뒤 단계 이후에 생기므로 그 시점에는 존재할 수 없었다.

조치 — 삽입 지점과 완료의 정의

두 가지 방법이 있었는데 앞 단계 끝에 두고 값이 비면 재시도하는 것과 후처리를 CompleteShipmentJob 이 성공한 뒤로 옮기는 것이다. 뒤쪽을 골랐다. 이유는 재시도는 값이 언제 생길지 모르는 채로 기다리는 것이라서다. 대신 후처리가 큐 지연만큼 늦어지는 것을 감수했다. 옮기니 값이 정상으로 읽혔고 이 문제의 전부는 출고했다는 말이 어느 시점을 뜻하느냐였다.

addShipment() 라는 이름이 배송을 추가한다는 뜻이라 그것이 출고인 줄 알았는데 실제로는 첫 단계까지였다. 비동기로 다음 단계를 등록하는 구조에서는 함수가 반환됐다고 그 동작이 끝난 것이 아니다.

검증 — 경로마다 다른 갱신 조건

이 김에 syncDelivery() 호출을 경로별로 훑어보니 조건이 제각각이었다. addShipment() 에서는 항상 부르고 cancelShipment() 에서는 옛 데이터일 때만 부르고 extendSchedule() 에서는 부르지 않았다.

그러면 deliveries 가 최신이라는 전제를 쓰는 기능은 어느 경로를 거쳐 왔느냐에 따라 성립하기도 하고 안 하기도 한다. 이 차이는 기능 쪽 코드만 봐서는 드러나지 않는다.

주의 — 전제를 만드는 쪽과 쓰는 쪽

그래서 최신 값을 전제하는 기능을 붙일 때 그 경로가 갱신을 하는지 먼저 확인하기로 했다. 안 하는 경로라면 그 경로에 syncDelivery() 를 추가하는 안과 후처리에서 직접 최신 값을 조회하는 안이 있다.

앞의 안은 그 경로의 다른 동작에까지 영향을 줄 수 있어서 뒤의 안이 안전했다. 전제를 만드는 쪽을 고치는 것보다 전제를 쓰는 쪽에서 닫는 편이 영향 범위가 좁다.

배경 — 증명하지 못한 자리

한 가지는 확인을 못 했는데 채널이 실제로 어느 시점에 shipped_at 을 확정하는지였다. 우리 쪽 코드는 전부 읽었지만 그쪽 동작은 API 문서에 없어서 updated_at 관측으로 추정만 했다.

검증을 시도하다 시험 계정 문제로 실패했고 그 사실도 NOTES.md 에 같이 적었다. 못 한 것을 안 한 것처럼도 한 것처럼도 쓰지 않는 것이 이 기록의 조건이었다.

정리


Share this post on:

Previous Post
연동 방향을 먼저 확인한다
Next Post
한 번도 채워진 적 없는 컬럼