druid_config 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 34faeb23be9dfd54181862f172bb5db8b794f489
4
- data.tar.gz: 58c09b7c65c33be02e1b2cf0f9ca8eaa3754666f
3
+ metadata.gz: bf454ef0181ed1e25627d5cfc70229feb60acc4b
4
+ data.tar.gz: b71143a30e604c6463738ea4a543a9775e50768d
5
5
  SHA512:
6
- metadata.gz: 64062d2ad8ec0abc2487a003feb746d175aaf6cc8b47b703fbc1544e1a59bd1089209c6d61d164678cbe469884ebefff97f0114cec7884bc63daea73b44df45f
7
- data.tar.gz: 7149d8613c814c63ae21ccae898a0205dcbe479a5b0973f757d462a4d8b4d47a5ebefff5fd1cda6527b73e61222c68ff221dc893523735ae33e579617422b129
6
+ metadata.gz: a3c56389d7dbc9778bb6c29091e8538da10b3dd1856e32d266290cfe3fa94e8d4ecea7b3d77997e793f00818c7a89831d40f38d25901a17d6a052a5dddc32240
7
+ data.tar.gz: 67ef3c716e5561a6043a009298039c01247a060356eba2f5d209a374c88f254c3bbde2ee99f4241d2618b2c8e7980921598878d3af39ae67b63324b0e636cebc
data/README.md CHANGED
@@ -61,7 +61,13 @@ Some methods return an instance of an `Entity` class. These entities provide mul
61
61
 
62
62
  ## Exceptions
63
63
 
64
- Sometimes the Gem can't access to Druid API. In this case, the gem automatically will reset the Zookeeper connection and retry the query. If second query fails too, a `DruidApiError` exception will be raised.
64
+ ### DruidConfig::Exceptions::NotAvailableNodes
65
+
66
+ This exception will be raised when you try to perform a query to a Druid Coordinator or Overlord but there aren't any node of that type available.
67
+
68
+ ### DruidConfig::Exceptions::DruidApiError
69
+
70
+ Sometimes the Gem have available nodes, but it can't access to Druid API. In this case, the gem automatically will reset the Zookeeper connection and retry the query. If second query fails too, a `DruidConfig::Exceptions::DruidApiError` exception will be raised.
65
71
 
66
72
  # Collaborate
67
73
 
@@ -9,23 +9,32 @@ module DruidConfig
9
9
  # Initialize Zookeeper connection
10
10
  #
11
11
  def initialize(zookeeper, opts = {})
12
- @zookeeper = :zk
12
+ # Store it for future resets
13
+ @zookeeper = zookeeper
13
14
  @opts = opts
14
15
  @zk = ZK.new(zookeeper, opts)
15
16
  end
16
17
 
17
18
  #
18
- # Get the URL of a coordinator
19
+ # Get the URL of a coordinator.
20
+ #
21
+ # This funciton can raise a DruidConfig::Exceptions::NotAvailableNodes
22
+ # exception indicating there aren't any node to process this request
19
23
  #
20
24
  def coordinator
21
- zk.coordinator
25
+ return zk.coordinator if zk.coordinator
26
+ fail DruidConfig::Exceptions::NotAvailableNodes, 'coordinator'
22
27
  end
23
28
 
24
29
  #
25
30
  # Get the URI of a overlord
26
31
  #
32
+ # This funciton can raise a DruidConfig::Exceptions::NotAvailableNodes
33
+ # exception indicating there aren't any node to process this request
34
+ #
27
35
  def overlord
28
- zk.overlord
36
+ return zk.overlord if zk.overlord
37
+ fail DruidConfig::Exceptions::NotAvailableNodes, 'overlord'
29
38
  end
30
39
 
31
40
  #
@@ -0,0 +1,23 @@
1
+ module DruidConfig
2
+ #
3
+ # Module of DruidConfgi exceptions
4
+ #
5
+ module Exceptions
6
+ # Get Global standard error
7
+ class StandardError < ::StandardError; end
8
+ #
9
+ # Indicate there aren't any node available in Zookeeper to run the data.
10
+ # It returns the name of the service user is trying to call.
11
+ #
12
+ class NotAvailableNodes < StandardError
13
+ def initialize(service)
14
+ super("There aren't any available #{service} node")
15
+ end
16
+ end
17
+
18
+ #
19
+ # Exception class for an error to connect the API
20
+ #
21
+ class DruidApiError < StandardError; end
22
+ end
23
+ end
@@ -20,12 +20,12 @@ module DruidConfig
20
20
  begin
21
21
  yield
22
22
  rescue HTTParty::RedirectionTooDeep => e
23
- raise(DruidApiError, e) if @retries > 0
23
+ raise(DruidConfig::Exceptions::DruidApiError, e) if @retries > 0
24
24
  @retries += 1
25
25
  reset!
26
26
  retry
27
27
  rescue Errno::ECONNREFUSED => e
28
- raise(DruidApiError, e) if @retries > 0
28
+ raise(DruidConfig::Exceptions::DruidApiError, e) if @retries > 0
29
29
  @retries += 1
30
30
  reset!
31
31
  retry
@@ -4,7 +4,7 @@
4
4
  module DruidConfig
5
5
  module Version
6
6
  # Version of the gem
7
- VERSION = '0.3.0'
7
+ VERSION = '0.4.0'
8
8
 
9
9
  # Base URI foor coordinator queries
10
10
  API_VERSION = 'v1'
@@ -34,6 +34,7 @@ module DruidConfig
34
34
  @registry = Hash.new { |hash, key| hash[key] = [] }
35
35
  @discovery_path = opts[:discovery_path] || '/discovery'
