diff --git a/services/forgejo-nsc/internal/app/service.go b/services/forgejo-nsc/internal/app/service.go index 45b66eb..10639a5 100644 --- a/services/forgejo-nsc/internal/app/service.go +++ b/services/forgejo-nsc/internal/app/service.go @@ -94,6 +94,17 @@ type RunnerHandle struct { Name string `json:"name"` } +func launchContext(ttl time.Duration) (context.Context, context.CancelFunc) { + if ttl <= 0 { + return context.WithTimeout(context.Background(), 2*time.Hour) + } + // Provisioning can legitimately take several minutes before the runner starts + // processing the actual Forgejo job. Keep the launch context independent from + // the caller's HTTP timeout so autoscaler/webhook requests don't kill active + // bootstraps mid-flight. + return context.WithTimeout(context.Background(), ttl+30*time.Minute) +} + func (s *Service) Dispatch(ctx context.Context, req DispatchRequest) (DispatchResponse, error) { count := req.Count if count <= 0 { @@ -134,7 +145,10 @@ func (s *Service) Dispatch(ctx context.Context, req DispatchRequest) (DispatchRe return fmt.Errorf("fetching registration token: %w", err) } - name, err := s.dispatcher.LaunchRunner(egCtx, nsc.LaunchRequest{ + launchCtx, cancel := launchContext(ttl) + defer cancel() + + name, err := s.dispatcher.LaunchRunner(launchCtx, nsc.LaunchRequest{ Token: token, InstanceURL: s.instanceURL, Labels: labels,