Skip to content

feat(durable): define generation-fenced conversion attempt record - #371

Open
seonghobae wants to merge 5 commits into
mainfrom
feat/conversion-attempt-record-main-20260811
Open

feat(durable): define generation-fenced conversion attempt record#371
seonghobae wants to merge 5 commits into
mainfrom
feat/conversion-attempt-record-main-20260811

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Objective

Advance issue #312 with a path-disjoint durable attempt-state primitive. One claimed conversion attempt must bind immutable job/generation/attempt/lease identity, and once that attempt reaches a terminal outcome a stale or contradictory completion must not rewrite it.

Test-first state

This Draft starts intentionally RED at exact test-only head 66bcbe6f74dcad76d358b2979ba7e1a202b960cc on protected main 55d7ae8647208e301f282350f076eeddaba61d11. ConversionAttemptRecordTest requires exact attempt/job/generation/lease authority, positive generation and attempt numbers, persisted claim/completion timestamps, exact publication fencing, monotonic terminal outcomes, idempotent exact terminal replay, and fail-closed invalid input. The production types do not exist at this head, so Maven test compilation is expected to fail at that exact boundary.

Scope

New durable-domain attempt state/record plus focused tests only. This does not persist attempts, claim a broker message, replace the process-local worker, wire PR #367's lease object, schedule PR #369 retries, publish artifacts, implement cancellation, or change HTTP acceptance. It is deliberately separate from the current idempotency writer and from the outbox/retry/cancellation PR paths.

Acceptance

Observe exact-head RED -> smallest immutable production implementation -> exact-head mvn -B --no-transfer-progress verify with zero missed owned production coverage/public Javadocs -> CI/Security Scan/SAST/fuzz -> current reviews/threads/live-base refetch. Keep Draft until GREEN exact-head evidence exists. Independent write-authorized approval remains a separate protected-merge gate.

Summary by CodeRabbit

  • 새로운 기능

    • 변환 작업 시도의 영속적인 상태 관리 기능을 추가했습니다.
    • 시도 생성 시 작업, 세대 및 워커 임대 정보를 검증합니다.
    • 성공, 재시도 가능한 실패, 최종 실패 상태를 구분해 기록합니다.
    • 작업 권한을 안전하게 확인할 수 있습니다.
    • 동일한 완료 결과는 멱등적으로 처리하며, 충돌하는 변경은 거부합니다.
  • 버그 수정

    • 잘못된 식별자, 시각, 세대 또는 시도 번호 입력을 차단합니다.
    • 유효하지 않은 상태 전환과 완료 시각을 방지합니다.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ed517bdc-4455-440c-acdc-0ef3cabeb4e5

📥 Commits

Reviewing files that changed from the base of the PR and between 67a28ab and 692fd7f.

📒 Files selected for processing (2)
  • src/main/java/com/clearfolio/viewer/durable/ConversionAttemptRecord.java
  • src/test/java/com/clearfolio/viewer/durable/ConversionAttemptRecordTest.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/com/clearfolio/viewer/durable/ConversionAttemptRecord.java

📝 Walkthrough

Walkthrough

변환 시도의 영속 상태와 불변 레코드를 추가했다. 레코드는 생성 입력을 검증하고 작업·세대·lease 권한을 확인한다. 성공 또는 실패 상태로 종료하며, 동일한 종료 결과는 멱등적으로 처리한다. 관련 동작을 JUnit 테스트로 검증한다.

Changes

변환 시도 생명주기

Layer / File(s) Summary
시도 상태와 영속 레코드
src/main/java/com/clearfolio/viewer/durable/ConversionAttemptState.java, src/main/java/com/clearfolio/viewer/durable/ConversionAttemptRecord.java
CLAIMED, SUCCEEDED, RETRYABLE_FAILED, TERMINAL_FAILED 상태와 불변 레코드를 추가했다. 레코드는 시도 식별자, 작업 세대, 시도 번호, worker lease, 청구 시각, 상태 및 완료 시각을 제공한다.
생성, 권한 및 종료 동작
src/main/java/com/clearfolio/viewer/durable/ConversionAttemptRecord.java
claim은 필수 값과 양수 제약을 검증한다. authorizes는 작업·세대·lease와 상태를 확인한다. finish는 유효한 종료 상태와 완료 시각을 검증하고 동일한 종료 결과만 재호출을 허용한다.
생명주기 동작 검증
src/test/java/com/clearfolio/viewer/durable/ConversionAttemptRecordTest.java
레코드 생성, 권한 판정, 성공·실패 종료, 멱등 종료, 충돌하는 종료 및 잘못된 입력을 검증한다.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 generation-fenced 변환 시도 레코드를 정의하는 PR의 주요 변경 사항을 정확하고 간결하게 설명합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/conversion-attempt-record-main-20260811

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@seonghobae
seonghobae marked this pull request as ready for review August 11, 2026 02:08

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/main/java/com/clearfolio/viewer/durable/ConversionAttemptRecord.java (1)

