class Async::HTTP::Client

def call(request)

def call(request)
	request.authority ||= @authority
	attempt = 0
	
	# There is a challenge with how this works. If you have 8 connections in the connection pool and they've all expired, retrying 3 times isn't going to work. We need to, perhaps, on the last retry, initiate a completely new connection.
	begin
		attempt += 1
		
		# As we cache connections, it's possible these connections 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 = @connections.acquire
		
		response = connection.call(request)
		
		# The connection won't be released until the body is completely read/released.
		Body::Streamable.wrap(response) do
			@connections.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.
		@connections.release(connection)
		
		attempt += 1
		if attempt < @retries
			retry
		else
			raise
		end
	rescue
		@connections.release(connection)
		
		if request.idempotent? and attempt < @retries
			retry
		else
			raise
		end
	end
end