upserve/docker-api

Docker::Event.stream documentation should mention how to waive the read_timeout

danschmidt5189 opened this issue · 1 comments

When streaming Docker events, you typically don't want to timeout at all — you want to keep reading forever until your own control logic kicks in to stop streaming. Read timeouts can be disabled in Excon by passing read_timeout: 0|nil, but docker-api only supports passing 0: the null-check in compile_request_params strips out read_timeout: nil, effectively mapping it to the default timeout value (60).

The README currently suggests setting Docker.options[:read_timeout] to a very high value, but this is bad for two reasons:

  1. It's global, and a very high timeout is bad in almost all other circumstances.
  2. You probably actually want no timeout when streaming events, not just a high one.

I suggest updating the Docker::Event.stream documentation with an example of disabling read timeouts completely.

I would also consider making read_timeout: 0 the default for that specific method, since that is the least surprising behavior and the one most likely wanted by users. This is a much more significant change, however, and would necessitate at least a minor version update.

calh commented

+1 to this. I'm writing a streaming health check event system, and I've been struggling with trying to figure out how to disable the read_timeout. Even if I set it to 0 or a large number it still seems to time out after 4 minutes. A stable production server might have containers running for months with no health change events.

require 'docker-api'
Docker.options[:read_timeout] = 604800

Docker::Event.stream(filters: '{"type":{"container":true},"event":{"health_status":true}}') do |event|
  puts event.inspect
end
$ time bundle exec ruby handler.rb 
Traceback (most recent call last):
        4: from handler.rb:8:in `<main>'
        3: from vendor/bundle/ruby/2.5.0/gems/docker-api-2.2.0/lib/docker/event.rb:31:in `stream'
        2: from vendor/bundle/ruby/2.5.0/gems/docker-api-2.2.0/lib/docker/connection.rb:109:in `block (2 levels) in <class:Connection>'
        1: from vendor/bundle/ruby/2.5.0/gems/docker-api-2.2.0/lib/docker/connection.rb:44:in `request'
vendor/bundle/ruby/2.5.0/gems/docker-api-2.2.0/lib/docker/connection.rb:91:in `rescue in request': read timeout reached (Docker::Error::TimeoutError)

real    4m0.746s
user    0m0.473s
sys     0m0.037s