같은 날 완료한 작업도 같은 ID를 계속 차지했다

주간 질문 분석의 중복을 막기 위해 봇 ID, 주차, 실행 날짜를 합친 jobId를 사용했다. 그런데 완료한 잡의 기록이 큐에 남아 있으면, 같은 날 같은 주차를 다시 채우는 요청도 같은 ID가 된다. 동시에 실행할 작업을 합치려던 규칙이 완료 이후의 재투입까지 막을 수 있었다.

변경은 이 날짜 기반 ID를 제거했다. 질문 분석 기능 브랜치에서 자동 분석과 백필 경로에 적용한 수정이며, 현재 main에는 해당 기능 소스가 없다. 실행 이력을 남길 기간과 중복을 차단할 기간을 같은 값으로 표현하던 구간을 나눈 사례다.

다음은 키 구성을 문자열 연결로 풀어 쓴 옵션 비교다.

// 이전: 완료 잡이 남아 있으면 당일 같은 ID로 재투입하기 어렵다.
jobId: 'qa-' + botId + '-' + weekStart + '-' + runDate

// 변경: 동일 봇·주차의 진행 중 작업을 합친다.
deduplication: { id: 'qa-' + botId + '-' + weekStart }

중복 차단이 풀려도 대상 선정 조건은 남는다

새 옵션은 TTL을 지정하지 않은 simple deduplication이다. 같은 봇·주차의 잡이 대기하거나 처리 중일 때 중복을 차단하고, 완료·실패하면 키를 해제하는 수명을 사용한다. 완료 기록을 보존하면서도 진행 중 잠금이 풀린 뒤 같은 날 다시 넣을 수 있다.

  1. 새 질문 확인

    기존 분석의 analyzed_until 이후이면서 대상 주차 종료 전인 질문이 있는지 확인한다.

  2. 진행 중이면 합치기

    같은 봇·주차의 deduplication 키로 큐에 넣는다.

  3. 완료 뒤 다시 대상 확인

    키가 풀려도 신규 질문 조건을 통과한 자동·백필 대상만 재투입한다.

따라서 완료한 모든 분석을 무조건 다시 실행하는 변경은 아니다. 별도의 수동 강제 분석은 시각이 붙은 고유 job ID와 regenerating_at 차단을 사용하므로, 모든 진입 경로가 하나의 중복 키를 공유하는 것도 아니다.

스케줄러 테스트는 mock 큐에 전달한 deduplication ID와 jobId가 없는 것을 검사한다. Redis 큐에서 실제 두 요청을 동시에 넣거나 완료 후 재투입한 통합 검증과는 범위가 다르다. 이 변경의 책임은 자동·백필 잡의 중복 차단 수명이며, 외부 AI 요청을 정확히 한 번 실행한다는 보장은 아니다.