Skip to content

change(options): stop tying :protocol_timeout to :timeout - #633

Closed
route wants to merge 1 commit into
mainfrom
fix/protocol-timeout-default
Closed

change(options): stop tying :protocol_timeout to :timeout#633
route wants to merge 1 commit into
mainfrom
fix/protocol-timeout-default

Conversation

@route

@route route commented Sep 2, 2026

Copy link
Copy Markdown
Member

Refs #470.

The problem

DEFAULT_PROTOCOL_TIMEOUT = ENV.fetch("FERRUM_PROTOCOL_TIMEOUT", DEFAULT_TIMEOUT).to_i

:timeout is a user-facing knob: how long to wait for a navigation, an evaluation, a DOM query. People set it low on purpose. :protocol_timeout is a different thing, the budget for internal CDP bookkeeping, Target.createTarget, Target.attachToTarget, Page.enable, calls that resolve in milliseconds on a healthy machine.

Tying the second to the first means Ferrum::Browser.new(timeout: 1) also gives target creation one second, and 5 by default. On a loaded CI box that is not enough, and what comes out is a Ferrum::TimeoutError while creating a page, which is precisely the shape of #470: Page.enable never answering on a busy runner, then the whole run unravelling.

The change

:protocol_timeout defaults to 30 seconds, independent of :timeout, still settable per browser and through FERRUM_PROTOCOL_TIMEOUT. Page-level waits are unaffected, Page#command passes :timeout as before.

Generous is the right default here: running out of this budget means the machine is struggling, not that the browser is gone. A browser that has actually died is detected by the socket closing, not by this timer.

Verification

  • New example in spec/browser_spec.rb: timeout: 1 no longer drags protocol_timeout down with it, and the setter still works. Fails before the change, protocol_timeout is 1 there.
  • Full suite: 616 examples, 0 failures.
  • :protocol_timeout is now documented in docs/2-customization.md next to :timeout, it was missing.

Best merged after #630, which is what makes a dead browser raise immediately rather than after this timeout. On its own this change makes that detection slower, 30s instead of 5s, until #630 lands.

`:protocol_timeout` bounds internal CDP bookkeeping, `Target.createTarget`, `Target.attachToTarget` and friends,
which resolve in milliseconds. It defaulted to `:timeout`, so anyone lowering that to keep page waits short also
gave the browser's own bookkeeping the same tiny budget, and on a loaded machine page creation started raising
`Ferrum::TimeoutError`.

It now defaults to 30 seconds, still overridable per browser or through `FERRUM_PROTOCOL_TIMEOUT`. Running out of it
means the machine is struggling rather than the browser being gone, which is detected on its own.

Refs #470
@route

route commented Sep 3, 2026

Copy link
Copy Markdown
Member Author

Closing this. 30s is far too much for a protocol call: :protocol_timeout only bounds browser-session bookkeeping (Target.createTarget, Target.attachToTarget), page commands go through Page#command with :timeout. Those responses are quick, what's slow is the page load, and that's a different budget. The unanswered Page.enable in #470 wasn't a slow response either, it never reached the browser, which #602 fixed.

@route route closed this Sep 3, 2026
@route
route deleted the fix/protocol-timeout-default branch September 3, 2026 11:21
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