Skip to content

Commit 6e4a2aa

Browse files
iMacTiaolleolleolle
authored andcommitted
Refactor Adapter as final endpoints (#846)
* Refactors Adapters: * They're now final endpoints. * They don't need to call `@app.call` anymore. * They don't inherit from `Faraday::Middleware` anymore.
1 parent 3fbf2d5 commit 6e4a2aa

File tree

6 files changed

+164
-159
lines changed

6 files changed

+164
-159
lines changed

lib/faraday.rb

Lines changed: 2 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
require 'cgi'
33
require 'set'
44
require 'forwardable'
5+
require 'faraday/middleware_registry'
6+
require 'faraday/dependency_loader'
57

68
# This is the main namespace for Faraday.
79
#
@@ -147,126 +149,6 @@ def self.default_connection_options=(options)
147149
Timer = Timeout
148150
end
149151

150-
# Adds the ability for other modules to register and lookup
151-
# middleware classes.
152-
module MiddlewareRegistry
153-
# Register middleware class(es) on the current module.
154-
#
155-
# @param autoload_path [String] Middleware autoload path
156-
# @param mapping [Hash{Symbol => Module, Symbol, Array<Module, Symbol, String>}] Middleware mapping from a lookup symbol to a reference to the middleware. - Classes can be expressed as:
157-
# - a fully qualified constant
158-
# - a Symbol
159-
# - a Proc that will be lazily called to return the former
160-
# - an array is given, its first element is the constant or symbol,
161-
# and its second is a file to `require`.
162-
# @return [void]
163-
#
164-
# @example Lookup by a constant
165-
#
166-
# module Faraday
167-
# class Whatever
168-
# # Middleware looked up by :foo returns Faraday::Whatever::Foo.
169-
# register_middleware :foo => Foo
170-
# end
171-
# end
172-
#
173-
# @example Lookup by a symbol
174-
#
175-
# module Faraday
176-
# class Whatever
177-
# # Middleware looked up by :bar returns Faraday::Whatever.const_get(:Bar)
178-
# register_middleware :bar => :Bar
179-
# end
180-
# end
181-
#
182-
# @example Lookup by a symbol and string in an array
183-
#
184-
# module Faraday
185-
# class Whatever
186-
# # Middleware looked up by :baz requires 'baz' and returns Faraday::Whatever.const_get(:Baz)
187-
# register_middleware :baz => [:Baz, 'baz']
188-
# end
189-
# end
190-
#
191-
def register_middleware(autoload_path = nil, mapping = nil)
192-
if mapping.nil?
193-
mapping = autoload_path
194-
autoload_path = nil
195-
end
196-
middleware_mutex do
197-
@middleware_autoload_path = autoload_path if autoload_path
198-
(@registered_middleware ||= {}).update(mapping)
199-
end
200-
end
201-
202-
# Unregister a previously registered middleware class.
203-
#
204-
# @param key [Symbol] key for the registered middleware.
205-
def unregister_middleware(key)
206-
@registered_middleware.delete(key)
207-
end
208-
209-
# Lookup middleware class with a registered Symbol shortcut.
210-
#
211-
# @param key [Symbol] key for the registered middleware.
212-
# @return [Class] a middleware Class.
213-
# @raise [Faraday::Error] if given key is not registered
214-
#
215-
# @example
216-
#
217-
# module Faraday
218-
# class Whatever
219-
# register_middleware :foo => Foo
220-
# end
221-
# end
222-
#
223-
# Faraday::Whatever.lookup_middleware(:foo)
224-
# # => Faraday::Whatever::Foo
225-
#
226-
def lookup_middleware(key)
227-
load_middleware(key) ||
228-
raise(Faraday::Error.new("#{key.inspect} is not registered on #{self}"))
229-
end
230-
231-
def middleware_mutex(&block)
232-
@middleware_mutex ||= begin
233-
require 'monitor'
234-
Monitor.new
235-
end
236-
@middleware_mutex.synchronize(&block)
237-
end
238-
239-
def fetch_middleware(key)
240-
defined?(@registered_middleware) && @registered_middleware[key]
241-
end
242-
243-
def load_middleware(key)
244-
value = fetch_middleware(key)
245-
case value
246-
when Module
247-
value
248-
when Symbol, String
249-
middleware_mutex do
250-
@registered_middleware[key] = const_get(value)
251-
end
252-
when Proc
253-
middleware_mutex do
254-
@registered_middleware[key] = value.call
255-
end
256-
when Array
257-
middleware_mutex do
258-
const, path = value
259-
if root = @middleware_autoload_path
260-
path = "#{root}/#{path}"
261-
end
262-
require(path)
263-
@registered_middleware[key] = const
264-
end
265-
load_middleware(key)
266-
end
267-
end
268-
end
269-
270152
require_libs "utils", "options", "connection", "rack_builder", "parameters",
271153
"middleware", "adapter", "request", "response", "upload_io", "error"
272154

lib/faraday/adapter.rb

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
module Faraday
22
# Base class for all Faraday adapters. Adapters are
33
# responsible for fulfilling a Faraday request.
4-
class Adapter < Middleware
4+
class Adapter
5+
extend MiddlewareRegistry
6+
extend DependencyLoader
7+
58
CONTENT_LENGTH = 'Content-Length'.freeze
69

710
register_middleware File.expand_path('../adapter', __FILE__),
@@ -31,13 +34,14 @@ def inherited(subclass)
3134
self.supports_parallel = false
3235

3336
def initialize(app = nil, opts = {}, &block)
34-
super(app)
37+
@app = lambda { |env| env.response }
3538
@connection_options = opts
3639
@config_block = block
3740
end
3841

3942
def call(env)
4043
env.clear_body if env.needs_body?
44+
env.response = Response.new
4145
end
4246

4347
private
@@ -50,6 +54,9 @@ def save_response(env, status, body, headers = nil, reason_phrase = nil)
5054
response_headers.update headers unless headers.nil?
5155
yield(response_headers) if block_given?
5256
end
57+
58+
env.response.finish(env) unless env.parallel?
59+
env.response
5360
end
5461
end
5562
end

lib/faraday/dependency_loader.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module Faraday
2+
module DependencyLoader
3+
attr_accessor :load_error
4+
private :load_error=
5+
6+
# Executes a block which should try to require and reference dependent libraries
7+
def dependency(lib = nil)
8+
lib ? require(lib) : yield
9+
rescue LoadError, NameError => error
10+
self.load_error = error
11+
end
12+
13+
def new(*)
14+
raise "missing dependency for #{self}: #{load_error.message}" unless loaded?
15+
super
16+
end
17+
18+
def loaded?
19+
load_error.nil?
20+
end
21+
22+
def inherited(subclass)
23+
super
24+
subclass.send(:load_error=, self.load_error)
25+
end
26+
end
27+
end

lib/faraday/middleware.rb

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,7 @@
11
module Faraday
22
class Middleware
33
extend MiddlewareRegistry
4-
5-
class << self
6-
attr_accessor :load_error
7-
private :load_error=
8-
end
9-
10-
self.load_error = nil
11-
12-
# Executes a block which should try to require and reference dependent libraries
13-
def self.dependency(lib = nil)
14-
lib ? require(lib) : yield
15-
rescue LoadError, NameError => error
16-
self.load_error = error
17-
end
18-
19-
def self.new(*)
20-
raise "missing dependency for #{self}: #{load_error.message}" unless loaded?
21-
super
22-
end
23-
24-
def self.loaded?
25-
load_error.nil?
26-
end
27-
28-
def self.inherited(subclass)
29-
super
30-
subclass.send(:load_error=, self.load_error)
31-
end
4+
extend DependencyLoader
325

336
def initialize(app = nil)
347
@app = app

lib/faraday/middleware_registry.rb

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
module Faraday
2+
# Adds the ability for other modules to register and lookup
3+
# middleware classes.
4+
module MiddlewareRegistry
5+
# Register middleware class(es) on the current module.
6+
#
7+
# @param autoload_path [String] Middleware autoload path
8+
# @param mapping [Hash{Symbol => Module, Symbol, Array<Module, Symbol, String>}] Middleware mapping from a lookup symbol to a reference to the middleware. - Classes can be expressed as:
9+
# - a fully qualified constant
10+
# - a Symbol
11+
# - a Proc that will be lazily called to return the former
12+
# - an array is given, its first element is the constant or symbol,
13+
# and its second is a file to `require`.
14+
# @return [void]
15+
#
16+
# @example Lookup by a constant
17+
#
18+
# module Faraday
19+
# class Whatever
20+
# # Middleware looked up by :foo returns Faraday::Whatever::Foo.
21+
# register_middleware :foo => Foo
22+
# end
23+
# end
24+
#
25+
# @example Lookup by a symbol
26+
#
27+
# module Faraday
28+
# class Whatever
29+
# # Middleware looked up by :bar returns Faraday::Whatever.const_get(:Bar)
30+
# register_middleware :bar => :Bar
31+
# end
32+
# end
33+
#
34+
# @example Lookup by a symbol and string in an array
35+
#
36+
# module Faraday
37+
# class Whatever
38+
# # Middleware looked up by :baz requires 'baz' and returns Faraday::Whatever.const_get(:Baz)
39+
# register_middleware :baz => [:Baz, 'baz']
40+
# end
41+
# end
42+
#
43+
def register_middleware(autoload_path = nil, mapping = nil)
44+
if mapping.nil?
45+
mapping = autoload_path
46+
autoload_path = nil
47+
end
48+
middleware_mutex do
49+
@middleware_autoload_path = autoload_path if autoload_path
50+
(@registered_middleware ||= {}).update(mapping)
51+
end
52+
end
53+
54+
# Unregister a previously registered middleware class.
55+
#
56+
# @param key [Symbol] key for the registered middleware.
57+
def unregister_middleware(key)
58+
@registered_middleware.delete(key)
59+
end
60+
61+
# Lookup middleware class with a registered Symbol shortcut.
62+
#
63+
# @param key [Symbol] key for the registered middleware.
64+
# @return [Class] a middleware Class.
65+
# @raise [Faraday::Error] if given key is not registered
66+
#
67+
# @example
68+
#
69+
# module Faraday
70+
# class Whatever
71+
# register_middleware :foo => Foo
72+
# end
73+
# end
74+
#
75+
# Faraday::Whatever.lookup_middleware(:foo)
76+
# # => Faraday::Whatever::Foo
77+
#
78+
def lookup_middleware(key)
79+
load_middleware(key) ||
80+
raise(Faraday::Error.new("#{key.inspect} is not registered on #{self}"))
81+
end
82+
83+
def middleware_mutex(&block)
84+
@middleware_mutex ||= begin
85+
require 'monitor'
86+
Monitor.new
87+
end
88+
@middleware_mutex.synchronize(&block)
89+
end
90+
91+
def fetch_middleware(key)
92+
defined?(@registered_middleware) && @registered_middleware[key]
93+
end
94+
95+
def load_middleware(key)
96+
value = fetch_middleware(key)
97+
case value
98+
when Module
99+
value
100+
when Symbol, String
101+
middleware_mutex do
102+
@registered_middleware[key] = const_get(value)
103+
end
104+
when Proc
105+
middleware_mutex do
106+
@registered_middleware[key] = value.call
107+
end
108+
when Array
109+
middleware_mutex do
110+
const, path = value
111+
if root = @middleware_autoload_path
112+
path = "#{root}/#{path}"
113+
end
114+
require(path)
115+
@registered_middleware[key] = const
116+
end
117+
load_middleware(key)
118+
end
119+
end
120+
end
121+
end

lib/faraday/rack_builder.rb

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def ==(other)
4747
end
4848
end
4949

50-
def build(app)
50+
def build(app = nil)
5151
klass.new(app, *@args, &@block)
5252
end
5353
end
@@ -160,19 +160,14 @@ def build_response(connection, request)
160160
def app
161161
@app ||= begin
162162
lock!
163-
to_app(lambda { |env|
164-
response = Response.new
165-
env.response = response
166-
response.finish(env) unless env.parallel?
167-
response
168-
})
163+
to_app
169164
end
170165
end
171166

172-
def to_app(inner_app)
167+
def to_app
173168
# last added handler is the deepest and thus closest to the inner app
174169
# adapter is always the last one
175-
(@handlers + [@adapter]).reverse.inject(inner_app) { |app, handler| handler.build(app) }
170+
(@handlers).reverse.inject(@adapter.build) { |app, handler| handler.build(app) }
176171
end
177172

178173
def ==(other)

0 commit comments

Comments
 (0)