Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
93 lines
2.9 KiB
Go
93 lines
2.9 KiB
Go
package agenthost
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
runtimeSessionPublishTimeout = 5 * time.Second
|
|
failedCreateLockTimeout = 2 * time.Second
|
|
failedCreateRuntimeCloseTimeout = 5 * time.Second
|
|
failedCreateRollbackTimeout = 3 * time.Second
|
|
failedCreatePreparationTimeout = 2 * time.Second
|
|
)
|
|
|
|
type failedCreateCleanupState struct {
|
|
RuntimeStarted bool
|
|
CanonicalCreated bool
|
|
SessionLockHeld bool
|
|
}
|
|
|
|
func publishRuntimeSessionInitialization(
|
|
ctx context.Context,
|
|
publisher RuntimeSessionInitializationPublisher,
|
|
input RuntimeSessionInitializationPublishInput,
|
|
) (ProviderRuntimeSession, error) {
|
|
publishCtx, cancel := detachedPhaseContext(ctx, runtimeSessionPublishTimeout)
|
|
defer cancel()
|
|
return publisher.PublishSessionInitialization(publishCtx, input)
|
|
}
|
|
|
|
func (h *Host) cleanupFailedCreate(
|
|
ctx context.Context,
|
|
ref SessionRef,
|
|
provider string,
|
|
cause error,
|
|
state failedCreateCleanupState,
|
|
) error {
|
|
errs := []error{cause}
|
|
closeRuntime := state.RuntimeStarted
|
|
if closeRuntime && !state.SessionLockHeld {
|
|
startedAt := h.now()
|
|
lockCtx, cancel := detachedPhaseContext(ctx, failedCreateLockTimeout)
|
|
release, err := h.acquireSession(lockCtx, ref)
|
|
h.observeStep(lockCtx, "session_create_cleanup", "lifecycle_lock_acquired", ref.WorkspaceID, ref.AgentSessionID, provider, startedAt, err)
|
|
cancel()
|
|
if err != nil {
|
|
errs = append(errs, err)
|
|
closeRuntime = false
|
|
} else {
|
|
defer release()
|
|
}
|
|
}
|
|
if closeRuntime {
|
|
startedAt := h.now()
|
|
closeCtx, cancel := detachedPhaseContext(ctx, failedCreateRuntimeCloseTimeout)
|
|
err := h.runtime.Close(closeCtx, RuntimeCloseInput{
|
|
WorkspaceID: ref.WorkspaceID, AgentSessionID: ref.AgentSessionID,
|
|
})
|
|
h.observeStep(closeCtx, "session_create_cleanup", "runtime_closed", ref.WorkspaceID, ref.AgentSessionID, provider, startedAt, err)
|
|
cancel()
|
|
errs = append(errs, err)
|
|
}
|
|
if state.CanonicalCreated {
|
|
startedAt := h.now()
|
|
rollbackCtx, cancel := detachedPhaseContext(ctx, failedCreateRollbackTimeout)
|
|
_, err := h.store.RollbackRuntimeSessionInitialization(
|
|
rollbackCtx,
|
|
ref.WorkspaceID,
|
|
ref.AgentSessionID,
|
|
)
|
|
h.observeStep(rollbackCtx, "session_create_cleanup", "canonical_rolled_back", ref.WorkspaceID, ref.AgentSessionID, provider, startedAt, err)
|
|
cancel()
|
|
errs = append(errs, err)
|
|
}
|
|
if h.preparation != nil {
|
|
startedAt := h.now()
|
|
cleanupCtx, cancel := detachedPhaseContext(ctx, failedCreatePreparationTimeout)
|
|
err := h.preparation.Cleanup(cleanupCtx, RuntimeCleanupInput{
|
|
WorkspaceID: ref.WorkspaceID, AgentSessionID: ref.AgentSessionID, Provider: provider,
|
|
})
|
|
h.observeStep(cleanupCtx, "session_create_cleanup", "preparation_cleaned", ref.WorkspaceID, ref.AgentSessionID, provider, startedAt, err)
|
|
cancel()
|
|
errs = append(errs, err)
|
|
}
|
|
return errors.Join(errs...)
|
|
}
|
|
|
|
func detachedPhaseContext(parent context.Context, timeout time.Duration) (context.Context, context.CancelFunc) {
|
|
return context.WithTimeout(context.WithoutCancel(parent), timeout)
|
|
}
|