elasticsearch-transport 1.0.16 → 1.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|