Skip to content

Commit bbbcd6c

Browse files
committed
Allow call #persistent with block
Example Usage: ============== ``` ruby def keys(users) HTTP.persistent("https://github.com") do |http| users.map { |u| http.get("/#{u}.keys").to_s } end end ``` Resolves #200
1 parent 50b8cda commit bbbcd6c

File tree

3 files changed

+68
-9
lines changed

3 files changed

+68
-9
lines changed

lib/http/chainable.rb

+34-4
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,41 @@ def request(verb, uri, options = {})
7272
branch(options).request verb, uri
7373
end
7474

75-
# Flag as persistent
76-
# @param [String] host
77-
# @raise [Request::Error] if Host is invalid
75+
# @overload persistent(host)
76+
# Flags as persistent
77+
# @param [String] host
78+
# @raise [Request::Error] if Host is invalid
79+
# @return [HTTP::Client] Persistent client
80+
# @overload persistent(host, &block)
81+
# Executes given block with persistent client and automatically closes
82+
# connection at the end of execution.
83+
#
84+
# @example
85+
#
86+
# def keys(users)
87+
# HTTP.persistent("https://github.com") do |http|
88+
# users.map { |u| http.get("/#{u}.keys").to_s }
89+
# end
90+
# end
91+
#
92+
# # same as
93+
#
94+
# def keys(users)
95+
# http = HTTP.persistent "https://github.com"
96+
# users.map { |u| http.get("/#{u}.keys").to_s }
97+
# ensure
98+
# http.close if http
99+
# end
100+
#
101+
#
102+
# @yieldparam [HTTP::Client] client Persistent client
103+
# @return [Object] result of last expression in the block
78104
def persistent(host)
79-
branch default_options.with_persistent host
105+
p_client = branch default_options.with_persistent host
106+
return p_client unless block_given?
107+
yield p_client
108+
ensure
109+
p_client.close
80110
end
81111

82112
# Make a request through an HTTP proxy

lib/http/client.rb

+11-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
require "forwardable"
2+
13
require "cgi"
24
require "uri"
35

@@ -10,6 +12,7 @@
1012
module HTTP
1113
# Clients make requests and receive responses
1214
class Client
15+
extend Forwardable
1316
include Chainable
1417

1518
CONNECTION = "Connection".freeze
@@ -58,6 +61,11 @@ def perform(req, options)
5861
end
5962
end
6063

64+
# @!method persistent?
65+
# @see Options#persistent?
66+
# @return [Boolean] whenever client is persistent
67+
def_delegator :default_options, :persistent?
68+
6169
def make_request(req, options)
6270
verify_connection!(req.uri)
6371

@@ -79,12 +87,10 @@ def make_request(req, options)
7987
@state = :clean
8088

8189
res
82-
83-
# On any exception we reset the conn. This is a safety measure, to ensure
84-
# we don't have conns in a bad state resulting in mixed requests/responses
8590
rescue
86-
close if default_options.persistent?
87-
91+
# On any exception we reset the conn. This is a safety measure, to ensure
92+
# we don't have conns in a bad state resulting in mixed requests/responses
93+
close if persistent?
8894
raise
8995
end
9096

spec/lib/http_spec.rb

+23
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,27 @@
163163
expect(client.default_options[:cache]).to eq cache
164164
end
165165
end
166+
167+
describe ".persistent" do
168+
let(:host) { "https://api.github.com" }
169+
170+
context "with host only given" do
171+
subject { HTTP.persistent host }
172+
it { is_expected.to be_an HTTP::Client }
173+
it { is_expected.to be_persistent }
174+
end
175+
176+
context "with host and block given" do
177+
it "returns last evaluation of last expression" do
178+
expect(HTTP.persistent(host) { :http }).to be :http
179+
end
180+
181+
it "auto-closes connection" do
182+
HTTP.persistent host do |client|
183+
expect(client).to receive(:close).and_call_original
184+
client.get("/repos/httprb/http.rb")
185+
end
186+
end
187+
end
188+
end
166189
end

0 commit comments

Comments
 (0)