upstream-slow

A slow upstream does not hang the server

shipped

The sections below are generated from the CLI (methodology 0.3-draft, CLI 0.3.0); the same text is printed by sealmark explain upstream-slow.

pack
upstream opt-in pack
weight
scoredcandidate
scope
server (what the harness's upstream stub received from the server, and what the server printed or relayed)
decided by
upstreamresponse
since
0.3-draft (methodology 0.3-draft)
config keys
checks.upstream-slow.enabledchecks.upstream-slow.expected_secchecks.upstream-slow.severityidentities.aidentities.btimeout_probe_secupstream.credential_headerupstream.kind

Probes

  • slow-mode the stub holds every reply for expected_sec + 5 s; the first valid call that reaches it is made with a timeout of expected_sec + 2 s

Settings and thresholds

Every check also takes checks.upstream-slow.enabled and checks.upstream-slow.severity; they are described once in the configuration reference.

ThresholdDefaultSet withStandard
expected_sectimeout_probe_secchecks.upstream-slow.expected_secnot locked
KeyDefaultStandardMeaning
checks.upstream-slow.expected_secnonenot lockedSeconds the server may take to answer when the upstream is slow before upstream-slow fails (a little slack is added). null uses timeout_probe_sec.
identities.anonenot lockedToken the harness sends as caller A wherever the server config says {bearer} or {bearer:a}. null mints one per run. Set it when the server validates tokens it did not issue. ${VAR} is read from the environment. Treated as a secret: redacted in config show and in reports (flag --identity-a).
identities.bnonenot lockedToken the harness sends as caller B ({bearer:b}). null mints one per run. Must differ from identities.a. Treated as a secret (flag --identity-b).
timeout_probe_sec10lockedSeconds the cap and timeout probes wait before a call counts as running too long (flag --timeout-probe).
upstream.credential_headerauthorizationnot lockedHeader the upstream-credential check reads the forwarded credential from (compared case-insensitively).
upstream.kindnonenot lockedKind of the harness-owned upstream stub the server's backend is pointed at through {upstream}. http starts a loopback stub that records every request the server forwards (flag --upstream). null starts none. The stub needs a server Sealmark starts, and the server must use {upstream} in command, args, env, url, headers or files.

How the verdict is established

  • Scoring. scored: pass = 1 point, part = 0.5, fail = 0. A fail lowers the pack's percentage but never caps the letter.

What to fix

Give every backend call a timeout shorter than the client's, and answer with an error that says the backend did not answer in time; a server that waits for the backend forever ties up the caller's session. The bound the check waits is checks.upstream-slow.expected_sec (default: the probe timeout) plus 2 s.

False positives

A server that answers an error within expected_sec + 2 s passes. A server that needs longer than that to give up is a fail by the bound the config states.

False negatives

Only the first call that reaches the stub is held; a tool with a different backend timeout is not seen.