Skip to content

Commit f3ece8d

Browse files
authored
Merge pull request #9 from bramski/master
Add timeout capability.
2 parents 56f2f6a + f3b3cb5 commit f3ece8d

File tree

6 files changed

+85
-8
lines changed

6 files changed

+85
-8
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,20 @@ uer.delete('contacts') # will remove user entities for given session
145145
#Error handling
146146
**ApiAiRuby::Client** currently able to raise two kind of errors: **ApiAiRuby::ClientError** (due to configuration mismatch) and **ApiAiRuby::RequestError** in case of something goes wrong during request. For both kind of errors you can get **error.message** (as usual) and **ApiAiRuby::RequestError** can additionally give you code of server error (you can get it with **error.code**)
147147

148+
#Timeouts
149+
**ApiAiRuby::Client** uses the [http gem](https://github.com/httprb/http) under the hood. You can use ```timeout_options``` on the client to set these.
150+
```ruby
151+
ApiAiRuby::Client.new(
152+
client_access_token: 'YOUR_ACCESS_TOKEN',
153+
api_lang: 'FR',
154+
api_base_url: 'http://example.com/v1/',
155+
api_version: 'YYYYMMDD',
156+
api_session_id: 'some_uuid_or_whatever',
157+
timeout_options: [:global, { write: 1, connect: 1, read: 1 }]
158+
)
159+
```
160+
161+
Please see the [httprb wiki on timeouts](https://github.com/httprb/http/wiki/Timeouts) for more information.
148162

149163
#Changelog
150164

lib/api-ai-ruby/client.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
module ApiAiRuby
44
class Client
5-
attr_accessor :client_access_token, :subscription_key
5+
attr_accessor :client_access_token, :subscription_key, :timeout_options
66
attr_writer :user_agent, :api_version, :api_lang, :api_base_url, :api_session_id
77

88
# Initializes a new Client object

lib/api-ai-ruby/request/request_query.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
module ApiAiRuby
44
class RequestQuery
55

6-
attr_accessor :client, :headers, :options, :request_method, :uri
6+
attr_accessor :client, :headers, :options, :request_method, :uri
77

88
# @param client [ApiAiRuby::Client]
99
# @param options [Hash]
@@ -18,20 +18,21 @@ def initialize(client, options = {})
1818
@headers = {
1919
Authorization: 'Bearer ' + client.client_access_token,
2020
}
21+
@timeout_options = client.timeout_options || options[:timeout_options]
2122
end
2223

2324
# @return [Array, Hash]
2425
def perform
25-
2626
if @options.has_key?(:voiceData)
2727
options_key = :form
2828
else
2929
options_key = (@request_method === :get) ? :params : :json
3030
end
3131

32-
response = HTTP.with(@headers).public_send(@request_method, @uri.to_s, options_key => @options)
32+
request = HTTP.with(@headers)
33+
request = request.timeout(*@timeout_options) if @timeout_options
34+
response = request.public_send(@request_method, @uri.to_s, options_key => @options)
3335
response_body = symbolize_keys!(response.parse)
34-
response_headers = response.headers
3536
fail_or_return_response_body(response.code, response_body)
3637
end
3738

spec/api-ai-ruby/client_spec.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,15 @@
4848
api_lang: 'RU',
4949
api_base_url: 'http://localhost',
5050
api_version: '1234',
51-
api_session_id: '555'
51+
api_session_id: '555',
52+
timeout_options: [:global, { write: 1, connect: 1, read: 1}]
5253
)
5354

5455
expect(client.api_base_url).to eq 'http://localhost'
5556
expect(client.api_version).to eq '1234'
5657
expect(client.api_lang).to eq 'RU'
5758
expect(client.api_session_id).to eq '555'
59+
expect(client.timeout_options).to eq [:global, { write: 1, connect: 1, read: 1}]
5860
end
5961

6062

spec/api-ai-ruby/text_request_spec.rb

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
require 'helper'
2+
3+
describe ApiAiRuby::TextRequest do
4+
let(:client) do
5+
ApiAiRuby::Client.new(
6+
client_access_token: 'CS',
7+
api_lang: 'EN',
8+
api_session_id: '555',
9+
timeout_options: [:global, { write: 1, connect: 1, read: 1 }]
10+
)
11+
end
12+
13+
subject(:text_request) { described_class.new(client, options) }
14+
let(:options) { { query: "hello" } }
15+
16+
around do |test|
17+
begin
18+
WebMock.disable_net_connect!(allow: 'coveralls.io')
19+
test.run
20+
ensure
21+
WebMock.allow_net_connect!
22+
end
23+
end
24+
25+
let(:response_headers) do
26+
{ "Content-Type" => "application/json;charset=UTF-8", "Content-Length" => "437", "Connection" => "close", "Access-Control-Allow-Credentials" => "true", "Cache-Control" => "no-cache=\"set-cookie\"", "Date" => "Wed, 12 Oct 2016 20:07:54 GMT", "Server" => "nginx/1.9.7", "Set-Cookie" => "AWSELB=9D5B4D210CCFFAF1BE1E0CD7C7E6FCBD7B46140CAAF64A202A005B9079598B549F7A5EC269DD0FF88508DA57410EFC7882B7860453691E7ACC870186C9D1589D2A332B51EC;PATH=/", "X-Cache" => "Miss from cloudfront", "Via" => "1.1 978198446b6fdba8a499c04f84a3a7e6.cloudfront.net (CloudFront)", "X-Amz-Cf-Id" => "ilwhpG75Ea4iXumklw7484nYt2jbx-L6ZaeiO9naUOstx45ia_nuaQ==" }
27+
end
28+
let(:body) do
29+
{ :id => "94613973-930f-4a53-9286-6e9efcbb5c57", :timestamp => "2016-10-12T20:07:54.876Z", :result => { :source => "domains", :resolvedQuery => "hello", :action => "smalltalk.greetings", :parameters => { :simplified => "hello" }, :metadata => {}, :fulfillment => { :speech => "Good day!" }, :score => 0.0 }, :status => { :code => 200, :errorType => "success" }, :sessionId => "555" }
30+
end
31+
let(:expected_headers) do
32+
{ 'Authorization' => 'Bearer CS', 'Connection' => 'close', 'Content-Type' => 'application/json; charset=UTF-8', 'Host' => 'api.api.ai' }
33+
end
34+
let(:expected_url) { "https://api.api.ai/v1/query?v=20150910" }
35+
let(:expected_body) { '{"query":"hello","lang":"EN","sessionId":"555"}' }
36+
37+
describe "#perform" do
38+
it "performs a request" do
39+
stub = stub_request(:post, expected_url).
40+
with(:body => expected_body,
41+
:headers => expected_headers).
42+
to_return(:status => 200, :body => body.to_json, :headers => response_headers)
43+
subject.perform
44+
expect(stub).to have_been_requested
45+
end
46+
47+
context "it times out" do
48+
it "times out properly" do
49+
stub = stub_request(:post, expected_url).
50+
with(:body => expected_body,
51+
:headers => expected_headers).to_timeout
52+
expect {
53+
subject.perform
54+
}.to raise_error(Errno::ETIMEDOUT)
55+
expect(stub).to have_been_requested
56+
end
57+
end
58+
end
59+
end

spec/helper.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@
1212

1313
require 'api-ai-ruby'
1414
require 'rspec'
15-
#require 'webmock/rspec'
15+
require 'webmock'
16+
require 'webmock/rspec'
1617

17-
#WebMock.disable_net_connect!(allow: 'coveralls.io')
18+
WebMock.allow_net_connect!
1819

1920
RSpec.configure do |config|
2021
config.expect_with :rspec do |c|

0 commit comments

Comments
 (0)