refactor(client): extract common client implementations to pkg#381
refactor(client): extract common client implementations to pkg#381
Conversation
Signed-off-by: Samuel K <skevetter@pm.me>
📝 WalkthroughWalkthroughDelegates build-agent orchestration, service-daemon startup, and workspace start-wait logic from cmd/* into pkg/client/clientimplementation via three new public APIs: BuildAgentClient, StartServicesDaemon, and StartWait, each accepting options structs and consolidating previously in-file plumbing. Changes
Sequence Diagram(s)mermaid CLI->>CI: BuildAgentClient(ctx, opts) mermaid CLI->>CI: StartServicesDaemon(ctx, opts) Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@pkg/client/clientimplementation/services.go`:
- Around line 64-84: The function getCredentialConfig reads
workspace.Status.Instance and instance.CredentialForwarding before verifying
workspace and Status are non-nil; move the accesses so you first check workspace
!= nil and workspace.Status != nil (and workspace.Status.Instance != nil) before
assigning instance := workspace.Status.Instance and instanceCredentialForwarding
:= instance.CredentialForwarding, and guard usages of
instanceCredentialForwarding.Docker / .Git with nil checks; ensure
credentialConfig default values are still derived from
devPodConfig.ContextOption and only overridden when the instance and its
CredentialForwarding are present.
In `@pkg/client/clientimplementation/workspace_client.go`:
- Around line 849-883: BuildAgentClient leaks the read end of the stdin pipe
returned by createPipes: stdinReader is passed to runAgentInjection but never
closed. After the createPipes call in BuildAgentClient, add a deferred close for
stdinReader (or ensure runAgentInjection closes it on completion/failure) so the
file descriptor is always released; reference the createPipes call and the
stdinReader passed into runAgentInjection to locate where to add the defer.
🧹 Nitpick comments (2)
pkg/client/clientimplementation/workspace_client.go (2)
776-808: Potential infinite loop when workspace status remains Stopped or NotFound withoutcreate=true.When
createisfalseand status isStatusStoppedorStatusNotFound, the handler functions return an error immediately (lines 826, 837). However, whencreateistrueand the Create/Start call succeeds, the loop continues without a status change check, potentially causing repeated Create/Start attempts if the status doesn't transition quickly.Consider adding a brief sleep after successful Create/Start to allow the workspace to transition, or return after initiating the operation:
♻️ Suggested improvement
func handleStoppedStatus(ctx context.Context, workspaceClient client.WorkspaceClient, create bool) error { if create { err := workspaceClient.Start(ctx, client.StartOptions{}) if err != nil { return fmt.Errorf("start workspace %w", err) } - return nil + time.Sleep(pollInterval) + return nil // Continue polling for status change } return fmt.Errorf("workspace is stopped") } func handleNotFoundStatus(ctx context.Context, workspaceClient client.WorkspaceClient, create bool) error { if create { err := workspaceClient.Create(ctx, client.CreateOptions{}) if err != nil { return err } - return nil + time.Sleep(pollInterval) + return nil // Continue polling for status change } return fmt.Errorf("workspace not found") }
918-949: Error from agent injection goroutine may be silently ignored on tunnel server failure.In
BuildAgentClient, ifrunTunnelServerreturns an error (line 878), the function returns immediately without waiting forerrChan. This means the goroutine inrunAgentInjectioncontinues running until it completes or the context is cancelled, but its error is never consumed.Additionally, if the tunnel server succeeds but agent injection fails, the error from
errChanis returned (line 882), but there's no aggregation of both errors.Consider ensuring both errors are properly handled:
♻️ Suggested improvement
result, err := runTunnelServer(cancelCtx, opts, stdoutReader, stdinWriter) - if err != nil { - return nil, err - } - - return result, <-errChan + agentErr := <-errChan + if err != nil { + // Tunnel server failed; agent error is secondary + return nil, err + } + if agentErr != nil { + return nil, agentErr + } + return result, nil
Signed-off-by: Samuel K <skevetter@pm.me>
Signed-off-by: Samuel K skevetter@pm.me
Summary by CodeRabbit
New Features
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.