Skip to content

fix(e2e): separate request deadlines and bound recovery of stalled reads #2203

Description

@rspurgeon

Problem

Two unrelated E2E commands stalled on HTTP reads until the 60-second harness
deadline killed kongctl. Both had six available command attempts but stopped
after one with retry_stop=retry_policy and cause=subprocess_deadline.
This is the second implementation task under #1943.

PR Scenario / command Last recorded request Comparison
#2195 deck/multi-file, 000-plan-create GET /v2/control-planes during reference resolution Same command passed in 1.214s on #2197 and 1.481s on #2201
#2201 ai-gateway/vault, 004-get-vault-by-id GET /v1/ai-gateways, first request of the process Same command passed in 315ms on #2195 and 311ms on #2197

No response or transport error was recorded for the two stalled requests
before termination. Their precise network/service cause remains unknown.

Important correction to the older #1943 discussion:
KONGCTL_E2E_HTTP_TIMEOUT=0s makes the harness omit http-timeout from the
generated CLI profile. Kongctl retains its default 60-second HTTP timeout.
The HTTP request and whole-command budgets therefore compete. Direct harness
HTTP operations have separate configuration semantics and must be documented
separately. Each command has its own deadline; earlier scenarios do not
consume a later command's 60-second allowance.

Proposed change

  • Configure an explicit bounded request timeout below the subprocess budget.
    Trial 15 seconds as a starting point, then choose values using live timing
    evidence. Budget for retry attempts, backoff, and other work in the command;
    use targeted longer command limits where warranted.
  • Add bounded retry of transient connection/read failures for safe GETs at
    the HTTP boundary, where failed requests are known. Avoid multiplying SDK,
    HTTP-wrapper, and harness retries into an excessive total retry budget.
  • Do not enable blanket transport retries for mutations or unconditionally
    retry every killed subprocess. Retain fail-fast behavior for deterministic
    errors and genuine command hangs.
  • Make zero/default timeout semantics explicit and consistent in config
    generation, documentation, and diagnostic output.
  • Preserve terminal failures and attempts even when later recovery succeeds.

Connection recycling is already enabled in these runs. Increasing shard/job
timeouts or enabling recycling again does not address this failure mechanism.

Acceptance criteria

  • A local test server that stalls a GET produces a classified request timeout
    before the harness kills the command; bounded recovery can then succeed.
  • A connection reset on a GET can recover within the configured total budget.
  • Persistent failures and genuine subprocess hangs stop within documented
    limits; non-retryable errors fail promptly.
  • Tests establish that unsafe mutations do not inherit the new read retries.
  • Both imperative reads and declarative planner/executor reads are covered.
  • Diagnostics report effective request/command limits and retry stop reasons.
  • Record live results for the three motivating scenarios and compare timeout
    frequency and elapsed time before/after; retain artifacts on failure.

The assertion task under #1943 remains necessary: command-level recovery of
partially applied mutations must not invalidate scenario expectations.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinge2eIssue related to the e2e tests and testing frameworkhigh-priorityThis item should be addressed asaptriagedThis item has been triaged

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions