Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pkg/session/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type SandboxConfig struct {
IdleTimeout time.Duration
HMACKey string
WarmPoolSize int
ReconcileInterval time.Duration
Namespace string
ServiceAccountName string
KubeconfigSecret string
Expand All @@ -28,6 +29,7 @@ func DefaultConfig() SandboxConfig {
MemoryLimit: "512Mi",
IdleTimeout: 30 * time.Minute,
WarmPoolSize: 0,
ReconcileInterval: 30 * time.Second,
Namespace: "tarsy",
ServiceAccountName: "cli-mcp-investigation-sa",
KubeconfigSecret: "cli-mcp-investigation-kubeconfig",
Expand Down
31 changes: 29 additions & 2 deletions pkg/session/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type SessionManager struct {
clientset kubernetes.Interface
config SandboxConfig
cache *PodCache
pool *WarmPool
httpClient *http.Client
logger *slog.Logger
}
Expand All @@ -65,13 +66,30 @@ func NewSessionManager(clientset kubernetes.Interface, config SandboxConfig, log
if logger == nil {
logger = slog.Default()
}
return &SessionManager{
mgr := &SessionManager{
clientset: clientset,
config: config,
cache: NewPodCache(defaultCacheTTL),
httpClient: &http.Client{Timeout: 0},
logger: logger,
}, nil
}
if config.WarmPoolSize > 0 {
mgr.pool = NewWarmPool(clientset, config, logger)
}
return mgr, nil
}

// StartPool starts the warm pool reconciler if the pool is enabled.
// It should be called once after NewSessionManager during server startup.
func (m *SessionManager) StartPool(ctx context.Context) {
if m.pool != nil {
m.pool.StartReconciler(ctx)
}
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

// Pool returns the warm pool (nil when disabled). Exposed for testing.
func (m *SessionManager) Pool() *WarmPool {
return m.pool
}

// SetHTTPClient replaces the default HTTP client (useful for testing).
Expand Down Expand Up @@ -111,6 +129,15 @@ func (m *SessionManager) GetOrCreatePod(ctx context.Context, sessionID string) (
return ip, nil
}

if m.pool != nil {
ip, podName, claimErr := m.pool.ClaimPod(ctx, sessionID)
if claimErr == nil {
m.cache.Set(sessionID, ip, podName)
return ip, nil
}
m.logger.Warn("warm pool claim failed, falling back to on-demand creation", "session", sessionID, "error", claimErr)
}

ip, podName, err = m.createSandboxPod(ctx, sessionID)
if err != nil {
if k8serrors.IsAlreadyExists(err) {
Expand Down
Loading
Loading