얼쑤에서 같은 녹음의 분석을 다시 요청하면 세션을 PENDING으로 바꾸고 시도 번호를 올립니다. 실행기는 커밋 뒤에 작업을 받습니다. 상태가 반영되기 전 작업이 시작되면 새 시도를 읽을 수 없기 때문입니다.
커밋과 작업 제출 사이에 실패할 수 있는 지점이 남습니다. 실행기의 대기열이 가득 차면 작업을 넘길 수 없지만, DB에는 이미 진행 중인 시도가 기록돼 있습니다. 이때 호출자에게 제출 실패만 돌려주면 상태를 읽는 쪽에는 아직 시작하지 못한 작업이 진행 중인 것처럼 보입니다.
커밋한 시도만 실패로 갱신
제출에서 예외가 나면 시작한 시도 번호와 시각을 사용해 해당 시도만 FAILED와 SERVER_ERROR로 바꾸도록 했습니다. 이미 결과가 기록됐거나 다른 시도가 진행 중이면 상태·시도 조건을 만족하지 못해 갱신되지 않습니다. 원래 제출 예외는 다시 던지고, 컨트롤러는 실행기 거절을 받아 503으로 응답합니다.
실패 처리 범위도 확인했습니다. Kotlin에서는 호출 대상이 IOException을 던질 수 있어, RuntimeException만 받던 경계에서는 이 시도가 SERVER_ERROR로 남지 않았습니다. Exception을 받도록 바꾸고, 실행기 거절과 IOException을 각각 주입해 두 번째 시도에서 시작한 세 번째 시도가 FAILED와 SERVER_ERROR가 되는지 검사했습니다.
컨트롤러 검사에서는 제출에 RejectedExecutionException을 넣자 HTTP 503이 반환되고 새로 시작한 시도 2의 실패가 기록됐습니다. 같은 위치에 예상 밖의 IllegalStateException을 넣은 검사는 HTTP 500을 받았습니다. 작업을 넘기지 못했을 때 상태를 정리하는 범위는 넓게 두되, 호출자에게 잠시 후 다시 요청하라고 답하는 예외는 실행기 거절로 한정했습니다.
정리 오류를 원래 예외에 보존
DB가 응답하지 않으면 실패를 기록하는 갱신도 예외를 던질 수 있습니다. 이 예외가 제출 실패를 덮으면, 호출자는 대기열 거절을 503으로 처리할 단서를 잃습니다. 정리에서 난 예외는 원래 예외에 addSuppressed로 붙이고 최초 예외를 다시 던졌습니다.
테스트에서 실행기 거절과 DB 갱신 오류를 함께 주입했을 때, 밖으로 나온 예외는 실행기 거절이었고 정리 오류는 그 예외의 부가 원인에 남았습니다. 이 검사는 작업 제출과 보상 갱신을 제어한 대역에서 수행했습니다. 보상할 수 없어 시도가 PENDING에 남은 경우는 이후 상태 조회에서 적용하는 기존 마감 판정으로 끝나도록 설계했습니다.
제출된 뒤 작업 스레드 안에서 실패하는 경로에는 별도의 예외 기록이 있습니다. 그 경로에서는 이미 제출 호출이 돌아왔으므로, 여기서 확인한 제출 실패 보상을 실행하지 않습니다. 작업을 받아들였는지와 실제 분석이 끝났는지를 구분해 기록할 수 있습니다.

댓글
댓글과 반응은 GitHub 계정으로 로그인해 남길 수 있어요.