| 288 | } |
| 289 | |
| 290 | func holdConnection(ctx context.Context, logs io.Writer, conn workspacesdk.AgentConn, holdDur time.Duration, specs []Connection) error { |
| 291 | ctx, span := tracing.StartSpan(ctx) |
| 292 | defer span.End() |
| 293 | |
| 294 | eg, egCtx := errgroup.WithContext(ctx) |
| 295 | client := conn.AppHTTPClient() |
| 296 | if len(specs) > 0 { |
| 297 | _, _ = fmt.Fprintln(logs, "\nStarting connection loops...") |
| 298 | } |
| 299 | for i, connSpec := range specs { |
| 300 | if connSpec.Interval <= 0 { |
| 301 | continue |
| 302 | } |
| 303 | |
| 304 | eg.Go(func() error { |
| 305 | t := time.NewTicker(time.Duration(connSpec.Interval)) |
| 306 | defer t.Stop() |
| 307 | |
| 308 | timeout := defaultRequestTimeout |
| 309 | if connSpec.Timeout > 0 { |
| 310 | timeout = time.Duration(connSpec.Timeout) |
| 311 | } |
| 312 | |
| 313 | for { |
| 314 | select { |
| 315 | case <-egCtx.Done(): |
| 316 | return egCtx.Err() |
| 317 | case <-t.C: |
| 318 | ctx, cancel := context.WithTimeout(ctx, timeout) |
| 319 | req, err := http.NewRequestWithContext(ctx, http.MethodGet, connSpec.URL, nil) |
| 320 | if err != nil { |
| 321 | cancel() |
| 322 | return xerrors.Errorf("create request: %w", err) |
| 323 | } |
| 324 | |
| 325 | res, err := client.Do(req) |
| 326 | cancel() |
| 327 | if err != nil { |
| 328 | _, _ = fmt.Fprintf(logs, "\tERR: %s (%d): %+v\n", connSpec.URL, i, err) |
| 329 | return xerrors.Errorf("make connection to conn spec %d %q: %w", i, connSpec.URL, err) |
| 330 | } |
| 331 | res.Body.Close() |
| 332 | |
| 333 | _, _ = fmt.Fprintf(logs, "\tOK: %s (%d)\n", connSpec.URL, i) |
| 334 | t.Reset(time.Duration(connSpec.Interval)) |
| 335 | } |
| 336 | } |
| 337 | }) |
| 338 | } |
| 339 | |
| 340 | // Wait for the hold duration to end. We use a fake error to signal that |
| 341 | // the hold duration has ended. |
| 342 | _, _ = fmt.Fprintf(logs, "\nWaiting for %s...\n", holdDur) |
| 343 | eg.Go(func() error { |
| 344 | t := time.NewTicker(holdDur) |
| 345 | defer t.Stop() |
| 346 | |
| 347 | select { |