36
36
  @watched_services = {}
37
+ @verify_retry = 0
37
38
  register
38
39
  end
39
40
 
@@ -84,8 +85,7 @@ module DruidConfig
84
85
  def random_node(service)
85
86
  return nil if @registry[service].size == 0
86
87
  # Return a random broker from available brokers
87
- i = Random.rand(@registry[service].size)
88
- @registry[service][i][:uri]
88
+ @registry[service].sample[:uri]
89
89
  end
90
90
 
91
91
  #
@@ -94,7 +94,7 @@ module DruidConfig
94
94
  def register_service(service, brokers)
95
95
  $log.info("druid.zk register", service: service, brokers: brokers) if $log
96
96
  # poor mans load balancing
97
- @registry[service] = brokers.shuffle
97
+ @registry[service] = brokers
98
98
  end
99
99
 
100
100
  #
@@ -146,7 +146,9 @@ module DruidConfig
146
146
  end
147
147
 
148
148
  #
149
- # Verify is a Coordinator is available
149
+ # Verify is a Coordinator is available. To do check, this method perform a
150
+ # GET request to the /status end point. This method will retry to connect
151
+ # three times with a delay of 0.8, 1.6, 2.4 seconds.
150
152
  #
151
153
  # == Parameters:
152
154
  # name::
@@ -162,6 +164,7 @@ module DruidConfig
162
164
  info = @zk.get("#{watch_path(service)}/#{name}")
163
165
  node = JSON.parse(info[0])
164
166
  uri = "http://#{node['address']}:#{node['port']}/"
167
+ # Try to get /status
165
168
  check = RestClient::Request.execute(
166
169
  method: :get, url: "#{uri}status",
167
170
  timeout: 5, open_timeout: 5
@@ -169,43 +172,59 @@ module DruidConfig
169
172
  $log.info("druid.zk verified", uri: uri, sources: check) if $log
170
173
  return uri if check.code == 200
171
174
  rescue
172
- return false
175
+ return false unless @verify_retry < 3
176
+ # Sleep some time and retry
177
+ @verify_retry += 1
178
+ sleep 0.8 * @verify_retry
179
+ retry
180
+ ensure
181
+ # Reset verify retries
182
+ @verify_retry = 0
173
183
  end
174
184
 
175
185
  #
176
- # Watch path of a service
186
+ # Return the path of a service in Zookeeper.
187
+ #
188
+ # == Parameters:
189
+ # service::
190
+ # String with the name of the service
177
191
  #
178
192
  def watch_path(service)
179
193
  "#{@discovery_path}/#{service}"
180
194
  end
181
195
 
182
196
  #
183
- # Check a service
197
+ # Check a given Druid service. Now we only need to track coordinator and
198
+ # overlord services. This method create a watcher to the service to check
199
+ # changes.
200
+ #
201
+ # This method get the available nodes in the Zookeeper path. When return
202
+ # them, it tries to connect to /status end point to check if the node
203
+ # is available. After it, it store in @registry.
204
+ #
205
+ # == Parameters:
206
+ # service::
207
+ # String with the service to check
184
208
  #
185
209
  def check_service(service)
210
+ # Only watch some services
186
211
  return if @watched_services.include?(service) ||
187
212
  !SERVICES.include?(service)
188
-
189
213
  # Start to watch this service
190
214
  watch_service(service)
215
+ # New list of nodes
216
+ new_list = []
191
217
 
192
- known = @registry[service].map { |node| node[:name] }
218
+ # Verify every node
193
219
  live = @zk.children(watch_path(service), watch: true)
194
- new_list = @registry[service].select { |node| live.include?(node[:name]) }
195
- $log.info("druid.zk checking", service: service, known: known, live: live, new_list: new_list) if $log
196
-
197
- # verify the new entries to be living brokers
198
- (live - known).each do |name|
220
+ live.each do |name|
221
+ # Verify a node
199
222
  uri = verify_node(name, service)
223
+ # If != false store the URI
200
224
  new_list.push(name: name, uri: uri) if uri
201
225
  end
202
-
203
- if new_list.empty?
204
- # don't show services w/o active brokers
205
- unregister_service(service)
206
- else
207
- register_service(service, new_list)
208
- end
226
+ # Register new service in the registry
227
+ register_service(service, new_list)
209
228
  end
210
229
 
211
230
  #
data/lib/druid_config.rb CHANGED
@@ -9,6 +9,7 @@ require 'net/http'
9
9
  require 'druid_config/zk'
10
10
  require 'druid_config/version'
11
11
  require 'druid_config/util'
12
+ require 'druid_config/exceptions'
12
13
  require 'druid_config/entities/segment'
13
14
  require 'druid_config/entities/rule'
14
15
  require 'druid_config/entities/rule_collection'
@@ -22,11 +23,6 @@ require 'druid_config/client'
22
23
 
23
24
  # Base namespace of the gem
24
25
  module DruidConfig
25
- #
26
- # Exception class for an error to connect the API
27
- #
28
- class DruidApiError < StandardError; end
29
-
30
26
  # Global client of Druidconfig module
31
27
  @client = nil
32
28
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: druid_config
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Angel M Miguel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-17 00:00:00.000000000 Z
11
+ date: 2015-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: zk
@@ -170,6 +170,7 @@ files:
170
170
  - lib/druid_config/entities/task.rb
171
171
  - lib/druid_config/entities/tier.rb
172
172
  - lib/druid_config/entities/worker.rb
173
+ - lib/druid_config/exceptions.rb
173
174
  - lib/druid_config/util.rb
174
175
  - lib/druid_config/validators/rule_validator.rb
175
176
  - lib/druid_config/version.rb