rubberband-pure 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +12 -0
- data/.gitignore +22 -0
- data/.rspec +2 -0
- data/CONTRIBUTORS +13 -0
- data/Gemfile +3 -0
- data/LICENSE +202 -0
- data/README.rdoc +44 -0
- data/Rakefile +13 -0
- data/TODO +9 -0
- data/lib/elasticsearch.rb +14 -0
- data/lib/elasticsearch/client.rb +20 -0
- data/lib/elasticsearch/client/abstract_client.rb +55 -0
- data/lib/elasticsearch/client/admin_cluster.rb +56 -0
- data/lib/elasticsearch/client/admin_index.rb +149 -0
- data/lib/elasticsearch/client/auto_discovering_client.rb +21 -0
- data/lib/elasticsearch/client/default_scope.rb +36 -0
- data/lib/elasticsearch/client/hits.rb +82 -0
- data/lib/elasticsearch/client/index.rb +143 -0
- data/lib/elasticsearch/client/retrying_client.rb +81 -0
- data/lib/elasticsearch/encoding.rb +7 -0
- data/lib/elasticsearch/encoding/base.rb +17 -0
- data/lib/elasticsearch/encoding/json.rb +19 -0
- data/lib/elasticsearch/transport.rb +15 -0
- data/lib/elasticsearch/transport/base.rb +41 -0
- data/lib/elasticsearch/transport/base_protocol.rb +298 -0
- data/lib/elasticsearch/transport/http.rb +66 -0
- data/lib/elasticsearch/transport/memcached.rb +72 -0
- data/lib/elasticsearch/transport/thrift.rb +111 -0
- data/lib/elasticsearch/transport/thrift/elasticsearch_constants.rb +12 -0
- data/lib/elasticsearch/transport/thrift/elasticsearch_types.rb +124 -0
- data/lib/elasticsearch/transport/thrift/rest.rb +83 -0
- data/lib/elasticsearch/version.rb +3 -0
- data/lib/rubberband.rb +1 -0
- data/rubberband-pure.gemspec +37 -0
- data/spec/admin_spec.rb +43 -0
- data/spec/bulk_spec.rb +57 -0
- data/spec/connect_spec.rb +61 -0
- data/spec/hits_spec.rb +67 -0
- data/spec/http_spec.rb +15 -0
- data/spec/index_spec.rb +84 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/type_spec.rb +47 -0
- data/vendor/elasticsearch/elasticsearch.thrift +81 -0
- metadata +183 -0
@@ -0,0 +1,149 @@
|
|
1
|
+
module ElasticSearch
|
2
|
+
module Api
|
3
|
+
module Admin
|
4
|
+
module Index
|
5
|
+
PSEUDO_INDICES = [:all]
|
6
|
+
|
7
|
+
def index_status(*args)
|
8
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
9
|
+
indices = args.empty? ? [(default_index || :all)] : args.flatten
|
10
|
+
indices.collect! { |i| PSEUDO_INDICES.include?(i) ? "_#{i}" : i }
|
11
|
+
execute(:index_status, indices, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def index_mapping(*args)
|
15
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
16
|
+
indices = args.empty? ? [(default_index || :all)] : args.flatten
|
17
|
+
indices.collect! { |i| PSEUDO_INDICES.include?(i) ? "_#{i}" : i }
|
18
|
+
execute(:index_mapping, indices, options)
|
19
|
+
end
|
20
|
+
|
21
|
+
# options: number_of_shards, number_of_replicas
|
22
|
+
def create_index(index, create_options={}, options={})
|
23
|
+
unless create_options[:index]
|
24
|
+
create_options = { :index => create_options }
|
25
|
+
end
|
26
|
+
execute(:create_index, index, create_options, options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def delete_index(index, options={})
|
30
|
+
execute(:delete_index, index, options)
|
31
|
+
end
|
32
|
+
|
33
|
+
# :add => { "index" => "alias" }
|
34
|
+
# :add => [{"index" => "alias"}, {"index2" => "alias2"}]
|
35
|
+
# :add => { "index" => "alias", "index2" => "alias2" }
|
36
|
+
# :remove => { "index" => "alias" }
|
37
|
+
# :remove => [{"index" => "alias", {"index2" => "alias2"}]
|
38
|
+
# :remove => { "index" => "alias", "index2" => "alias2" }
|
39
|
+
# :actions => [{:add => {:index => "index", :alias => "alias"}}]
|
40
|
+
def alias_index(operations, options={})
|
41
|
+
if operations[:actions]
|
42
|
+
alias_ops = operations
|
43
|
+
else
|
44
|
+
alias_ops = { :actions => [] }
|
45
|
+
[:add, :remove].each do |op|
|
46
|
+
next unless operations.has_key?(op)
|
47
|
+
op_actions = operations[op].is_a?(Array) ? operations[op] : [operations[op]]
|
48
|
+
op_actions.each do |action_hash|
|
49
|
+
action_hash.each do |index, index_alias|
|
50
|
+
alias_ops[:actions] << { op => { :index => index, :alias => index_alias }}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
execute(:alias_index, alias_ops, options)
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_aliases(index=default_index, options={})
|
59
|
+
index, type, options = extract_scope(options)
|
60
|
+
execute(:get_aliases, index, options)
|
61
|
+
end
|
62
|
+
|
63
|
+
# options: ignore_conflicts
|
64
|
+
def update_mapping(mapping, options={})
|
65
|
+
index, type, options = extract_required_scope(options)
|
66
|
+
|
67
|
+
options = options.dup
|
68
|
+
indices = Array(index)
|
69
|
+
unless mapping[type]
|
70
|
+
mapping = { type => mapping }
|
71
|
+
end
|
72
|
+
|
73
|
+
indices.collect! { |i| PSEUDO_INDICES.include?(i) ? "_#{i}" : i }
|
74
|
+
execute(:update_mapping, indices, type, mapping, options)
|
75
|
+
end
|
76
|
+
|
77
|
+
def delete_mapping(options={})
|
78
|
+
index, type, options = extract_required_scope(options)
|
79
|
+
execute(:delete_mapping, index, type, options)
|
80
|
+
end
|
81
|
+
|
82
|
+
def update_settings(settings, options={})
|
83
|
+
index, type, options = extract_scope(options)
|
84
|
+
execute(:update_settings, index, settings, options)
|
85
|
+
end
|
86
|
+
|
87
|
+
def get_settings(index=default_index, options={})
|
88
|
+
execute(:get_settings, index, options)
|
89
|
+
end
|
90
|
+
|
91
|
+
# list of indices, or :all
|
92
|
+
# options: refresh
|
93
|
+
# default: default_index if defined, otherwise :all
|
94
|
+
def flush(*args)
|
95
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
96
|
+
indices = args.empty? ? [(default_index || :all)] : args.flatten
|
97
|
+
indices.collect! { |i| PSEUDO_INDICES.include?(i) ? "_#{i}" : i }
|
98
|
+
execute(:flush, indices, options)
|
99
|
+
end
|
100
|
+
|
101
|
+
# list of indices, or :all
|
102
|
+
# no options
|
103
|
+
# default: default_index if defined, otherwise all
|
104
|
+
def refresh(*args)
|
105
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
106
|
+
indices = args.empty? ? [(default_index || :all)] : args.flatten
|
107
|
+
indices.collect! { |i| PSEUDO_INDICES.include?(i) ? "_#{i}" : i }
|
108
|
+
execute(:refresh, indices, options)
|
109
|
+
end
|
110
|
+
|
111
|
+
# list of indices, or :all
|
112
|
+
# no options
|
113
|
+
# default: default_index if defined, otherwise all
|
114
|
+
def snapshot(*args)
|
115
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
116
|
+
indices = args.empty? ? [(default_index || :all)] : args.flatten
|
117
|
+
indices.collect! { |i| PSEUDO_INDICES.include?(i) ? "_#{i}" : i }
|
118
|
+
execute(:snapshot, indices, options)
|
119
|
+
end
|
120
|
+
|
121
|
+
# list of indices, or :all
|
122
|
+
# options: max_num_segments, only_expunge_deletes, refresh, flush
|
123
|
+
# default: default_index if defined, otherwise all
|
124
|
+
def optimize(*args)
|
125
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
126
|
+
indices = args.empty? ? [(default_index || :all)] : args.flatten
|
127
|
+
indices.collect! { |i| PSEUDO_INDICES.include?(i) ? "_#{i}" : i }
|
128
|
+
execute(:optimize, indices, options)
|
129
|
+
end
|
130
|
+
|
131
|
+
def create_river(type, create_options, options={})
|
132
|
+
execute(:create_river, type, create_options, options)
|
133
|
+
end
|
134
|
+
|
135
|
+
def get_river(type, options={})
|
136
|
+
execute(:get_river, type, options)
|
137
|
+
end
|
138
|
+
|
139
|
+
def river_status(type, options={})
|
140
|
+
execute(:river_status, type, options)
|
141
|
+
end
|
142
|
+
|
143
|
+
def delete_river(type=nil, options={})
|
144
|
+
execute(:delete_river, type, options)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ElasticSearch
|
2
|
+
module AutoDiscoveringClient
|
3
|
+
|
4
|
+
AUTO_DISCOVERING_DEFAULTS = {
|
5
|
+
:auto_discovery => true
|
6
|
+
}.freeze
|
7
|
+
|
8
|
+
def initialize(servers, options={})
|
9
|
+
super
|
10
|
+
@options = AUTO_DISCOVERING_DEFAULTS.merge(@options)
|
11
|
+
if @options[:auto_discovery]
|
12
|
+
auto_discover_nodes!
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
#TODO how to autodiscover on reconnect? don't want to overwrite methods of RetryingClient
|
17
|
+
def auto_discover_nodes!
|
18
|
+
@server_list = execute(:all_nodes)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module ElasticSearch
|
2
|
+
module Api
|
3
|
+
module DefaultScope
|
4
|
+
def default_index
|
5
|
+
@default_index ||= @options[:index]
|
6
|
+
end
|
7
|
+
|
8
|
+
def default_index=(index)
|
9
|
+
@default_index = index
|
10
|
+
end
|
11
|
+
|
12
|
+
def default_type
|
13
|
+
@default_type ||= @options[:type]
|
14
|
+
end
|
15
|
+
|
16
|
+
def default_type=(type)
|
17
|
+
@default_type = type
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def extract_scope(options)
|
23
|
+
options = options.dup
|
24
|
+
index = options.delete(:index) || default_index
|
25
|
+
type = options.delete(:type) || default_type
|
26
|
+
[index, type, options]
|
27
|
+
end
|
28
|
+
|
29
|
+
def extract_required_scope(options)
|
30
|
+
scope = extract_scope(options)
|
31
|
+
raise "index and type or defaults required" unless scope[0] && scope[1]
|
32
|
+
scope
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module ElasticSearch
|
4
|
+
module Api
|
5
|
+
class Hit < OpenStruct
|
6
|
+
undef_method :id if method_defined?(:id)
|
7
|
+
|
8
|
+
def initialize(hit)
|
9
|
+
hit = hit.dup
|
10
|
+
hit.merge!(hit["_source"]) if hit["_source"]
|
11
|
+
hit["id"] ||= hit["_id"]
|
12
|
+
super(hit)
|
13
|
+
end
|
14
|
+
|
15
|
+
def attributes
|
16
|
+
@table
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module Pagination
|
21
|
+
def current_page
|
22
|
+
(@options[:page].respond_to?(:empty?) ? @options[:page].empty? : !@options[:page]) ? 1 : @options[:page].to_i
|
23
|
+
end
|
24
|
+
|
25
|
+
def next_page
|
26
|
+
current_page >= total_pages ? nil : current_page + 1
|
27
|
+
end
|
28
|
+
|
29
|
+
def previous_page
|
30
|
+
current_page == 1 ? nil : current_page - 1
|
31
|
+
end
|
32
|
+
|
33
|
+
def per_page
|
34
|
+
@options[:per_page] || 10
|
35
|
+
end
|
36
|
+
|
37
|
+
def total_pages
|
38
|
+
(total_entries / per_page.to_f).ceil
|
39
|
+
end
|
40
|
+
alias_method :page_count, :total_pages
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
class Hits
|
45
|
+
include Pagination
|
46
|
+
attr_reader :hits, :total_entries, :_shards, :response, :facets, :scroll_id
|
47
|
+
|
48
|
+
def initialize(response, options={})
|
49
|
+
@response = response
|
50
|
+
@options = options
|
51
|
+
@total_entries = response["hits"]["total"]
|
52
|
+
@_shards = response["_shards"]
|
53
|
+
@facets = response["facets"]
|
54
|
+
@scroll_id = response["_scroll_id"] || response["_scrollId"]
|
55
|
+
populate(@options[:ids_only])
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_a
|
59
|
+
@hits
|
60
|
+
end
|
61
|
+
|
62
|
+
def freeze
|
63
|
+
@hits.freeze
|
64
|
+
super
|
65
|
+
end
|
66
|
+
|
67
|
+
def method_missing(method, *args, &block)
|
68
|
+
@hits.send(method, *args, &block)
|
69
|
+
end
|
70
|
+
|
71
|
+
def respond_to?(method, include_private = false)
|
72
|
+
super || @hits.respond_to?(method, include_private)
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def populate(ids_only=false)
|
78
|
+
@hits = @response["hits"]["hits"].collect { |h| ids_only ? h["_id"] : Hit.new(h) }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'client/hits'
|
2
|
+
|
3
|
+
module ElasticSearch
|
4
|
+
module Api
|
5
|
+
module Index
|
6
|
+
def index(document, options={})
|
7
|
+
index, type, options = extract_required_scope(options)
|
8
|
+
# type
|
9
|
+
# index
|
10
|
+
# id (optional)
|
11
|
+
# op_type (optional)
|
12
|
+
# timeout (optional)
|
13
|
+
# document (optional)
|
14
|
+
|
15
|
+
id = options.delete(:id)
|
16
|
+
if @batch
|
17
|
+
#TODO add routing, parent
|
18
|
+
@batch << { :index => { :_index => index, :_type => type, :_id => id }.merge(options)}
|
19
|
+
@batch << document
|
20
|
+
else
|
21
|
+
result = execute(:index, index, type, id, document, options)
|
22
|
+
if result["ok"]
|
23
|
+
result["_id"]
|
24
|
+
else
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def get(id, options={})
|
31
|
+
index, type, options = extract_required_scope(options)
|
32
|
+
# index
|
33
|
+
# type
|
34
|
+
# id
|
35
|
+
# fields
|
36
|
+
|
37
|
+
hit = execute(:get, index, type, id, options)
|
38
|
+
if hit
|
39
|
+
Hit.new(hit)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete(id, options={})
|
44
|
+
index, type, options = extract_required_scope(options)
|
45
|
+
|
46
|
+
if @batch
|
47
|
+
#TODO add routing, parent
|
48
|
+
@batch << { :delete => { :_index => index, :_type => type, :_id => id }}
|
49
|
+
else
|
50
|
+
result = execute(:delete, index, type, id, options)
|
51
|
+
result["ok"]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def delete_by_query(query, options = {})
|
56
|
+
index, type, options = extract_required_scope(options)
|
57
|
+
execute(:delete_by_query, index, type, query, options)
|
58
|
+
end
|
59
|
+
|
60
|
+
#df The default field to use when no field prefix is defined within the query.
|
61
|
+
#analyzer The analyzer name to be used when analyzing the query string.
|
62
|
+
#default_operator The default operator to be used, can be AND or OR. Defaults to OR.
|
63
|
+
#explain For each hit, contain an explanation of how to scoring of the hits was computed.
|
64
|
+
#fields The selective fields of the document to return for each hit (fields must be stored), comma delimited. Defaults to the internal _source field.
|
65
|
+
#field Same as fields above, but each parameter contains a single field name to load. There can be several field parameters.
|
66
|
+
#sort Sorting to perform. Can either be in the form of fieldName, or fieldName:desc (for reverse sorting). The fieldName can either be an actual field within the document, or the special score name to indicate sorting based on scores. There can be several sort parameters (order is important).
|
67
|
+
#from The starting from index of the hits to return. Defaults to 0.
|
68
|
+
#size The number of hits to return. Defaults to 10.
|
69
|
+
#search_type The type of the search operation to perform. Can be dfs_query_then_fetch, dfs_query_and_fetch, query_then_fetch, query_and_fetch. Defaults to query_then_fetch.
|
70
|
+
#scroll Get a scroll id to continue paging through the search results. Value is the time to keep a scroll request around, e.g. 5m
|
71
|
+
#ids_only Return ids instead of hits
|
72
|
+
def search(query, options={})
|
73
|
+
index, type, options = extract_scope(options)
|
74
|
+
|
75
|
+
options[:size] ||= (options[:per_page] || options[:limit] || 10)
|
76
|
+
options[:from] ||= options[:size] * (options[:page].to_i-1) if options[:page] && options[:page].to_i > 1
|
77
|
+
options[:from] ||= options[:offset] if options[:offset]
|
78
|
+
|
79
|
+
options[:fields] = "_id" if options[:ids_only]
|
80
|
+
|
81
|
+
# options that elasticsearch doesn't recognize: page, per_page, ids_only, limit, offset
|
82
|
+
search_options = options.reject { |k, v| [:page, :per_page, :ids_only, :limit, :offset].include?(k) }
|
83
|
+
|
84
|
+
response = execute(:search, index, type, query, search_options)
|
85
|
+
|
86
|
+
Hits.new(response, {:per_page => options[:per_page], :page => options[:page], :ids_only => options[:ids_only]}) #ids_only returns array of ids instead of hits
|
87
|
+
end
|
88
|
+
|
89
|
+
#ids_only Return ids instead of hits
|
90
|
+
#pass a block to execute the block for each batch of hits
|
91
|
+
def scroll(scroll_id, options={}, &block)
|
92
|
+
begin
|
93
|
+
search_options = options.reject { |k, v| [:page, :per_page, :ids_only, :limit, :offset].include?(k) }
|
94
|
+
response = execute(:scroll, scroll_id, options)
|
95
|
+
hits = Hits.new(response, { :ids_only => options[:ids_only] })
|
96
|
+
if block_given? && !hits.empty?
|
97
|
+
yield hits
|
98
|
+
scroll_id = hits.scroll_id
|
99
|
+
end
|
100
|
+
end until !block_given? || hits.empty?
|
101
|
+
hits
|
102
|
+
end
|
103
|
+
|
104
|
+
#df The default field to use when no field prefix is defined within the query.
|
105
|
+
#analyzer The analyzer name to be used when analyzing the query string.
|
106
|
+
#default_operator The default operator to be used, can be AND or OR. Defaults to OR.
|
107
|
+
def count(query, options={})
|
108
|
+
index, type, options = extract_scope(options)
|
109
|
+
|
110
|
+
response = execute(:count, index, type, query, options)
|
111
|
+
response["count"].to_i #TODO check if count is nil
|
112
|
+
end
|
113
|
+
|
114
|
+
# Starts a bulk operation batch and yields self. Index and delete requests will be
|
115
|
+
# queued until the block closes, then sent as a single _bulk call.
|
116
|
+
def bulk(options={})
|
117
|
+
# allow nested bulk calls
|
118
|
+
if @batch
|
119
|
+
yield(self)
|
120
|
+
else
|
121
|
+
begin
|
122
|
+
@batch = []
|
123
|
+
yield(self)
|
124
|
+
response = execute(:bulk, @batch, options)
|
125
|
+
ensure
|
126
|
+
@batch = nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# minor multi get support
|
132
|
+
def multi_get(ids, options={})
|
133
|
+
index, type, options = extract_required_scope(options)
|
134
|
+
results = execute(:multi_get, index, type, ids, options)
|
135
|
+
if(results)
|
136
|
+
hits = []
|
137
|
+
results.each { |hit| hits << Hit.new(hit) }
|
138
|
+
hits
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# mostly ripped from thrift_client
|
2
|
+
|
3
|
+
module ElasticSearch
|
4
|
+
class NoServersAvailable < StandardError; end
|
5
|
+
|
6
|
+
module RetryingClient
|
7
|
+
|
8
|
+
RETRYING_DEFAULTS = {
|
9
|
+
:randomize_server_list => true,
|
10
|
+
:retries => nil,
|
11
|
+
:server_retry_period => 1,
|
12
|
+
:server_max_requests => nil,
|
13
|
+
:retry_overrides => {}
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
# use cluster status to get server list
|
17
|
+
def initialize(servers, options={})
|
18
|
+
super
|
19
|
+
@options = RETRYING_DEFAULTS.merge(@options)
|
20
|
+
@retries = options[:retries] || @server_list.size
|
21
|
+
@request_count = 0
|
22
|
+
@max_requests = @options[:server_max_requests]
|
23
|
+
@retry_period = @options[:server_retry_period]
|
24
|
+
rebuild_live_server_list!
|
25
|
+
end
|
26
|
+
|
27
|
+
def connect!
|
28
|
+
@current_server = next_server
|
29
|
+
super
|
30
|
+
rescue ElasticSearch::RetryableError
|
31
|
+
retry
|
32
|
+
end
|
33
|
+
|
34
|
+
def disconnect!
|
35
|
+
# Keep live servers in the list if we have a retry period. Otherwise,
|
36
|
+
# always eject, because we will always re-add them.
|
37
|
+
if @retry_period && @current_server
|
38
|
+
@live_server_list.unshift(@current_server)
|
39
|
+
end
|
40
|
+
|
41
|
+
super
|
42
|
+
@request_count = 0
|
43
|
+
end
|
44
|
+
|
45
|
+
#TODO this can spin indefinitely if timeout > retry_period
|
46
|
+
def next_server
|
47
|
+
if @retry_period
|
48
|
+
rebuild_live_server_list! if Time.now > @last_rebuild + @retry_period
|
49
|
+
raise NoServersAvailable, "No live servers in #{@server_list.inspect} since #{@last_rebuild.inspect}." if @live_server_list.empty?
|
50
|
+
elsif @live_server_list.empty?
|
51
|
+
rebuild_live_server_list!
|
52
|
+
end
|
53
|
+
@live_server_list.pop
|
54
|
+
end
|
55
|
+
|
56
|
+
def rebuild_live_server_list!
|
57
|
+
@last_rebuild = Time.now
|
58
|
+
if @options[:randomize_server_list]
|
59
|
+
@live_server_list = @server_list.sort_by { rand }
|
60
|
+
else
|
61
|
+
@live_server_list = @server_list.dup
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def execute(method_name, *args)
|
66
|
+
disconnect_on_max! if @max_requests and @request_count >= @max_requests
|
67
|
+
@request_count += 1
|
68
|
+
begin
|
69
|
+
super
|
70
|
+
rescue ElasticSearch::RetryableError
|
71
|
+
disconnect!
|
72
|
+
retry
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def disconnect_on_max!
|
77
|
+
@live_server_list.push(@current_server)
|
78
|
+
disconnect!
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|