Class: Async::HTTP::Client

Inherits:
Object
  • Object
show all
Includes:
Methods
Defined in:
lib/async/http/client.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(endpoint, protocol = nil, authority = nil, retries: 3, **options) ⇒ Client

Returns a new instance of Client.



30
31
32
33
34
35
36
37
38
# File 'lib/async/http/client.rb', line 30

def initialize(endpoint, protocol = nil, authority = nil, retries: 3, **options)
	@endpoint = endpoint
	
	@protocol = protocol || endpoint.protocol
	@authority = authority || endpoint.hostname
	
	@retries = retries
	@pool = connect(**options)
end

Instance Attribute Details

#authorityObject (readonly)

Returns the value of attribute authority.



42
43
44
# File 'lib/async/http/client.rb', line 42

def authority
  @authority
end

#endpointObject (readonly)

Returns the value of attribute endpoint.



40
41
42
# File 'lib/async/http/client.rb', line 40

def endpoint
  @endpoint
end

#poolObject (readonly)

Returns the value of attribute pool.



45
46
47
# File 'lib/async/http/client.rb', line 45

def pool
  @pool
end

#protocolObject (readonly)

Returns the value of attribute protocol.



41
42
43
# File 'lib/async/http/client.rb', line 41

def protocol
  @protocol
end

#retriesObject (readonly)

Returns the value of attribute retries.



44
45
46
# File 'lib/async/http/client.rb', line 44

def retries
  @retries
end

Class Method Details

.open(*args, &block) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
# File 'lib/async/http/client.rb', line 47

def self.open(*args, &block)
	client = self.new(*args)
	
	return client unless block_given?
	
	begin
		yield client
	ensure
		client.close
	end
end

Instance Method Details

#call(request) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/async/http/client.rb', line 65

def call(request)
	request.authority ||= @authority
	attempt = 0
	
	# We may retry the request if it is possible to do so. https://tools.ietf.org/html/draft-nottingham-httpbis-retry-01 is a good guide for how retrying requests should work.
	begin
		attempt += 1
		
		# As we cache pool, it's possible these pool go bad (e.g. closed by remote host). In this case, we need to try again. It's up to the caller to impose a timeout on this. If this is the last attempt, we force a new connection.
		connection = @pool.acquire
		
		response = connection.call(request)
		
		# The connection won't be released until the body is completely read/released.
		Body::Streamable.wrap(response) do
			@pool.release(connection)
		end
		
		return response
	rescue Protocol::RequestFailed
		# This is a specific case where the entire request wasn't sent before a failure occurred. So, we can even resend non-idempotent requests.
		@pool.release(connection)
		
		attempt += 1
		if attempt < @retries
			retry
		else
			raise
		end
	rescue
		@pool.release(connection)
		
		if request.idempotent? and attempt < @retries
			retry
		else
			raise
		end
	end
end

#closeObject



59
60
61
# File 'lib/async/http/client.rb', line 59

def close
	@pool.close
end