Class: Async::REST::Wrapper::Generic

Inherits:
Object
  • Object
show all
Defined in:
lib/async/rest/wrapper/generic.rb

Direct Known Subclasses

Form, JSON, URLEncoded

Defined Under Namespace

Classes: Unsupported

Instance Method Summary collapse

Instance Method Details

#call(resource, method = "GET", payload = nil, &block) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/async/rest/wrapper/generic.rb', line 34

def call(resource, method = "GET", payload = nil, &block)
	request = ::Protocol::HTTP::Request[method, nil]
	
	self.prepare_request(request, payload)
	
	response = self.response_for(resource, request)
	
	# If we exit this block because of an exception, we close the response. This ensures we don't have any dangling connections.
	begin
		self.process_response(request, response)
		
		yield response
	rescue
		response.close
		
		raise
	end
end

#parser_for(response) ⇒ Object



67
68
69
70
# File 'lib/async/rest/wrapper/generic.rb', line 67

def parser_for(response)
	# It's not always clear why this error is being thrown.
	return nil
end

#prepare_request(request, payload) ⇒ Body | nil

Returns an optional request body based on the given payload.

Parameters:

  • payload (Object)

    a request payload to send.

  • headers (Protocol::HTTP::Headers)

    the mutable HTTP headers for the request.

Returns:

  • (Body | nil)

    an optional request body based on the given payload.



56
57
58
# File 'lib/async/rest/wrapper/generic.rb', line 56

def prepare_request(request, payload)
	request.body = ::Protocol::HTTP::Body::Buffered.wrap(payload)
end

#process_response(request, response) ⇒ Object

Returns some application specific representation of the response.

Parameters:

  • request (Protocol::HTTP::Request)

    the request that was made.

  • response (Protocol::HTTP::Response)

    the response that was received.

Returns:

  • (Object)

    some application specific representation of the response.



63
64
65
# File 'lib/async/rest/wrapper/generic.rb', line 63

def process_response(request, response)
	wrap_response(response)
end

#response_for(resource, request) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/async/rest/wrapper/generic.rb', line 17

def response_for(resource, request)
	while true
		response = resource.call(request)
		
		if response.status == 429
			if retry_after = response.headers["retry-after"]
				sleep(retry_after_duration(retry_after))
			else
				# Without the `retry-after` header, we can't determine how long to wait, so we just return the response.
				return response
			end
		else
			return response
		end
	end
end

#retry_after_duration(value) ⇒ Object



10
11
12
13
14
15
# File 'lib/async/rest/wrapper/generic.rb', line 10

def retry_after_duration(value)
	retry_after_time = Time.httpdate(value)
	return [retry_after_time - Time.now, 0].max
rescue ArgumentError
	return value.to_f
end

#wrap_response(response) ⇒ Object

Wrap the response body in the given klass.



73
74
75
76
77
78
79
80
81
# File 'lib/async/rest/wrapper/generic.rb', line 73

def wrap_response(response)
	if body = response.body
		if parser = parser_for(response)
			response.body = parser.new(body)
		end
	end
	
	return response
end