Files
tutti/packages/agent/host/create_session_initialization.go
agent-radar 2ed3415fb7
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
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

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)
}