elasticsearch-transport 1.0.0 → 1.0.1
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.
- data/README.md +46 -12
- data/elasticsearch-transport.gemspec +2 -1
- data/lib/elasticsearch/transport/client.rb +36 -3
- data/lib/elasticsearch/transport/version.rb +1 -1
- data/test/integration/client_test.rb +14 -0
- data/test/integration/transport_test.rb +1 -0
- data/test/profile/client_benchmark_test.rb +27 -10
- data/test/unit/client_test.rb +30 -0
- metadata +18 -2
data/README.md
CHANGED
@@ -28,8 +28,9 @@ Features overview:
|
|
28
28
|
* Node reloading (based on cluster state) on errors or on demand
|
29
29
|
|
30
30
|
For optimal performance, you should use a HTTP library which supports persistent ("keep-alive") connections,
|
31
|
-
e.g. [Typhoeus](https://github.com/typhoeus/typhoeus) or [
|
32
|
-
|
31
|
+
e.g. [Typhoeus](https://github.com/typhoeus/typhoeus) or [Patron](https://github.com/toland/patron).
|
32
|
+
Just `require 'typhoeus'` or `require 'patron'` in your code, and it will be used.
|
33
|
+
For detailed information, see example configurations [below](#transport-implementations).
|
33
34
|
|
34
35
|
## Installation
|
35
36
|
|
@@ -198,29 +199,61 @@ Only when these would be unavailable, the strategy will use the other nodes:
|
|
198
199
|
### Transport Implementations
|
199
200
|
|
200
201
|
By default, the client will use the [_Faraday_](https://rubygems.org/gems/faraday) HTTP library
|
201
|
-
as a transport implementation.
|
202
|
-
|
203
|
-
|
202
|
+
as a transport implementation.
|
203
|
+
|
204
|
+
It will auto-detect and use an _adapter_ for _Faraday_ based on gems loaded in your code,
|
205
|
+
preferring HTTP clients with support for persistent connections.
|
206
|
+
|
207
|
+
To use the [_Patron_](https://github.com/toland/patron) HTTP, for example, just require it:
|
208
|
+
|
209
|
+
require 'patron'
|
210
|
+
|
211
|
+
Then, create a new client, and the _Patron_ gem will be used as the "driver":
|
212
|
+
|
213
|
+
client = Elasticsearch::Client.new
|
214
|
+
|
215
|
+
client.transport.connections.first.connection.builder.handlers
|
216
|
+
# => [Faraday::Adapter::Patron]
|
217
|
+
|
218
|
+
10.times do
|
219
|
+
client.nodes.stats(metric: 'http')['nodes'].values.each do |n|
|
220
|
+
puts "#{n['name']} : #{n['http']['total_opened']}"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
# => Stiletoo : 24
|
225
|
+
# => Stiletoo : 24
|
226
|
+
# => Stiletoo : 24
|
227
|
+
# => ...
|
228
|
+
|
229
|
+
To use a specific adapter for _Faraday_, pass it as the `adapter` argument:
|
230
|
+
|
231
|
+
client = Elasticsearch::Client.new adapter: :net_http_persistent
|
232
|
+
|
233
|
+
client.transport.connections.first.connection.builder.handlers
|
234
|
+
# => [Faraday::Adapter::NetHttpPersistent]
|
235
|
+
|
236
|
+
To configure the _Faraday_ instance, pass a configuration block to the transport constructor:
|
204
237
|
|
205
238
|
require 'typhoeus'
|
206
239
|
require 'typhoeus/adapters/faraday'
|
207
240
|
|
208
|
-
|
241
|
+
transport_configuration = lambda do |f|
|
209
242
|
f.response :logger
|
210
243
|
f.adapter :typhoeus
|
211
244
|
end
|
212
245
|
|
213
246
|
transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new \
|
214
247
|
hosts: [ { host: 'localhost', port: '9200' } ],
|
215
|
-
&
|
248
|
+
&transport_configuration
|
216
249
|
|
217
250
|
# Pass the transport to the client
|
218
251
|
#
|
219
252
|
client = Elasticsearch::Client.new transport: transport
|
220
253
|
|
221
254
|
To pass options to the
|
222
|
-
[`Faraday::Connection`](https://github.com/lostisland/faraday/blob/master/lib/faraday/connection.rb)
|
223
|
-
use the `transport_options` key:
|
255
|
+
[`Faraday::Connection`](https://github.com/lostisland/faraday/blob/master/lib/faraday/connection.rb)
|
256
|
+
constructor, use the `transport_options` key:
|
224
257
|
|
225
258
|
client = Elasticsearch::Client.new transport_options: {
|
226
259
|
request: { open_timeout: 1 },
|
@@ -233,9 +266,11 @@ You can also use a bundled [_Curb_](https://rubygems.org/gems/curb) based transp
|
|
233
266
|
require 'curb'
|
234
267
|
require 'elasticsearch/transport/transport/http/curb'
|
235
268
|
|
236
|
-
# Use Curb as the HTTP client
|
237
269
|
client = Elasticsearch::Client.new transport_class: Elasticsearch::Transport::Transport::HTTP::Curb
|
238
270
|
|
271
|
+
client.transport.connections.first.connection
|
272
|
+
# => #<Curl::Easy http://localhost:9200/>
|
273
|
+
|
239
274
|
It's possible to customize the _Curb_ instance by passing a block to the constructor as well
|
240
275
|
(in this case, as an inline block):
|
241
276
|
|
@@ -273,8 +308,7 @@ Instead of passing the transport to the constructor, you can inject it at run ti
|
|
273
308
|
|
274
309
|
You can write your own transport implementation easily, by including the
|
275
310
|
{Elasticsearch::Transport::Transport::Base} module, implementing the required contract,
|
276
|
-
and passing it to the client as the `transport_class` parameter
|
277
|
-
passed to client will be passed as the `:options` parameter to the transport constructor.
|
311
|
+
and passing it to the client as the `transport_class` parameter -- or injecting it directly.
|
278
312
|
|
279
313
|
### Serializer Implementations
|
280
314
|
|
@@ -43,7 +43,8 @@ Gem::Specification.new do |s|
|
|
43
43
|
s.add_development_dependency "ci_reporter"
|
44
44
|
|
45
45
|
# Gems for testing integrations
|
46
|
-
s.add_development_dependency "curb"
|
46
|
+
s.add_development_dependency "curb" unless defined? JRUBY_VERSION
|
47
|
+
s.add_development_dependency "patron" unless defined? JRUBY_VERSION
|
47
48
|
s.add_development_dependency "typhoeus", '~> 0.6'
|
48
49
|
|
49
50
|
# Prevent unit test failures on Ruby 1.8
|
@@ -57,6 +57,8 @@ module Elasticsearch
|
|
57
57
|
#
|
58
58
|
# @option arguments [Boolean] :reload_on_failure Reload connections after failure (false by default)
|
59
59
|
#
|
60
|
+
# @option arguments [Symbol] :adapter A specific adapter for Faraday (e.g. `:patron`)
|
61
|
+
#
|
60
62
|
# @option arguments [Hash] :transport_options Options to be passed to the `Faraday::Connection` constructor
|
61
63
|
#
|
62
64
|
# @option arguments [Constant] :transport_class A specific transport class to use, will be initialized by
|
@@ -71,7 +73,6 @@ module Elasticsearch
|
|
71
73
|
# {Elasticsearch::Transport::Transport::Connections::Selector::Base}.
|
72
74
|
#
|
73
75
|
def initialize(arguments={})
|
74
|
-
transport_class = arguments[:transport_class] || DEFAULT_TRANSPORT_CLASS
|
75
76
|
hosts = arguments[:hosts] || arguments[:host] || arguments[:url]
|
76
77
|
|
77
78
|
arguments[:logger] ||= arguments[:log] ? DEFAULT_LOGGER.call() : nil
|
@@ -82,8 +83,17 @@ module Elasticsearch
|
|
82
83
|
arguments[:randomize_hosts] ||= false
|
83
84
|
arguments[:transport_options] ||= {}
|
84
85
|
|
85
|
-
|
86
|
-
|
86
|
+
transport_class = arguments[:transport_class] || DEFAULT_TRANSPORT_CLASS
|
87
|
+
|
88
|
+
@transport = arguments[:transport] || begin
|
89
|
+
if transport_class == Transport::HTTP::Faraday
|
90
|
+
transport_class.new(:hosts => __extract_hosts(hosts, arguments), :options => arguments) do |faraday|
|
91
|
+
faraday.adapter(arguments[:adapter] || __auto_detect_adapter)
|
92
|
+
end
|
93
|
+
else
|
94
|
+
transport_class.new(:hosts => __extract_hosts(hosts, arguments), :options => arguments)
|
95
|
+
end
|
96
|
+
end
|
87
97
|
end
|
88
98
|
|
89
99
|
# Performs a request through delegation to {#transport}.
|
@@ -129,6 +139,29 @@ module Elasticsearch
|
|
129
139
|
hosts.shuffle! if options[:randomize_hosts]
|
130
140
|
hosts
|
131
141
|
end
|
142
|
+
|
143
|
+
# Auto-detect the best adapter (HTTP "driver") available, based on libraries
|
144
|
+
# loaded by the user, preferring those with persistent connections
|
145
|
+
# ("keep-alive") by default
|
146
|
+
#
|
147
|
+
# @return [Symbol]
|
148
|
+
#
|
149
|
+
# @api private
|
150
|
+
#
|
151
|
+
def __auto_detect_adapter
|
152
|
+
case
|
153
|
+
when defined?(::Patron)
|
154
|
+
:patron
|
155
|
+
when defined?(::Typhoeus)
|
156
|
+
:typhoeus
|
157
|
+
when defined?(::HTTPClient)
|
158
|
+
:httpclient
|
159
|
+
when defined?(::Net::HTTP::Persistent)
|
160
|
+
:net_http_persistent
|
161
|
+
else
|
162
|
+
::Faraday.default_adapter
|
163
|
+
end
|
164
|
+
end
|
132
165
|
end
|
133
166
|
end
|
134
167
|
end
|
@@ -6,6 +6,11 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
|
|
6
6
|
end
|
7
7
|
|
8
8
|
context "Elasticsearch client" do
|
9
|
+
teardown do
|
10
|
+
begin; Object.send(:remove_const, :Typhoeus); rescue NameError; end
|
11
|
+
begin; Object.send(:remove_const, :Patron); rescue NameError; end
|
12
|
+
end
|
13
|
+
|
9
14
|
setup do
|
10
15
|
@port = (ENV['TEST_CLUSTER_PORT'] || 9250).to_i
|
11
16
|
system "curl -X DELETE http://localhost:#{@port}/_all > /dev/null 2>&1"
|
@@ -116,5 +121,14 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
|
|
116
121
|
end
|
117
122
|
end
|
118
123
|
|
124
|
+
context "with Faraday adapters" do
|
125
|
+
should "automatically use the Patron client when loaded" do
|
126
|
+
require 'patron'
|
127
|
+
client = Elasticsearch::Transport::Client.new host: "localhost:#{@port}"
|
128
|
+
|
129
|
+
response = @client.perform_request 'GET', '_cluster/health'
|
130
|
+
assert_equal 200, response.status
|
131
|
+
end unless JRUBY
|
132
|
+
end
|
119
133
|
end
|
120
134
|
end
|
@@ -8,6 +8,7 @@ class Elasticsearch::Transport::ClientIntegrationTest < Elasticsearch::Test::Int
|
|
8
8
|
context "Transport" do
|
9
9
|
setup do
|
10
10
|
@port = (ENV['TEST_CLUSTER_PORT'] || 9250).to_i
|
11
|
+
begin; Object.send(:remove_const, :Patron); rescue NameError; end
|
11
12
|
end
|
12
13
|
|
13
14
|
should "allow to customize the Faraday adapter" do
|
@@ -8,7 +8,7 @@ class Elasticsearch::Transport::ClientProfilingTest < Elasticsearch::Test::Profi
|
|
8
8
|
context "Elasticsearch client benchmark" do
|
9
9
|
setup do
|
10
10
|
@port = (ENV['TEST_CLUSTER_PORT'] || 9250).to_i
|
11
|
-
client = Elasticsearch::Client.new host: "localhost:#{@port}"
|
11
|
+
client = Elasticsearch::Client.new host: "localhost:#{@port}", adapter: ::Faraday.default_adapter
|
12
12
|
client.perform_request 'DELETE', '/ruby_test_benchmark/' rescue nil
|
13
13
|
client.perform_request 'POST', '/ruby_test_benchmark/', {index: {number_of_shards: 1, number_of_replicas: 0}}
|
14
14
|
100.times do client.perform_request 'POST', '/ruby_test_benchmark_search/test/', {}, {foo: 'bar'}; end
|
@@ -20,9 +20,9 @@ class Elasticsearch::Transport::ClientProfilingTest < Elasticsearch::Test::Profi
|
|
20
20
|
client.perform_request 'DELETE', '/ruby_test_benchmark_search/'
|
21
21
|
end
|
22
22
|
|
23
|
-
context "with a single-node cluster" do
|
23
|
+
context "with a single-node cluster and the default adapter" do
|
24
24
|
setup do
|
25
|
-
@client = Elasticsearch::Client.new hosts: "localhost:#{@port}"
|
25
|
+
@client = Elasticsearch::Client.new hosts: "localhost:#{@port}", adapter: ::Faraday.default_adapter
|
26
26
|
end
|
27
27
|
|
28
28
|
measure "get the cluster info", count: 1_000 do
|
@@ -38,9 +38,9 @@ class Elasticsearch::Transport::ClientProfilingTest < Elasticsearch::Test::Profi
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
context "with a two-node cluster" do
|
41
|
+
context "with a two-node cluster and the default adapter" do
|
42
42
|
setup do
|
43
|
-
@client = Elasticsearch::Client.new hosts: ["localhost:#{@port}", "localhost:#{@port+1}"]
|
43
|
+
@client = Elasticsearch::Client.new hosts: ["localhost:#{@port}", "localhost:#{@port+1}"], adapter: ::Faraday.default_adapter
|
44
44
|
end
|
45
45
|
|
46
46
|
measure "get the cluster info", count: 1_000 do
|
@@ -78,9 +78,12 @@ class Elasticsearch::Transport::ClientProfilingTest < Elasticsearch::Test::Profi
|
|
78
78
|
end
|
79
79
|
|
80
80
|
context "with a single-node cluster and the Typhoeus client" do
|
81
|
+
require 'typhoeus'
|
82
|
+
require 'typhoeus/adapters/faraday'
|
83
|
+
|
81
84
|
# Fix for incompatibility of the Typhoeus adapter
|
82
85
|
# Related commit: elasticsearch/elasticsearch-ruby@adc4810227fad03ae5cabfbb2a0905fb75bfb331
|
83
|
-
# Related: lostisland/faraday/pull/323, lostisland/faraday/pull/335
|
86
|
+
# Related: lostisland/faraday/pull/323, lostisland/faraday/issues/333, lostisland/faraday/pull/335
|
84
87
|
#
|
85
88
|
class ::Faraday::Adapter::Typhoeus
|
86
89
|
def configure_ssl(req, env)
|
@@ -89,9 +92,6 @@ class Elasticsearch::Transport::ClientProfilingTest < Elasticsearch::Test::Profi
|
|
89
92
|
end
|
90
93
|
|
91
94
|
setup do
|
92
|
-
require 'typhoeus'
|
93
|
-
require 'typhoeus/adapters/faraday'
|
94
|
-
|
95
95
|
transport = Elasticsearch::Transport::Transport::HTTP::Faraday.new \
|
96
96
|
:hosts => [ { :host => 'localhost', :port => @port } ] do |f|
|
97
97
|
f.adapter :typhoeus
|
@@ -113,6 +113,23 @@ class Elasticsearch::Transport::ClientProfilingTest < Elasticsearch::Test::Profi
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
-
|
116
|
+
context "with a single-node cluster and the Patron adapter" do
|
117
|
+
setup do
|
118
|
+
require 'patron'
|
119
|
+
@client = Elasticsearch::Client.new host: "localhost:#{@port}", adapter: :patron
|
120
|
+
end
|
121
|
+
|
122
|
+
measure "get the cluster info", count: 1_000 do
|
123
|
+
@client.perform_request 'GET', ''
|
124
|
+
end
|
117
125
|
|
126
|
+
measure "index a document" do
|
127
|
+
@client.perform_request 'POST', '/ruby_test_benchmark/test/', {}, {foo: 'bar'}
|
128
|
+
end
|
129
|
+
|
130
|
+
measure "search" do
|
131
|
+
@client.perform_request 'POST', '/ruby_test_benchmark_search/test/_search', {}, {query: {match: {foo: 'bar'}}}
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
118
135
|
end
|
data/test/unit/client_test.rb
CHANGED
@@ -169,5 +169,35 @@ class Elasticsearch::Transport::ClientTest < Test::Unit::TestCase
|
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
172
|
+
context "detecting adapter for Faraday" do
|
173
|
+
setup do
|
174
|
+
Elasticsearch::Transport::Client::DEFAULT_TRANSPORT_CLASS.any_instance.unstub(:__build_connections)
|
175
|
+
begin; Object.send(:remove_const, :Typhoeus); rescue NameError; end
|
176
|
+
begin; Object.send(:remove_const, :Patron); rescue NameError; end
|
177
|
+
end
|
178
|
+
|
179
|
+
should "use the default adapter" do
|
180
|
+
c = Elasticsearch::Transport::Client.new
|
181
|
+
handlers = c.transport.connections.all.first.connection.builder.handlers
|
182
|
+
|
183
|
+
assert_includes handlers, Faraday::Adapter::NetHttp
|
184
|
+
end
|
185
|
+
|
186
|
+
should "use the adapter from arguments" do
|
187
|
+
c = Elasticsearch::Transport::Client.new :adapter => :typhoeus
|
188
|
+
handlers = c.transport.connections.all.first.connection.builder.handlers
|
189
|
+
|
190
|
+
assert_includes handlers, Faraday::Adapter::Typhoeus
|
191
|
+
end
|
192
|
+
|
193
|
+
should "detect the adapter" do
|
194
|
+
require 'patron'
|
195
|
+
c = Elasticsearch::Transport::Client.new
|
196
|
+
handlers = c.transport.connections.all.first.connection.builder.handlers
|
197
|
+
|
198
|
+
assert_includes handlers, Faraday::Adapter::Patron
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
172
202
|
end
|
173
203
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elasticsearch-transport
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-03-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: multi_json
|
@@ -219,6 +219,22 @@ dependencies:
|
|
219
219
|
- - ! '>='
|
220
220
|
- !ruby/object:Gem::Version
|
221
221
|
version: '0'
|
222
|
+
- !ruby/object:Gem::Dependency
|
223
|
+
name: patron
|
224
|
+
requirement: !ruby/object:Gem::Requirement
|
225
|
+
none: false
|
226
|
+
requirements:
|
227
|
+
- - ! '>='
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0'
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
none: false
|
234
|
+
requirements:
|
235
|
+
- - ! '>='
|
236
|
+
- !ruby/object:Gem::Version
|
237
|
+
version: '0'
|
222
238
|
- !ruby/object:Gem::Dependency
|
223
239
|
name: typhoeus
|
224
240
|
requirement: !ruby/object:Gem::Requirement
|