Skip to content

fix: make proxy response_header_timeout configurable#164

Merged
thushan merged 1 commit into
thushan:mainfrom
matthewjhunter:fix/configurable-response-header-timeout
Jun 7, 2026
Merged

fix: make proxy response_header_timeout configurable#164
thushan merged 1 commit into
thushan:mainfrom
matthewjhunter:fix/configurable-response-header-timeout

Conversation

@matthewjhunter

@matthewjhunter matthewjhunter commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Resolves #163

Problem

The Olla engine hardcodes the transport's ResponseHeaderTimeout to DefaultResponseHeaderTimeout (30s) with no override. Backends that load models on demand (Lemonade especially) send no response header until the model is resident, so a cold load over 30s aborts with a 502 "request timeout after 30.0s ..." -- even when response_timeout is set much higher (that governs a later deadline and never applies).

Change

Add a response_header_timeout key under proxy, threaded through to the Olla transport, defaulting to DefaultResponseHeaderTimeout (30s) so existing behaviour is unchanged.

  • config/types.go: new response_header_timeout yaml field.
  • proxy.Configuration + BaseProxyConfig: field + GetResponseHeaderTimeout() (defaults to 30s when unset).
  • factory.go: picked up via the existing olla-specific type-assertion block (no ports.ProxyConfiguration interface change).
  • olla/service.go: transport uses config.GetResponseHeaderTimeout() instead of the hardcoded constant.
  • Docs: configuration reference + Lemonade backend note.

Verification

  • make ready passes (test-race, fmt, vet, golangci-lint 0 issues, better-align).
  • New test asserts a configured value is honoured; the existing default test still covers the unset-falls-back-to-30s case.
  • Validated against a live Lemonade backend: with response_header_timeout: 180s, a cold model load that previously 502'd at 30s now completes.

Independent of #161 (the Lemonade model-state fix); they compose but don't depend on each other.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added configurable response_header_timeout setting for proxy configurations, enabling users to extend header wait times for backends with extended initialisation periods.
  • Documentation

    • Added configuration reference documentation for the new response_header_timeout option.
    • Included integration guidance to prevent cold-start failures for backends with extended model loading times.

The Olla engine hardcoded the HTTP transport's ResponseHeaderTimeout to
DefaultResponseHeaderTimeout (30s) with no override. Backends that load models
on demand (e.g. Lemonade) send no response header until the model is resident,
so a cold load exceeding 30s aborts the request with a 502 ("request timeout
after 30.0s ...") even when response_timeout is set far higher -- that governs a
later deadline and never gets a chance to apply.

Add a `response_header_timeout` proxy config key, threaded through to the Olla
transport, defaulting to DefaultResponseHeaderTimeout (30s) so existing
behaviour is unchanged. Operators with on-demand backends can raise it (e.g.
180s) to tolerate cold model loads.

Refs thushan#163
@matthewjhunter
matthewjhunter requested a review from thushan as a code owner June 7, 2026 07:47
@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

This PR extends the proxy configuration to make ResponseHeaderTimeout user-configurable, allowing operators to override the default 30s limit for backends that require longer initial response times during on-demand model loading. Configuration flows through the factory into the HTTP transport, with test validation and documentation.

Changes

Configurable proxy response header timeout

Layer / File(s) Summary
Configuration contract and getters
internal/adapter/proxy/config.go, internal/adapter/proxy/config/unified.go, internal/config/types.go, internal/app/config.go, internal/app/services/proxy.go
Configuration and BaseProxyConfig structs now declare ResponseHeaderTimeout fields with getter methods; Configuration.GetResponseHeaderTimeout() returns the raw value (including zero) whilst BaseProxyConfig.GetResponseHeaderTimeout() applies the default when unset. Configuration literals in updateProxyConfiguration and createProxyConfiguration are reformatted for field alignment.
Factory configuration wiring
internal/adapter/proxy/factory.go
The Olla-specific factory closure reads GetResponseHeaderTimeout() from the proxy configuration port and assigns it to ollaConfig.ResponseHeaderTimeout, threading the user-provided timeout into Olla service initialisation.
Transport implementation applies configured timeout
internal/adapter/proxy/olla/service.go
createOptimisedTransport replaces the hardcoded proxyconfig.DefaultResponseHeaderTimeout with config.GetResponseHeaderTimeout(), making the HTTP transport honour the configured response header timeout.
Test coverage for configurable timeout
internal/adapter/proxy/olla/service_transport_test.go
New test TestCreateOptimisedTransport_ResponseHeaderTimeout_Configurable verifies that when Configuration.ResponseHeaderTimeout is set to 180s, the resulting transport reflects that configured value.
Configuration documentation and examples
docs/content/configuration/reference.md, docs/content/integrations/backend/lemonade.md
Reference documentation describes the new response_header_timeout field with guidance for slow first-response-header scenarios; Lemonade backend documentation explains the cold-load issue and provides a 180s configuration example to prevent 502 failures.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • thushan/olla#59: Introduces the unified proxy configuration (BaseProxyConfig) in internal/adapter/proxy/config/unified.go that this PR extends with the ResponseHeaderTimeout field and threads through the factory into the Olla transport.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly summarizes the main change: making proxy response_header_timeout configurable, which is the core objective addressed throughout the changeset.
Linked Issues check ✅ Passed All requirements from issue #163 are met: response_header_timeout field added to proxy config, GetResponseHeaderTimeout() getter implemented with 30s default, factory wiring completed, and transport uses the configurable value.
Out of Scope Changes check ✅ Passed All changes directly support making response_header_timeout configurable; documentation, config structures, factory wiring, and transport usage are all aligned with the stated objective.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/content/configuration/reference.md (1)

187-197: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add response_header_timeout to the “Complete default configuration” proxy block.

This section now documents the field, but the default YAML later in the page still omits it, so the reference is internally inconsistent for copy/paste users.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/content/configuration/reference.md` around lines 187 - 197, The
documentation's "Complete default configuration" proxy YAML is missing the
response_header_timeout field described earlier; update the proxy block in the
"Complete default configuration" section to include response_header_timeout
(e.g., set to the documented default `30s`), ensuring the proxy keys
(connection_timeout, response_timeout, read_timeout, response_header_timeout)
match the earlier example and keep formatting consistent for copy/paste users.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@docs/content/configuration/reference.md`:
- Around line 187-197: The documentation's "Complete default configuration"
proxy YAML is missing the response_header_timeout field described earlier;
update the proxy block in the "Complete default configuration" section to
include response_header_timeout (e.g., set to the documented default `30s`),
ensuring the proxy keys (connection_timeout, response_timeout, read_timeout,
response_header_timeout) match the earlier example and keep formatting
consistent for copy/paste users.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fa5af72d-9b66-4753-87a2-bb48d87585cd

📥 Commits

Reviewing files that changed from the base of the PR and between c336dc7 and 8738276.

📒 Files selected for processing (10)
  • docs/content/configuration/reference.md
  • docs/content/integrations/backend/lemonade.md
  • internal/adapter/proxy/config.go
  • internal/adapter/proxy/config/unified.go
  • internal/adapter/proxy/factory.go
  • internal/adapter/proxy/olla/service.go
  • internal/adapter/proxy/olla/service_transport_test.go
  • internal/app/config.go
  • internal/app/services/proxy.go
  • internal/config/types.go

@thushan
thushan merged commit 6b61f56 into thushan:main Jun 7, 2026
8 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.

Proxy ResponseHeaderTimeout is hardcoded to 30s — cold-loading backends (Lemonade) 502 on first request

2 participants