Skip to content

HandleRepo logic Timeout issue #33

Description

@atharv10032

Summary

HandleRepoSubmit (projects.go:31) performs the entire deployment pipeline synchronously before returning an HTTP response. Any Cloudflare proxy, load balancer, or browser upstream will time out long before the deploy completes — the user sees a failure, retries, and the system spawns a duplicate container even though the first deploy succeeded.


Timeline — single deploy request

Phase Duration
git clone + stack detection ~5–15s
docker build ~30–90s (Node can be longer)
temp container + time.Sleep(5s) ~10s
Azure NSG PollUntilDone 10–30s
WaitForResponse (polls deploy-responses.json) up to 60s

Total: easily 2–3 minutes. Cloudflare default gateway timeout: 100s.


Steps to reproduce

  1. Submit a repo that requires a non-trivial Node build (e.g. a Next.js app with many dependencies).
  2. Observe the browser or Cloudflare returning a 524/504 timeout.
  3. User retries. A second container is deployed; the first is still running.
  4. deploy-responses.json now has entries from both runs; port reservations in Mongo are duplicated.

Root cause

All of the following run inline inside the HTTP handler, holding the connection open:

HandleRepoSubmit (projects.go:31)
  ├── git clone + stack detection
  ├── docker build              ← unbounded; Node can take 90s+
  ├── docker run (temp)
  ├── time.Sleep(5s)            ← hard-coded probe delay
  ├── port detection
  ├── Mongo reservation
  ├── Azure NSG PollUntilDone   ← 10–30s, network I/O
  ├── docker run (final)
  └── WaitForResponse()         ← polls deploy-responses.json, 60s max

No deduplication or idempotency key exists on the deploy path. A retry issued after a proxy timeout will re-run every step regardless of whether the first run is still in progress.


Impact

  • Any real-world Node/Python build exceeds Cloudflare's 100s gateway timeout.
  • Retries create orphaned containers consuming ports and memory.
  • Duplicate Mongo port reservations corrupt subsequent deploys on those ports.
  • Users have no feedback between submission and timeout — perceived reliability is zero.

Proposed fix

  1. Decouple — accept the request, enqueue a job, return a 202 Accepted with a deploy_id immediately. Run the pipeline in a background goroutine or worker queue.
  2. Poll / stream status — expose a GET /deploys/{deploy_id}/status endpoint (or SSE stream) the client can poll; remove WaitForResponse from the handler entirely.
  3. Idempotency — gate job creation on a deploy_id or content hash so duplicate submissions within a window are deduplicated before any Docker work begins.
  4. Remove time.Sleep(5s) — replace with an active health-check loop with a configurable timeout and backoff.
  5. Fence NSG callsPollUntilDone should run in the background job, not block the HTTP response path.

Acceptance criteria

  • POST /repos returns within 500ms regardless of build duration.
  • Submitting the same repo twice within a deploy window results in exactly one container.
  • Client can query deploy status and retrieve logs without holding an HTTP connection open.

Metadata

Metadata

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions