Skip to content

Per-request read timeout on KB::Client#request (1.1.0) - #105

Merged
fatbeard2 merged 2 commits into
masterfrom
feat/per-request-read-timeout
Sep 22, 2026
Merged

fatbeard2 merged 2 commits into
masterfrom
feat/per-request-read-timeout

Conversation

@fatbeard2

@fatbeard2 fatbeard2 commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Why?

GET /v1/pets/birthdays is the one Knowledge Base endpoint whose server-side work legitimately runs for seconds: 3.4s median, up to 39s in production last week. Because the gem only had a global read budget, connected_health had to run a 12s timeout for every KB call to keep that single daily job alive, while the steady-state p99 of all its other KB calls is 61ms. This gives the consumer a seam to go back to the gem defaults and raise the budget only where it is needed.

Changes

  • KB::Client#request takes read_timeout:; when given, it is set on the Faraday request options for that call only. Connect and write budgets stay global.
  • The override is applied through the request block, so it does not leak into later calls on the memoized connection. A spec pins that.
  • Non-GET calls through #request accept it too, for symmetry.
  • Version 1.1.0, README and CHANGELOG updated.

Not in scope: retries. max_retries = 0 stays.

Checklist

  • Tests added/updated
  • README file updated
  • Changelog updated
  • Version file lib/kb/version.rb updated

How to test

spec/client_spec.rb #request block: default read timeout, the override, no leak into later calls, non-GET.

spec/client_read_timeout_socket_spec.rb is the sanity check that the value reaches the socket: a local TCP server accepts the connection and never answers; the call with read_timeout: 1 fails with Faraday::TimeoutError in about one second, well under the 5s default. WebMock is opened for localhost inside that spec only.

Full suite 171 examples, 0 failures; RuboCop clean on lib/ and spec/ (ruby:3.2.3 container via docker-compose). CI (#106) runs both on this PR.

Consumer side: connected_health will point its Gemfile at this branch while testing, then at the released gem.

🤖 Generated with Claude Code

fatbeard2 and others added 2 commits September 22, 2026 15:34
Add a `read_timeout:` keyword to `KB::Client#request` so a single call can
raise its read budget above `KB.config.request.read_timeout`. Connect and
write budgets stay global, and the override is applied through the Faraday
request block, so it does not leak into later calls on the memoized
connection.

Motivation: `GET /v1/pets/birthdays` is the one KB endpoint whose
server-side work legitimately runs for seconds (3.4s median, up to 39s in
production), and it forced connected_health to run a 12s global timeout
that no other call needs. With this seam the consumer can go back to the
gem defaults and give only that call a longer budget.

Bump to 1.1.0, document in README and CHANGELOG.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A local TCP server accepts and never answers; the call with read_timeout: 1
fails with Faraday::TimeoutError in about a second, well under the 5s
default. WebMock is opened for localhost inside this spec only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@fatbeard2
fatbeard2 force-pushed the feat/per-request-read-timeout branch from 1235f50 to 3fc6779 Compare September 22, 2026 13:36
@fatbeard2
fatbeard2 marked this pull request as ready for review September 22, 2026 13:38
@fatbeard2
fatbeard2 merged commit 3c10697 into master Sep 22, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant