From b9fb30c18cbf0a7dfe32b6cce58365b4c1a25926 Mon Sep 17 00:00:00 2001 From: Conrad Kramer Date: Wed, 18 Mar 2026 23:07:57 -0700 Subject: [PATCH] Detach runner launch from request timeout --- services/forgejo-nsc/internal/app/service.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) 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,