Skip to content

Commit

Permalink
Ability to configure httpclient send/receive timeout
Browse files Browse the repository at this point in the history
  • Loading branch information
jazminschroeder committed Apr 14, 2014
1 parent 6829cfd commit bc632e9
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 86 deletions.
72 changes: 38 additions & 34 deletions lib/neography/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,53 +7,57 @@ class Config
:max_threads,
:authentication, :username, :password,
:parser, :max_execution_time,
:proxy
:proxy, :http_send_timeout, :http_receive_timeout

def initialize
set_defaults
end

def to_hash
{
:protocol => @protocol,
:server => @server,
:port => @port,
:directory => @directory,
:cypher_path => @cypher_path,
:gremlin_path => @gremlin_path,
:log_file => @log_file,
:log_enabled => @log_enabled,
:logger => @logger,
:slow_log_threshold => @slow_log_threshold,
:max_threads => @max_threads,
:authentication => @authentication,
:username => @username,
:password => @password,
:parser => @parser,
:max_execution_time => @max_execution_time,
:proxy => @proxy
:protocol => @protocol,
:server => @server,
:port => @port,
:directory => @directory,
:cypher_path => @cypher_path,
:gremlin_path => @gremlin_path,
:log_file => @log_file,
:log_enabled => @log_enabled,
:logger => @logger,
:slow_log_threshold => @slow_log_threshold,
:max_threads => @max_threads,
:authentication => @authentication,
:username => @username,
:password => @password,
:parser => @parser,
:max_execution_time => @max_execution_time,
:proxy => @proxy,
:http_send_timeout => @http_send_timeout,
:http_receive_timeout => @http_receive_timeout
}
end

private

def set_defaults
@protocol = "http://"
@server = "localhost"
@port = 7474
@directory = ""
@cypher_path = "/cypher"
@gremlin_path = "/ext/GremlinPlugin/graphdb/execute_script"
@log_file = "neography.log"
@log_enabled = false
@slow_log_threshold = 0
@max_threads = 20
@authentication = nil
@username = nil
@password = nil
@parser = MultiJsonParser
@max_execution_time = 6000
@proxy = nil
@protocol = "http://"
@server = "localhost"
@port = 7474
@directory = ""
@cypher_path = "/cypher"
@gremlin_path = "/ext/GremlinPlugin/graphdb/execute_script"
@log_file = "neography.log"
@log_enabled = false
@slow_log_threshold = 0
@max_threads = 20
@authentication = nil
@username = nil
@password = nil
@parser = MultiJsonParser
@max_execution_time = 6000
@proxy = nil
@http_send_timeout = 1200
@http_receive_timeout = 1200
end

end
Expand Down
34 changes: 17 additions & 17 deletions lib/neography/connection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@ module WasCreated
class Connection
USER_AGENT = "Neography/#{Neography::VERSION}"
ACTIONS = ["get", "post", "put", "delete"]

attr_accessor :protocol, :server, :port, :directory,
:cypher_path, :gremlin_path,
:log_file, :log_enabled, :logger, :slow_log_threshold,
:max_threads,
:authentication, :username, :password,
:parser, :client,
:proxy
:proxy, :http_send_timeout, :http_receive_timeout

def initialize(options = ENV['NEO4J_URL'] || {})
config = merge_configuration(options)
save_local_configuration(config)
@client ||= HTTPClient.new(config[:proxy])
@client.send_timeout = 1200 # 10 minutes
@client.receive_timeout = 1200
@client.send_timeout = config[:http_send_timeout]
@client.receive_timeout = config[:http_receive_timeout]
authenticate
end

Expand All @@ -42,16 +42,16 @@ def merge_options(options)
end

ACTIONS.each do |action|
define_method(action) do |path, options = {}|
define_method(action) do |path, options = {}|
# This ugly hack is required because internal Batch paths do not start with "/db/data"
# if somebody has a cleaner solution... pull request please!
path = "/db/data" + path if ["node", "relationship", "transaction", "cypher", "propertykeys", "schema", "label", "labels", "batch", "index", "ext"].include?(path.split("/")[1].split("?").first)
query_path = configuration + path
query_body = merge_options(options)[:body]
query_body = merge_options(options)[:body]
log path, query_body do
evaluate_response(@client.send(action.to_sym, query_path, query_body, merge_options(options)[:headers]), path, query_body)
evaluate_response(@client.send(action.to_sym, query_path, query_body, merge_options(options)[:headers]), path, query_body)
end
end
end
end

def log(path, body)
Expand Down Expand Up @@ -80,7 +80,7 @@ def authenticate(path = nil)
@client.www_auth.basic_auth.challenge(configuration) if auth_type == 'basic_auth'
end
end

private

def merge_configuration(options)
Expand Down Expand Up @@ -143,13 +143,13 @@ def handle_batch(response)
body = @parser.json(response.body.force_encoding("UTF-8"))
body.each do |result|
if result["status"] >= 400
code = result["status"]
code = result["status"]
break
end
end
return code, body, true
end

