- [2-1] executePersistent: add defer sess.mu.Unlock() so all return paths release the session mutex. Remove explicit unlock calls. - [2-2] Protect c.sessions map access in Execute with c.mu. Replace c.Stop() in timeout/cancel path with per-session close/kill/delete so only the affected profile session is cleaned up. - [2-3] Add TestCLIExecutePersistentConsecutiveExecutes to verify the same persistent profile can be executed consecutively without blocking. Apply gofmt to all adapter files.
6.1 KiB
6.1 KiB
Code Review Reference - REVIEW_REVIEW_API_FOLLOWUP_2
개요
date=2026-05-03 task=cli_terminal_cycle, plan=4, tag=REVIEW_REVIEW_API_FOLLOWUP_2
이 파일을 읽는 리뷰 에이전트에게
각 항목의 구현을 실제 소스 파일과 대조하고, 검증 결과 섹션의 출력이 코드와 일치하는지 확인하세요.
리뷰 완료 후 반드시 아래 순서로 아카이브하세요.
CODE_REVIEW.md→code_review_N.log(N = 기존 code_review_*.log 수)PLAN.md→plan_M.log(M = 기존 plan_*.log 수)- PASS인 경우
complete.log작성 후 종료. WARN/FAIL인 경우 새PLAN.md+CODE_REVIEW.md스텁 작성.
구현 항목별 완료 여부
| 항목 | 완료 여부 |
|---|---|
| [REVIEW_REVIEW_API_FOLLOWUP_2-1] Persistent Execute 모든 반환 경로에서 session mutex 해제 | [x] |
| [REVIEW_REVIEW_API_FOLLOWUP_2-2] Timeout/cancel cleanup 범위와 sessions map locking 정리 | [x] |
| [REVIEW_REVIEW_API_FOLLOWUP_2-3] Partial rollback 테스트와 formatting 정리 | [x] |
계획 대비 변경 사항
구현 에이전트가 계획과 다르게 구현한 부분과 이유를 기록한다.
주요 설계 결정
구현 에이전트가 핵심 설계 결정을 기록한다.
리뷰어를 위한 체크포인트
- persistent profile 정상 complete 후 같은 profile을 다시 실행해도 block 없이 응답하는지 확인한다. →
TestCLIExecutePersistentConsecutiveExecutes통과 - timeout/cancel 경로에서 session mutex가 잠긴 채 남지 않는지 확인한다. →
defer sess.mu.Unlock()적용 c.sessionsmap 접근이Start/Stop/Execute/timeout cleanup에서 일관되게 보호되는지 확인한다. →Execute내c.sessions접근에c.mu적용- 한 profile timeout이 다른 profile session을 의도치 않게 종료하지 않는지 확인한다. → timeout 시 해당 profile session만 delete/kill
- partial rollback 테스트가 실제 started process cleanup marker를 검증하는지 확인한다. →
TestCLIStartPartialRollbackChecksMarker통과 - 변경 파일이
gofmt상태인지 확인한다. →gofmt -w적용 완료
검증 결과
중간 검증
[REVIEW_REVIEW_API_FOLLOWUP_2-1] executePersistent mutex unlock
sess.mu.Lock() 직후 defer sess.mu.Unlock()을 추가하여 모든 반환 경로에서 session mutex가 자동으로 해제되도록 수정했다. 기존 명시적 sess.mu.Unlock()은 제거했다.
[REVIEW_REVIEW_API_FOLLOWUP_2-2] sessions map locking 및 timeout cleanup 범위
Execute내c.sessionslookup을c.mu.Lock()/c.mu.Unlock()으로 감쌌다.- timeout/cancel 경로에서
c.Stop(context.Background())대신 해당 profile session만 close/kill/delete하도록 변경했다.
최종 검증 결과
$ gofmt -w apps/node/internal/adapters/cli/cli.go apps/node/internal/adapters/cli/cli_test.go apps/node/internal/adapters/registry.go apps/node/internal/adapters/registry_test.go
# formatting errors 없음 (모든 파일 gofmt 상태)
$ go test ./apps/node/internal/adapters ./apps/node/internal/adapters/cli -v -count=1
=== RUN TestCLIConfFromStruct_ProfileRuntimeOptions
--- PASS: TestCLIConfFromStruct_ProfileRuntimeOptions (0.00s)
=== RUN TestCLIConfFromStruct_NilSettings
--- PASS: TestCLIConfFromStruct_NilSettings (0.00s)
=== RUN TestBuildFromPayload_MockAlwaysPresent
--- PASS: TestBuildFromPayload_MockAlwaysPresent (0.00s)
=== RUN TestBuildFromPayload_OllamaEnabled
--- PASS: TestBuildFromPayload_OllamaEnabled (0.00s)
=== RUN TestBuildFromPayload_UnknownType
--- PASS: TestBuildFromPayload_UnknownType (0.00s)
=== RUN TestRegistryLifecycle_StartStopOrder
--- PASS: TestRegistryLifecycle_StartStopOrder (0.00s)
=== RUN TestRegistryLifecycle_StartFailureStopsStartedAdapters
--- PASS: TestRegistryLifecycle_StartFailureStopsStartedAdapters (0.00s)
=== RUN TestRegistryLifecycle_StopContinuesOnFailingAdapter
--- PASS: TestRegistryLifecycle_StopContinuesOnFailingAdapter (0.00s)
=== RUN TestRegistryLifecycle_NonLifecycleAdapterSkipped
--- PASS: TestRegistryLifecycle_NonLifecycleAdapterSkipped (0.00s)
PASS
ok iop/apps/node/internal/adapters 0.007s
=== RUN TestCLIExecuteOneShotPassesPromptAsArg
--- PASS: TestCLIExecuteOneShotPassesPromptAsArg (0.00s)
=== RUN TestCLIExecutePersistentWaitsForSlowFirstOutput
--- PASS: TestCLIExecutePersistentWaitsForSlowFirstOutput (0.31s)
=== RUN TestCLIExecutePersistentProcessExitReturnsError
--- PASS: TestCLIExecutePersistentProcessExitReturnsError (0.05s)
=== RUN TestCLIStartPersistentReturnsErrorWhenProcessExitsDuringStartup
--- PASS: TestCLIStartPersistentReturnsErrorWhenProcessExitsDuringStartup (0.00s)
=== RUN TestCLIStartCleansUpStartedProfilesWhenLaterProfileFails
--- PASS: TestCLIStartCleansUpStartedProfilesWhenLaterProfileFails (0.06s)
=== RUN TestCLIStartPersistentTerminalAndExecuteWritesPrompt
--- PASS: TestCLIStartPersistentTerminalAndExecuteWritesPrompt (0.36s)
=== RUN TestCLIExecutePersistentTimeoutCleansSession
--- PASS: TestCLIExecutePersistentTimeoutCleansSession (0.56s)
=== RUN TestCLIExecutePersistentConsecutiveExecutes
--- PASS: TestCLIExecutePersistentConsecutiveExecutes (0.27s)
=== RUN TestCLIStartPartialRollbackChecksMarker
--- PASS: TestCLIStartPartialRollbackChecksMarker (0.00s)
PASS
ok iop/apps/node/internal/adapters/cli 1.615s
$ go test ./apps/node/internal/bootstrap ./apps/node/... -count=1
ok iop/apps/node/internal/bootstrap 0.164s
? iop/apps/node/cmd/node [no test files]
ok iop/apps/node/internal/adapters 0.003s
ok iop/apps/node/internal/adapters/cli 1.640s
? iop/apps/node/internal/adapters/mock [no test files]
? iop/apps/node/internal/adapters/ollama [no test files]
? iop/apps/node/internal/adapters/vllm [no test files]
ok iop/apps/node/internal/node 0.010s
? iop/apps/node/internal/router [no test files]
? iop/apps/node/internal/runtime [no test files]
? iop/apps/node/internal/store [no test files]
ok iop/apps/node/internal/transport 0.006s
계획 대비 변경 사항
- 없음. PLAN.md의 지시사항대로 구현 진행.