129-144: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

JavaDoc에 null 후보 동작을 명시하세요.

authorizescandidateJobId 또는 candidateLeaseId가 null이면 false를 반환합니다. 이 동작은 필드가 항상 non-null이기 때문에 성립합니다. 현재 JavaDoc은 이 계약을 기술하지 않습니다. 향후 비교 순서를 바꾸는 리팩터링이 NPE를 유발할 수 있습니다. 계약을 문서로 고정하세요.

📝 제안 변경
      * `@param` candidateJobId candidate permanently reserved job identifier
      * `@param` candidateGeneration candidate lifecycle generation
      * `@param` candidateLeaseId candidate worker-lease identifier
-     * `@return` true only when job, generation, and lease all match exactly
+     * `@return` true only when job, generation, and lease all match exactly;
+     *         false when a candidate identifier is null
      */
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/clearfolio/viewer/durable/ConversionAttemptRecord.java`
around lines 129 - 144, Update the JavaDoc for
ConversionAttemptRecord.authorizes to explicitly state that it returns false
when candidateJobId or candidateLeaseId is null, while retaining the existing
exact-match contract for non-null candidates.
src/test/java/com/clearfolio/viewer/durable/ConversionAttemptRecordTest.java (1)

136-139: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

예외 메시지를 함께 검증하세요.

finish는 서로 다른 두 원인으로 IllegalArgumentException을 던집니다. 하나는 비종료 상태이고, 다른 하나는 완료 시각이 청구 시각보다 앞선 경우입니다. 현재 테스트는 예외 타입만 확인합니다. 두 메시지가 뒤바뀌어도 테스트는 통과합니다. 메시지를 함께 검증하면 실패 원인을 정확히 고정할 수 있습니다.

♻️ 제안 변경
-        assertThrows(IllegalArgumentException.class,
-                () -> record.finish(ConversionAttemptState.CLAIMED, claimedAt));
-        assertThrows(IllegalArgumentException.class,
-                () -> record.finish(ConversionAttemptState.SUCCEEDED, claimedAt.minusNanos(1L)));
+        assertEquals("terminalState must be terminal",
+                assertThrows(IllegalArgumentException.class,
+                        () -> record.finish(ConversionAttemptState.CLAIMED, claimedAt)).getMessage());
+        assertEquals("completionTime must not precede claimedAt",
+                assertThrows(IllegalArgumentException.class,
+                        () -> record.finish(ConversionAttemptState.SUCCEEDED, claimedAt.minusNanos(1L)))
+                        .getMessage());

동일한 방식을 claimFailsClosedForMissingOrNonPositiveAuthoritygenerationattempt 검증에도 적용할 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/test/java/com/clearfolio/viewer/durable/ConversionAttemptRecordTest.java`
around lines 136 - 139, Update the assertions in ConversionAttemptRecordTest
around finish so each IllegalArgumentException also verifies the expected
message for the non-terminal state and the completion timestamp preceding
claimedAt. Apply the same message-assertion pattern to generation and attempt
validation in claimFailsClosedForMissingOrNonPositiveAuthority, preserving the
existing exception-type checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/main/java/com/clearfolio/viewer/durable/ConversionAttemptRecord.java`:
- Around line 129-144: Update the JavaDoc for ConversionAttemptRecord.authorizes
to explicitly state that it returns false when candidateJobId or
candidateLeaseId is null, while retaining the existing exact-match contract for
non-null candidates.

In
`@src/test/java/com/clearfolio/viewer/durable/ConversionAttemptRecordTest.java`:
- Around line 136-139: Update the assertions in ConversionAttemptRecordTest
around finish so each IllegalArgumentException also verifies the expected
message for the non-terminal state and the completion timestamp preceding
claimedAt. Apply the same message-assertion pattern to generation and attempt
validation in claimFailsClosedForMissingOrNonPositiveAuthority, preserving the
existing exception-type checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0aec4837-552e-481c-8a65-aa6651979aa2

📥 Commits

Reviewing files that changed from the base of the PR and between 55d7ae8 and 67a28ab.

📒 Files selected for processing (3)
  • src/main/java/com/clearfolio/viewer/durable/ConversionAttemptRecord.java
  • src/main/java/com/clearfolio/viewer/durable/ConversionAttemptState.java
  • src/test/java/com/clearfolio/viewer/durable/ConversionAttemptRecordTest.java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant