| 208 | } |
| 209 | |
| 210 | func verifyConnection(ctx context.Context, logs io.Writer, conn workspacesdk.AgentConn) error { |
| 211 | const verifyConnectionAttempts = 30 |
| 212 | const verifyConnectionDelay = 1 * time.Second |
| 213 | |
| 214 | ctx, span := tracing.StartSpan(ctx) |
| 215 | defer span.End() |
| 216 | |
| 217 | client := conn.AppHTTPClient() |
| 218 | for i := 0; i < verifyConnectionAttempts; i++ { |
| 219 | _, _ = fmt.Fprintf(logs, "\tVerify connection attempt %d/%d...\n", i+1, verifyConnectionAttempts) |
| 220 | verifyCtx, cancel := context.WithTimeout(ctx, defaultRequestTimeout) |
| 221 | |
| 222 | u := &url.URL{ |
| 223 | Scheme: "http", |
| 224 | Host: net.JoinHostPort("localhost", strconv.Itoa(workspacesdk.AgentHTTPAPIServerPort)), |
| 225 | Path: "/", |
| 226 | } |
| 227 | req, err := http.NewRequestWithContext(verifyCtx, http.MethodGet, u.String(), nil) |
| 228 | if err != nil { |
| 229 | cancel() |
| 230 | return xerrors.Errorf("new verify connection request to %q: %w", u.String(), err) |
| 231 | } |
| 232 | resp, err := client.Do(req) |
| 233 | cancel() |
| 234 | if err == nil { |
| 235 | _ = resp.Body.Close() |
| 236 | break |
| 237 | } |
| 238 | if i == verifyConnectionAttempts-1 { |
| 239 | return xerrors.Errorf("verify connection: %w", err) |
| 240 | } |
| 241 | |
| 242 | select { |
| 243 | case <-ctx.Done(): |
| 244 | return xerrors.Errorf("verify connection: %w", ctx.Err()) |
| 245 | case <-time.After(verifyConnectionDelay): |
| 246 | } |
| 247 | } |
| 248 | |
| 249 | return nil |
| 250 | } |
| 251 | |
| 252 | func performInitialConnections(ctx context.Context, logs io.Writer, conn workspacesdk.AgentConn, specs []Connection) error { |
| 253 | if len(specs) == 0 { |