From 1525406540f2cb2f21344b1a63ba9bfbdcb04414 Mon Sep 17 00:00:00 2001 From: kaspernj Date: Sun, 16 Feb 2020 10:38:29 +0000 Subject: [PATCH 1/6] Cache resource --- lib/docker/connection.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/docker/connection.rb b/lib/docker/connection.rb index 6f1b7ccaf..e9396a226 100644 --- a/lib/docker/connection.rb +++ b/lib/docker/connection.rb @@ -29,16 +29,21 @@ def initialize(url, opts) # The actual client that sends HTTP methods to the Docker server. This value # is not cached, since doing so may cause socket errors after bad requests. def resource - Excon.new(url, options) + @resource ||= Excon.new(url, options) end private :resource + def reset_resource + @resource = nil + end + # Send a request to the server with the ` def request(*args, &block) request = compile_request_params(*args, &block) log_request(request) resource.request(request).body rescue Excon::Errors::BadRequest => ex + reset_resource raise ClientError, ex.response.body rescue Excon::Errors::Unauthorized => ex raise UnauthorizedError, ex.response.body From 1df7b9f5bd9be5947d0e343a127e425f8e0ad9df Mon Sep 17 00:00:00 2001 From: kaspernj Date: Sun, 16 Feb 2020 14:42:25 +0000 Subject: [PATCH 2/6] Added specs --- spec/docker/connection_spec.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/spec/docker/connection_spec.rb b/spec/docker/connection_spec.rb index 10185422f..71f503ff5 100644 --- a/spec/docker/connection_spec.rb +++ b/spec/docker/connection_spec.rb @@ -65,6 +65,20 @@ describe '#resource' do its(:resource) { should be_a Excon::Connection } + + it 'reuses the same connection' do + previous_resource = subject.__send__(:resource) + expect(subject.__send__(:resource).__id__).to eq previous_resource.__id__ + end + + it 'spawns a new Excon::Connection if encountering a bad request' do + previous_resource = subject.__send__(:resource) + response = Excon::Response.new + error = Excon::Errors::BadRequest.new("Hello world", nil, response) + expect(subject).to receive(:compile_request_params).and_raise(error) + expect { subject.request }.to raise_error(Docker::Error::ClientError) + expect(subject.__send__(:resource).__id__).not_to eq previous_resource.__id__ + end end describe '#request' do From 63a43b8eef8dabbb50de170c1d833a3da17da94d Mon Sep 17 00:00:00 2001 From: kaspernj Date: Sun, 16 Feb 2020 14:43:11 +0000 Subject: [PATCH 3/6] Removed comment about not caching connection --- lib/docker/connection.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/docker/connection.rb b/lib/docker/connection.rb index e9396a226..bdf39dc38 100644 --- a/lib/docker/connection.rb +++ b/lib/docker/connection.rb @@ -26,8 +26,7 @@ def initialize(url, opts) end end - # The actual client that sends HTTP methods to the Docker server. This value - # is not cached, since doing so may cause socket errors after bad requests. + # The actual client that sends HTTP methods to the Docker server. def resource @resource ||= Excon.new(url, options) end From 28938db5ad0fb12871c15b947da65926cb07c610 Mon Sep 17 00:00:00 2001 From: kaspernj Date: Fri, 29 Apr 2022 09:34:31 +0000 Subject: [PATCH 4/6] Cache resource based on options --- lib/docker/connection.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/docker/connection.rb b/lib/docker/connection.rb index 85727ec73..f41949e34 100644 --- a/lib/docker/connection.rb +++ b/lib/docker/connection.rb @@ -31,10 +31,18 @@ def initialize(url, opts) # The actual client that sends HTTP methods to the Docker server. def resource - @resource ||= Excon.new(url, options) + if @options[:cache_resource] + @resource ||= new_excon + else + new_excon + end end private :resource + def new_excon + Excon.new(url, options) + end + def reset_resource @resource = nil end From 987a5982f6658d749bb9e01315e469eaedc63a36 Mon Sep 17 00:00:00 2001 From: kaspernj Date: Fri, 29 Apr 2022 09:41:09 +0000 Subject: [PATCH 5/6] Fixed specs --- lib/docker/connection.rb | 2 ++ spec/docker/connection_spec.rb | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/docker/connection.rb b/lib/docker/connection.rb index f41949e34..5f5358efd 100644 --- a/lib/docker/connection.rb +++ b/lib/docker/connection.rb @@ -1,3 +1,5 @@ +require 'json' + # This class represents a Connection to a Docker server. The Connection is # immutable in that once the url and options is set they cannot be changed. class Docker::Connection diff --git a/spec/docker/connection_spec.rb b/spec/docker/connection_spec.rb index a5c2c414b..c00edc5fc 100644 --- a/spec/docker/connection_spec.rb +++ b/spec/docker/connection_spec.rb @@ -64,6 +64,8 @@ end describe '#resource' do + subject { described_class.new('http://localhost:4243', cache_resource: true) } + its(:resource) { should be_a Excon::Connection } it 'reuses the same connection' do @@ -74,9 +76,9 @@ it 'spawns a new Excon::Connection if encountering a bad request' do previous_resource = subject.__send__(:resource) response = Excon::Response.new - error = Excon::Errors::BadRequest.new("Hello world", nil, response) - expect(subject).to receive(:compile_request_params).and_raise(error) - expect { subject.request }.to raise_error(Docker::Error::ClientError) + error = Excon::Errors::BadRequest.new('Hello world', nil, response) + expect(previous_resource).to receive(:request).and_raise(error) + expect { subject.request(:get, '/test', {all: true}, {}) }.to raise_error(Docker::Error::ClientError) expect(subject.__send__(:resource).__id__).not_to eq previous_resource.__id__ end end From 15dd532488538563c2da93fcb90f4d5e1d1eff97 Mon Sep 17 00:00:00 2001 From: kaspernj Date: Fri, 6 May 2022 06:19:29 +0000 Subject: [PATCH 6/6] Added note about cache_resource in README --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index e0697050b..6147a2df7 100644 --- a/README.md +++ b/README.md @@ -600,6 +600,19 @@ require 'docker' Docker::Container.all({}, Docker::Connection.new('tcp://example.com:2375', {})) ``` +## Keep connection to Docker alive + +Each call will be done through a new established HTTP connection. This can be a bit slow if doing a lot of calls. You can keep the HTTP connection alive like this: + +```ruby +connection = Docker::Connection.new("tcp://example.com:1000", cache_resource: true) +``` + +And then use the connection on eahc call like this: +```ruby +container = Docker::Image.get(id, {}, connection) +``` + ## Rake Task To create images through `rake`, a DSL task is provided. For example: