feat(phase-07): server lifecycle — wire JNA/Panama to AbstractChromaRuntime#79
Conversation
Two plans in 2 waves: Plan 01 retrofits JNA and Panama backends to extend AbstractChromaRuntime, Plan 02 adds integration tests covering the full server lifecycle error matrix.
- Replace `implements ChromaRuntime` with `extends AbstractChromaRuntime` - Implement readBorrowedString, readOwnedString, readLastError abstract methods - Route all FFI calls through callFfiHandle, callFfiBorrowedString, callFfiVoid - Wire ServerSession with method-reference callbacks for port, address, persistPath - Remove old lastError(String) helper and verbose try-catch blocks
…time - Replace `implements ChromaRuntime` with `extends AbstractChromaRuntime` - Implement readBorrowedString, readOwnedString, readLastError abstract methods - Route all FFI calls through callFfiHandle, callFfiBorrowedString, callFfiVoid - Wire ServerSession with method-reference callbacks for port, address, persistPath - Preserve Windows arena close workaround - Remove old lastError(String) helper and verbose try-catch blocks - Update AbstractChromaRuntime comment to reflect wired state
- Add 07-01-PLAN.md and 07-01-SUMMARY.md - Update STATE.md with phase 7 position and decisions - Update ROADMAP.md progress for phase 7
…fecycle # Conflicts: # .planning/ROADMAP.md # .planning/STATE.md
- Restore 07-01-PLAN.md, 07-01-SUMMARY.md, 07-02-PLAN.md - Restore context, research, validation, and discussion log files - Files were lost during merge conflict resolution
- 6 test methods per backend covering full error matrix - Happy path: start, accessors, stop, close with ServerConfigBuilder - Double close idempotency via AtomicBoolean CAS - Accessors throw IllegalStateException after close - Null, empty, and malformed config rejection - Ephemeral ports via findFreePort(), @tempdir for isolation
- Add 07-02-SUMMARY.md with self-check - Update STATE.md with phase 7 position and decisions - Update ROADMAP.md progress for phase 7 (2/2 plans complete)
…fecycle # Conflicts: # .planning/ROADMAP.md # .planning/STATE.md
…o AbstractChromaRuntime - Lift closed/ensureOpen/close into AbstractChromaRuntime with doClose template - Add callFfiInt for int-returning FFI calls (serverPort), callFfiFree for free operations, ffiLock/ffiUnlock for Panama invokeExact workaround - Make version/startEmbedded/startServer final template methods with shared config validation - Fix readOwnedString to use suppressed exception pattern instead of masking - Fix readLastError to return null on failure instead of synthetic string - Fix EmbeddedSession.close() to not rollback closed flag (prevents double-free) - Drain error slot in callFfiVoid catch path to prevent stale error leaking - Add error wrapping to JNA serverFree/embeddedFree (regression fix) - Acquire FFI_LOCK in Panama serverFree/embeddedFree (thread-safety fix) - Group Panama MethodHandle fields into private Ffi record - Add validateLibraryPath static helper to eliminate init() duplication - Add lifecycle, callFfiInt, and close-rollback tests - Add startServer-after-close coverage to both runtime test suites
|
@claude PTAL |
|
Claude finished @tazarov's task in 2m 49s —— View job Code Review — Phase 7: Server Lifecycle
Overall the retrofit is well-executed. The template method pattern cleanly centralizes FFI lock serialization, error handling, and lifecycle management. The hardening fixes from the 4-round review are all correctly applied. A few observations below, ranging from a potential bug to minor style notes.
|
serverStop was using callFfiVoid with an inner rc check that threw before readLastError could run, discarding the native error message. Since the Rust shim returns negative error codes (SUCCESS=0, errors=-1..-8), callFfiInt naturally surfaces the native error via readLastError on failure.
Native server may not release SQLite file handles synchronously after chroma_server_free on Windows, causing @tempdir cleanup to fail with IOException. Use CleanupMode.NEVER for all tests that start a real Chroma server — the OS temp cleaner handles eventual cleanup.
|
Claude finished @tazarov's task in 2m 19s —— View job Code Review — Phase 7: Server Lifecycle
The prior review's main concern — One new asymmetry is worth calling out: JNA
|
Summary
Phase 7: Server Lifecycle
Goal: Users can start a Chroma server from Java, retrieve connection details, and cleanly shut it down using try-with-resources in both JNA and Panama backends.
Verification: 9/9 must-haves passed
Retrofits both
JnaChromaRuntimeandPanamaChromaRuntimeto extendAbstractChromaRuntime, centralizing FFI lock serialization, lifecycle management, and error handling into template methods. Adds server lifecycle integration tests for both backends.Changes
Plan 01: AbstractChromaRuntime Retrofit
AbstractChromaRuntimeinstead of implementingChromaRuntimedirectlycallFfiHandle,callFfiInt,callFfiVoid,callFfiBorrowedString,callFfiJson,callFfiFree) centralize lock acquisition, null-handle checking, and error propagationclosed/ensureOpen/close/doClose) lives in the base class with rollback ondoClosefailureversion(),startEmbedded(),startServer()are final template methods with shared config validationMethodHandlefields grouped into privateFfirecord (12-param constructor → 2)Plan 02: Server Lifecycle Integration Tests
JnaServerLifecycleTest(6 tests): full accessor verification, double-close idempotency, post-close rejection, null/empty/malformed configPanamaServerLifecycleTest(6 tests): mirrors JNA coverageHardening (from 4-round PR review)
readOwnedStringexception masking with suppressed exception patternreadLastErrorreturning synthetic string → returns null (callers have better fallbacks)EmbeddedSession.close()rollback enabling double-free → stays closed on failurecallFfiVoidstale error slot leak → drains slot in catch pathserverFree/embeddedFreemissing error wrapping (regression)serverFree/embeddedFreebypassingFFI_LOCK(thread-safety)ffiLock()/ffiUnlock()helpers for Panama'sinvokeExactworkaroundvalidateLibraryPath()to deduplicateinit()validationKey files modified:
java/core/src/main/java/.../AbstractChromaRuntime.javajava/jna/src/main/java/.../JnaChromaRuntime.javajava/panama/src/main/java/.../PanamaChromaRuntime.javajava/core/src/main/java/.../EmbeddedSession.javaKey files created:
java/jna/src/test/.../JnaServerLifecycleTest.javajava/panama/src/test/.../PanamaServerLifecycleTest.javaTest plan
core:test— unit tests for AbstractChromaRuntime (lifecycle, callFfiInt, close rollback, FFI serialization)jna:test— JNA integration tests with real native librarypanama:test— Panama integration tests with real native library