package builder import ( "context" "time" ) // tickCompileProgress emits interpolated progress during long compile steps (garble can run 10+ minutes). // Returns a stop function; call it when the compile finishes. func (h *Handler) tickCompileProgress(ctx context.Context, token, stage string, startPct, capPct int, obfuscated bool) func() { if token == "" || capPct <= startPct { return func() {} } est := 3 * time.Minute if obfuscated { est = 12 * time.Minute } done := make(chan struct{}) go func() { h.setProgress(token, stage, startPct) ticker := time.NewTicker(2 * time.Second) defer ticker.Stop() start := time.Now() for { select { case <-done: return case <-ctx.Done(): return case <-ticker.C: elapsed := time.Since(start) ratio := float64(elapsed) / float64(est) if ratio > 0.92 { ratio = 0.92 } pct := startPct + int(float64(capPct-startPct)*ratio) if pct >= capPct { pct = capPct - 1 } h.setProgress(token, stage, pct) } } }() return func() { close(done) } }