elasticsearch-transport 1.0.16 → 1.0.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/elasticsearch/transport/transport/base.rb +60 -19
- data/lib/elasticsearch/transport/transport/connections/collection.rb +20 -0
- data/lib/elasticsearch/transport/transport/connections/connection.rb +10 -0
- data/lib/elasticsearch/transport/transport/http/curb.rb +13 -21
- data/lib/elasticsearch/transport/transport/http/faraday.rb +5 -20
- data/lib/elasticsearch/transport/version.rb +1 -1
- data/test/integration/client_test.rb +23 -1
- data/test/unit/connection_collection_test.rb +44 -2
- data/test/unit/connection_test.rb +9 -0
- data/test/unit/transport_base_test.rb +26 -7
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03da4187dfe5748e0a63a03b5311e69a16c300ee
|
4
|
+
data.tar.gz: e5150265f830efda95bf5da80f2fe9e89cd8b98f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1fdb7e4a825042933383ec0fe4bddd3db31996e73f1095cc7c406889bbea887d14827e7c28357b9bf86eaeca4b6995a65f019897c3385f4f9da0b2f2849c364c
|
7
|
+
data.tar.gz: 6281a6bada7e2db9aac41397539cc1ab9aeec92fae134a9286b8461e1b4d05abb6f600a05ffe70325cd377d3c0164df5da118d1b43503b9793faf8404868d82b
|
@@ -18,7 +18,7 @@ module Elasticsearch
|
|
18
18
|
:reload_connections, :reload_after,
|
19
19
|
:resurrect_after, :max_retries
|
20
20
|
|
21
|
-
# Creates a new transport object
|
21
|
+
# Creates a new transport object
|
22
22
|
#
|
23
23
|
# @param arguments [Hash] Settings and options for the transport
|
24
24
|
# @param block [Proc] Lambda or Proc which can be evaluated in the context of the "session" object
|
@@ -71,7 +71,7 @@ module Elasticsearch
|
|
71
71
|
connections.get_connection(options)
|
72
72
|
end
|
73
73
|
|
74
|
-
# Reloads and replaces the connection collection based on cluster information
|
74
|
+
# Reloads and replaces the connection collection based on cluster information
|
75
75
|
#
|
76
76
|
# @see Sniffer#hosts
|
77
77
|
#
|
@@ -84,7 +84,7 @@ module Elasticsearch
|
|
84
84
|
self
|
85
85
|
end
|
86
86
|
|
87
|
-
# Tries to "resurrect" all eligible dead connections
|
87
|
+
# Tries to "resurrect" all eligible dead connections
|
88
88
|
#
|
89
89
|
# @see Connections::Connection#resurrect!
|
90
90
|
#
|
@@ -92,28 +92,74 @@ module Elasticsearch
|
|
92
92
|
connections.dead.each { |c| c.resurrect! }
|
93
93
|
end
|
94
94
|
|
95
|
-
#
|
95
|
+
# Rebuilds the connections collection in the transport.
|
96
96
|
#
|
97
|
+
# The methods *adds* new connections from the passed hosts to the collection,
|
98
|
+
# and *removes* all connections not contained in the passed hosts.
|
99
|
+
#
|
100
|
+
# @return [Connections::Collection]
|
97
101
|
# @api private
|
98
102
|
#
|
99
103
|
def __rebuild_connections(arguments={})
|
100
104
|
@state_mutex.synchronize do
|
101
105
|
@hosts = arguments[:hosts] || []
|
102
106
|
@options = arguments[:options] || {}
|
107
|
+
|
103
108
|
__close_connections
|
104
|
-
|
109
|
+
|
110
|
+
new_connections = __build_connections
|
111
|
+
stale_connections = @connections.select { |c| ! new_connections.include?(c) }
|
112
|
+
new_connections = new_connections.reject { |c| @connections.include?(c) }
|
113
|
+
|
114
|
+
@connections.remove(stale_connections)
|
115
|
+
@connections.add(new_connections)
|
116
|
+
@connections
|
105
117
|
end
|
106
118
|
end
|
107
119
|
|
108
|
-
#
|
120
|
+
# Builds and returns a collection of connections
|
121
|
+
#
|
122
|
+
# The adapters have to implement the {Base#__build_connection} method.
|
123
|
+
#
|
124
|
+
# @return [Connections::Collection]
|
125
|
+
# @api private
|
126
|
+
#
|
127
|
+
def __build_connections
|
128
|
+
Connections::Collection.new \
|
129
|
+
:connections => hosts.map { |host|
|
130
|
+
host[:protocol] = host[:scheme] || options[:scheme] || options[:http][:scheme] || DEFAULT_PROTOCOL
|
131
|
+
host[:port] ||= options[:port] || options[:http][:scheme] || DEFAULT_PORT
|
132
|
+
if (options[:user] || options[:http][:user]) && !host[:user]
|
133
|
+
host[:user] ||= options[:user] || options[:http][:user]
|
134
|
+
host[:password] ||= options[:password] || options[:http][:password]
|
135
|
+
end
|
136
|
+
|
137
|
+
__build_connection(host, (options[:transport_options] || {}), @block)
|
138
|
+
},
|
139
|
+
:selector_class => options[:selector_class],
|
140
|
+
:selector => options[:selector]
|
141
|
+
end
|
142
|
+
|
143
|
+
# @abstract Build and return a connection.
|
144
|
+
# A transport implementation *must* implement this method.
|
145
|
+
# See {HTTP::Faraday#__build_connection} for an example.
|
146
|
+
#
|
147
|
+
# @return [Connections::Connection]
|
148
|
+
# @api private
|
149
|
+
#
|
150
|
+
def __build_connection(host, options={}, block=nil)
|
151
|
+
raise NoMethodError, "Implement this method in your class"
|
152
|
+
end
|
153
|
+
|
154
|
+
# Closes the connections collection
|
109
155
|
#
|
110
156
|
# @api private
|
111
157
|
#
|
112
158
|
def __close_connections
|
113
|
-
#
|
159
|
+
# A hook point for specific adapters when they need to close connections
|
114
160
|
end
|
115
161
|
|
116
|
-
# Log request and response information
|
162
|
+
# Log request and response information
|
117
163
|
#
|
118
164
|
# @api private
|
119
165
|
#
|
@@ -125,16 +171,18 @@ module Elasticsearch
|
|
125
171
|
logger.debug "< #{response.body}"
|
126
172
|
end
|
127
173
|
|
128
|
-
# Log failed request
|
174
|
+
# Log failed request
|
129
175
|
#
|
130
176
|
# @api private
|
177
|
+
#
|
131
178
|
def __log_failed(response)
|
132
179
|
logger.fatal "[#{response.status}] #{response.body}"
|
133
180
|
end
|
134
181
|
|
135
|
-
# Trace the request in the `curl` format
|
182
|
+
# Trace the request in the `curl` format
|
136
183
|
#
|
137
184
|
# @api private
|
185
|
+
#
|
138
186
|
def __trace(method, path, params, body, url, response, json, took, duration)
|
139
187
|
trace_url = "http://localhost:9200/#{path}?pretty" +
|
140
188
|
( params.empty? ? '' : "&#{::Faraday::Utils::ParamsHash[params].to_query}" )
|
@@ -147,6 +195,7 @@ module Elasticsearch
|
|
147
195
|
# Raise error specific for the HTTP response status or a generic server error
|
148
196
|
#
|
149
197
|
# @api private
|
198
|
+
#
|
150
199
|
def __raise_transport_error(response)
|
151
200
|
error = ERRORS[response.status] || ServerError
|
152
201
|
raise error.new "[#{response.status}] #{response.body}"
|
@@ -155,6 +204,7 @@ module Elasticsearch
|
|
155
204
|
# Converts any non-String object to JSON
|
156
205
|
#
|
157
206
|
# @api private
|
207
|
+
#
|
158
208
|
def __convert_to_json(o=nil, options={})
|
159
209
|
o = o.is_a?(String) ? o : serializer.dump(o, options)
|
160
210
|
end
|
@@ -281,15 +331,6 @@ module Elasticsearch
|
|
281
331
|
def host_unreachable_exceptions
|
282
332
|
[Errno::ECONNREFUSED]
|
283
333
|
end
|
284
|
-
|
285
|
-
# @abstract A transport implementation must implement this method.
|
286
|
-
# See {HTTP::Faraday#__build_connections} for an example.
|
287
|
-
#
|
288
|
-
# @return [Connections::Collection]
|
289
|
-
# @api private
|
290
|
-
def __build_connections
|
291
|
-
raise NoMethodError, "Implement this method in your class"
|
292
|
-
end
|
293
334
|
end
|
294
335
|
end
|
295
336
|
end
|
@@ -85,6 +85,26 @@ module Elasticsearch
|
|
85
85
|
def size
|
86
86
|
connections.size
|
87
87
|
end
|
88
|
+
|
89
|
+
# Add connection(s) to the collection
|
90
|
+
#
|
91
|
+
# @param connections [Connection,Array] A connection or an array of connections to add
|
92
|
+
# @return [self]
|
93
|
+
#
|
94
|
+
def add(connections)
|
95
|
+
@connections += Array(connections).to_a
|
96
|
+
self
|
97
|
+
end
|
98
|
+
|
99
|
+
# Remove connection(s) from the collection
|
100
|
+
#
|
101
|
+
# @param connections [Connection,Array] A connection or an array of connections to remove
|
102
|
+
# @return [self]
|
103
|
+
#
|
104
|
+
def remove(connections)
|
105
|
+
@connections -= Array(connections).to_a
|
106
|
+
self
|
107
|
+
end
|
88
108
|
end
|
89
109
|
|
90
110
|
end
|
@@ -118,6 +118,16 @@ module Elasticsearch
|
|
118
118
|
}
|
119
119
|
end
|
120
120
|
|
121
|
+
# Equality operator based on connection protocol, host and port
|
122
|
+
#
|
123
|
+
# @return [Boolean]
|
124
|
+
#
|
125
|
+
def ==(other)
|
126
|
+
self.host[:protocol] == other.host[:protocol] && \
|
127
|
+
self.host[:host] == other.host[:host] && \
|
128
|
+
self.host[:port].to_i == other.host[:port].to_i
|
129
|
+
end
|
130
|
+
|
121
131
|
# @return [String]
|
122
132
|
#
|
123
133
|
def to_s
|
@@ -37,32 +37,24 @@ module Elasticsearch
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
|
-
# Builds and returns a
|
40
|
+
# Builds and returns a connection
|
41
41
|
#
|
42
|
-
# @return [Connections::
|
42
|
+
# @return [Connections::Connection]
|
43
43
|
#
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
host[:port] ||= DEFAULT_PORT
|
44
|
+
def __build_connection(host, options={}, block=nil)
|
45
|
+
client = ::Curl::Easy.new
|
46
|
+
client.headers = {'User-Agent' => "Curb #{Curl::CURB_VERSION}"}
|
47
|
+
client.url = __full_url(host)
|
49
48
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
client.http_auth_types = host[:auth_type] || :basic
|
56
|
-
client.username = host[:user]
|
57
|
-
client.password = host[:password]
|
58
|
-
end
|
49
|
+
if host[:user]
|
50
|
+
client.http_auth_types = host[:auth_type] || :basic
|
51
|
+
client.username = host[:user]
|
52
|
+
client.password = host[:password]
|
53
|
+
end
|
59
54
|
|
60
|
-
|
55
|
+
client.instance_eval(&block) if block
|
61
56
|
|
62
|
-
|
63
|
-
},
|
64
|
-
:selector_class => options[:selector_class],
|
65
|
-
:selector => options[:selector]
|
57
|
+
Connections::Connection.new :host => host, :connection => client
|
66
58
|
end
|
67
59
|
|
68
60
|
# Returns an array of implementation specific connection errors.
|
@@ -27,28 +27,13 @@ module Elasticsearch
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
# Builds and returns a
|
30
|
+
# Builds and returns a connection
|
31
31
|
#
|
32
|
-
# @return [Connections::
|
32
|
+
# @return [Connections::Connection]
|
33
33
|
#
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
host[:protocol] = host[:scheme] || options[:scheme] || options[:http][:scheme] || DEFAULT_PROTOCOL
|
38
|
-
host[:port] ||= options[:port] || options[:http][:scheme] || DEFAULT_PORT
|
39
|
-
if (options[:user] || options[:http][:user]) && !host[:user]
|
40
|
-
host[:user] ||= options[:user] || options[:http][:user]
|
41
|
-
host[:password] ||= options[:password] || options[:http][:password]
|
42
|
-
end
|
43
|
-
|
44
|
-
url = __full_url(host)
|
45
|
-
|
46
|
-
Connections::Connection.new \
|
47
|
-
:host => host,
|
48
|
-
:connection => ::Faraday::Connection.new(url, (options[:transport_options] || {}), &@block )
|
49
|
-
},
|
50
|
-
:selector_class => options[:selector_class],
|
51
|
-
:selector => options[:selector]
|
34
|
+
def __build_connection(host, options={}, block=nil)
|
35
|
+
client = ::Faraday::Connection.new(__full_url(host), options, &block)
|
36
|
+
Connections::Connection.new :host => host, :connection => client
|
52
37
|
end
|
53
38
|
|
54
39
|
# Returns an array of implementation specific connection errors.
|
@@ -12,7 +12,6 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
|
|
12
12
|
context "Elasticsearch client" do
|
13
13
|
teardown do
|
14
14
|
begin; Object.send(:remove_const, :Typhoeus); rescue NameError; end
|
15
|
-
begin; Object.send(:remove_const, :Patron); rescue NameError; end
|
16
15
|
begin; Net::HTTP.send(:remove_const, :Persistent); rescue NameError; end
|
17
16
|
end
|
18
17
|
|
@@ -168,6 +167,27 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
|
|
168
167
|
end
|
169
168
|
end
|
170
169
|
|
170
|
+
context "when reloading connections" do
|
171
|
+
should "keep existing connections" do
|
172
|
+
require 'patron' # We need a client with keep-alive
|
173
|
+
client = Elasticsearch::Transport::Client.new host: "localhost:#{@port}", adapter: :patron, logger: @logger
|
174
|
+
|
175
|
+
assert_equal 'Faraday::Adapter::Patron',
|
176
|
+
client.transport.connections.first.connection.builder.handlers.first.name
|
177
|
+
|
178
|
+
response = client.perform_request 'GET', '_nodes/stats/http'
|
179
|
+
|
180
|
+
a = response.body['nodes'].values.select { |n| n['name'] == 'node-1' }.first['http']['total_opened']
|
181
|
+
|
182
|
+
client.transport.reload_connections!
|
183
|
+
|
184
|
+
response = client.perform_request 'GET', '_nodes/stats/http'
|
185
|
+
b = response.body['nodes'].values.select { |n| n['name'] == 'node-1' }.first['http']['total_opened']
|
186
|
+
|
187
|
+
assert_equal a, b
|
188
|
+
end unless JRUBY
|
189
|
+
end
|
190
|
+
|
171
191
|
context "with Faraday adapters" do
|
172
192
|
should "set the adapter with a block" do
|
173
193
|
require 'net/http/persistent'
|
@@ -184,6 +204,8 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
|
|
184
204
|
end
|
185
205
|
|
186
206
|
should "automatically use the Patron client when loaded" do
|
207
|
+
teardown { begin; Object.send(:remove_const, :Patron); rescue NameError; end }
|
208
|
+
|
187
209
|
require 'patron'
|
188
210
|
client = Elasticsearch::Transport::Client.new host: "localhost:#{@port}"
|
189
211
|
|
@@ -43,6 +43,48 @@ class Elasticsearch::Transport::Transport::Connections::CollectionTest < Test::U
|
|
43
43
|
assert_equal 2, c.size
|
44
44
|
end
|
45
45
|
|
46
|
+
should "add connections" do
|
47
|
+
c = Collection.new :connections => [ Connection.new(:host => { :protocol => 'http', :host => 'foo', :port => 1}) ]
|
48
|
+
assert_equal 1, c.size
|
49
|
+
|
50
|
+
c.add([ Connection.new(:host => { :protocol => 'http', :host => 'bar', :port => 1 }),
|
51
|
+
Connection.new(:host => { :protocol => 'http', :host => 'bam', :port => 1 }) ])
|
52
|
+
assert_equal 3, c.size
|
53
|
+
end
|
54
|
+
|
55
|
+
should "add connection" do
|
56
|
+
c = Collection.new :connections => [ Connection.new(:host => { :protocol => 'http', :host => 'foo', :port => 1}) ]
|
57
|
+
assert_equal 1, c.size
|
58
|
+
|
59
|
+
c.add(Connection.new(:host => { :protocol => 'http', :host => 'bar', :port => 1 }))
|
60
|
+
assert_equal 2, c.size
|
61
|
+
end
|
62
|
+
|
63
|
+
should "remove connections" do
|
64
|
+
c = Collection.new :connections => [
|
65
|
+
Connection.new(:host => { :protocol => 'http', :host => 'foo', :port => 1 }),
|
66
|
+
Connection.new(:host => { :protocol => 'http', :host => 'bar', :port => 1 })
|
67
|
+
]
|
68
|
+
assert_equal 2, c.size
|
69
|
+
|
70
|
+
c.remove([c.first])
|
71
|
+
assert_equal 1, c.size
|
72
|
+
|
73
|
+
c.remove(c)
|
74
|
+
assert_equal 0, c.size
|
75
|
+
end
|
76
|
+
|
77
|
+
should "remove connection" do
|
78
|
+
c = Collection.new :connections => [
|
79
|
+
Connection.new(:host => { :protocol => 'http', :host => 'foo', :port => 1 }),
|
80
|
+
Connection.new(:host => { :protocol => 'http', :host => 'bar', :port => 1 })
|
81
|
+
]
|
82
|
+
assert_equal 2, c.size
|
83
|
+
|
84
|
+
c.remove(c.first)
|
85
|
+
assert_equal 1, c.size
|
86
|
+
end
|
87
|
+
|
46
88
|
context "with the dead pool" do
|
47
89
|
setup do
|
48
90
|
@collection = Collection.new :connections => [ Connection.new(:host => 'foo'), Connection.new(:host => 'bar') ]
|
@@ -66,8 +108,8 @@ class Elasticsearch::Transport::Transport::Connections::CollectionTest < Test::U
|
|
66
108
|
end
|
67
109
|
|
68
110
|
should "resurrect dead connection with least failures when no alive is available" do
|
69
|
-
c1 = Connection.new(:host => 'foo').dead!.dead!
|
70
|
-
c2 = Connection.new(:host => 'bar').dead!
|
111
|
+
c1 = Connection.new(:host => { :protocol => 'http', :host => 'foo', :port => 123 }).dead!.dead!
|
112
|
+
c2 = Connection.new(:host => { :protocol => 'http', :host => 'bar', :port => 123 }).dead!
|
71
113
|
|
72
114
|
@collection = Collection.new :connections => [ c1, c2 ]
|
73
115
|
|
@@ -95,6 +95,15 @@ class Elasticsearch::Transport::Transport::Connections::ConnectionTest < Test::U
|
|
95
95
|
assert ! c.dead?, c.inspect
|
96
96
|
end
|
97
97
|
|
98
|
+
should "implement the equality operator" do
|
99
|
+
c1 = Connection.new(:host => { :protocol => 'http', :host => 'foo', :port => 123 })
|
100
|
+
c2 = Connection.new(:host => { :protocol => 'http', :host => 'foo', :port => 123 })
|
101
|
+
c3 = Connection.new(:host => { :protocol => 'http', :host => 'foo', :port => 456 })
|
102
|
+
|
103
|
+
assert c1 == c2, "Connection #{c1} should be equal to #{c2}"
|
104
|
+
assert c2 != c3, "Connection #{c2} should NOT be equal to #{c3}"
|
105
|
+
end
|
106
|
+
|
98
107
|
end
|
99
108
|
|
100
109
|
end
|
@@ -8,7 +8,9 @@ class Elasticsearch::Transport::Transport::BaseTest < Test::Unit::TestCase
|
|
8
8
|
|
9
9
|
class DummyTransport
|
10
10
|
include Elasticsearch::Transport::Transport::Base
|
11
|
-
def
|
11
|
+
def __build_connection(host, options={}, block=nil)
|
12
|
+
Elasticsearch::Transport::Transport::Connections::Connection.new :host => host, :connection => Object.new
|
13
|
+
end
|
12
14
|
end
|
13
15
|
|
14
16
|
class DummyTransportPerformer < DummyTransport
|
@@ -24,9 +26,9 @@ class Elasticsearch::Transport::Transport::BaseTest < Test::Unit::TestCase
|
|
24
26
|
end
|
25
27
|
|
26
28
|
context "Transport::Base" do
|
27
|
-
should "raise exception when it doesn't implement
|
29
|
+
should "raise exception when it doesn't implement __build_connection" do
|
28
30
|
assert_raise NoMethodError do
|
29
|
-
EmptyTransport.new.
|
31
|
+
EmptyTransport.new.__build_connection({ :host => 'foo'}, {})
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
@@ -488,6 +490,20 @@ class Elasticsearch::Transport::Transport::BaseTest < Test::Unit::TestCase
|
|
488
490
|
@transport.reload_connections!
|
489
491
|
end
|
490
492
|
end
|
493
|
+
|
494
|
+
should "keep existing connections" do
|
495
|
+
@transport.__rebuild_connections :hosts => [ { :host => 'node1', :port => 1 } ], :options => { :http => {} }
|
496
|
+
assert_equal 1, @transport.connections.size
|
497
|
+
|
498
|
+
old_connection_id = @transport.connections.first.object_id
|
499
|
+
|
500
|
+
@transport.__rebuild_connections :hosts => [ { :host => 'node1', :port => 1 },
|
501
|
+
{ :host => 'node2', :port => 2 } ],
|
502
|
+
:options => { :http => {} }
|
503
|
+
|
504
|
+
assert_equal 2, @transport.connections.size
|
505
|
+
assert_equal old_connection_id, @transport.connections.first.object_id
|
506
|
+
end
|
491
507
|
end
|
492
508
|
|
493
509
|
context "rebuilding connections" do
|
@@ -497,13 +513,16 @@ class Elasticsearch::Transport::Transport::BaseTest < Test::Unit::TestCase
|
|
497
513
|
|
498
514
|
should "close connections" do
|
499
515
|
@transport.expects(:__close_connections)
|
500
|
-
@transport.__rebuild_connections :hosts => ['foo']
|
516
|
+
@transport.__rebuild_connections :hosts => [ { :scheme => 'http', :host => 'foo', :port => 1 } ], :options => { :http => {} }
|
501
517
|
end
|
502
518
|
|
503
519
|
should "should replace the connections" do
|
504
|
-
assert_equal
|
505
|
-
|
506
|
-
|
520
|
+
assert_equal 0, @transport.connections.size
|
521
|
+
|
522
|
+
@transport.__rebuild_connections :hosts => [{ :scheme => 'http', :host => 'foo', :port => 1 }],
|
523
|
+
:options => { :http => {} }
|
524
|
+
|
525
|
+
assert_equal 1, @transport.connections.size
|
507
526
|
end
|
508
527
|
end
|
509
528
|
|