def return_result(response, code, body, parsed, path, query_body)
case code
when 200
Expand All @@ -166,7 +166,7 @@ def return_result(response, code, body, parsed, path, query_body)
when 400..500
handle_4xx_500_response(response, code, body, path, query_body)
nil
end
end
end

def handle_4xx_500_response(response, code, body, path, query_body)
Expand All @@ -184,7 +184,7 @@ def handle_4xx_500_response(response, code, body, path, query_body)
parsed_body = result["body"] || result
break
end
end
end
else
parsed_body = @parser.json(body)
end
Expand All @@ -195,7 +195,7 @@ def handle_4xx_500_response(response, code, body, path, query_body)
@logger.error "#{response.dump} error: #{body}" if @log_enabled
raise_errors(code, parsed_body["exception"], message, stacktrace, request, index)
end

def raise_errors(code, exception, message, stacktrace, request, index)
error = nil
case code
Expand All @@ -215,12 +215,12 @@ def raise_errors(code, exception, message, stacktrace, request, index)
when /RelationshipNotFoundException/ ; RelationshipNotFoundException
when /NotFoundException/ ; NotFoundException
when /UniquePathNotUniqueException/ ; UniquePathNotUniqueException
when /DeadlockDetectedException/ ; DeadlockDetectedException
when /DeadlockDetectedException/ ; DeadlockDetectedException
else
NeographyError
end
raise error.new(message, code, stacktrace, request, index)

raise error.new(message, code, stacktrace, request, index)
end

def parse_string_options(options)
Expand Down
73 changes: 39 additions & 34 deletions spec/unit/config_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,49 @@ module Neography

context "defaults" do

its(:protocol) { should == 'http://' }
its(:server) { should == 'localhost' }
its(:port) { should == 7474 }
its(:directory) { should == '' }
its(:cypher_path) { should == '/cypher' }
its(:gremlin_path) { should == '/ext/GremlinPlugin/graphdb/execute_script' }
its(:log_file) { should == 'neography.log' }
its(:log_enabled) { should == false }
its(:logger) { should == nil }
its(:slow_log_threshold) { should == 0 }
its(:max_threads) { should == 20 }
its(:authentication) { should == nil }
its(:username) { should == nil }
its(:password) { should == nil }
its(:parser) { should == MultiJsonParser}
its(:max_execution_time) { should == 6000 }
its(:proxy) { should == nil }
its(:protocol) { should == 'http://' }
its(:server) { should == 'localhost' }
its(:port) { should == 7474 }
its(:directory) { should == '' }
its(:cypher_path) { should == '/cypher' }
its(:gremlin_path) { should == '/ext/GremlinPlugin/graphdb/execute_script' }
its(:log_file) { should == 'neography.log' }
its(:log_enabled) { should == false }
its(:logger) { should == nil }
its(:slow_log_threshold) { should == 0 }
its(:max_threads) { should == 20 }
its(:authentication) { should == nil }
its(:username) { should == nil }
its(:password) { should == nil }
its(:parser) { should == MultiJsonParser}
its(:max_execution_time) { should == 6000 }
its(:proxy) { should == nil }
its(:http_send_timeout) { should == 1200 }
its(:http_receive_timeout) { should == 1200 }


it "has a hash representation" do
expected_hash = {
:protocol => 'http://',
:server => 'localhost',
:port => 7474,
:directory => '',
:cypher_path => '/cypher',
:gremlin_path => '/ext/GremlinPlugin/graphdb/execute_script',
:log_file => 'neography.log',
:log_enabled => false,
:logger => nil,
:slow_log_threshold => 0,
:max_threads => 20,
:authentication => nil,
:username => nil,
:password => nil,
:parser => MultiJsonParser,
:max_execution_time => 6000,
:proxy => nil
:protocol => 'http://',
:server => 'localhost',
:port => 7474,
:directory => '',
:cypher_path => '/cypher',
:gremlin_path => '/ext/GremlinPlugin/graphdb/execute_script',
:log_file => 'neography.log',
:log_enabled => false,
:logger => nil,
:slow_log_threshold => 0,
:max_threads => 20,
:authentication => nil,
:username => nil,
:password => nil,
:parser => MultiJsonParser,
:max_execution_time => 6000,
:proxy => nil,
:http_send_timeout => 1200,
:http_receive_timeout => 1200

}
config.to_hash.should == expected_hash
end
Expand Down
21 changes: 20 additions & 1 deletion spec/unit/connection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,27 @@ module Neography
}
}
end

context "httpclient" do
let(:httpclient) { double(:http_client) }
let(:options) do
{
:http_send_timeout => 120,
:http_receive_timeout => 120
}
end

it 'configures send/receive timeout' do
HTTPClient.should_receive(:new).and_return(httpclient)
httpclient.should_receive(:send_timeout=).with(120)
httpclient.should_receive(:receive_timeout=).with(120)
connection
end
end
end



context "string option" do
let(:options) { "https://user:pass@somehost:8585/path" }

Expand Down Expand Up @@ -256,4 +275,4 @@ module Neography
end
end

class Foo; end
class Foo; end

0 comments on commit bc632e9

Please sign in to comment.