consul-ruby-client 0.0.4 → 0.0.5

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: 77180800b03d349664137915197bc18fbc2059f8
4
- data.tar.gz: 619c8ee87ce16fa62d7feeb5bad2eb74385fd7fb
3
+ metadata.gz: 892b1008577e86cdd860d5fd19b89d0baf32e79d
4
+ data.tar.gz: cb395d778d0cbd68ab6d1e219bb7e0563e78a239
5
5
  SHA512:
6
- metadata.gz: 580de3dba33a0fd2aa3967404ebb9e581661e46574c2ce269c4b63f7ba1717e9dc8240b9cad6d811f9b3d1b5d4928ad453c3c795529f24d0ed1e54afbad67d31
7
- data.tar.gz: f9d7248c305173cfaf898cc77586ca4e91baa19c286f36341d649095b7d577a91fd37226e29e9c3f21896c5f0cf3be0125c8444108ffdc8233f74227f35317a7
6
+ metadata.gz: ffdbe76cafaca0b747f969595253c2138e32f0ab7ae61721403ac5687c134cd6d80272ae1441b5abea96f04f6224025fae22ca58cac74a3b0f99144bafe05c60
7
+ data.tar.gz: 4c8081a66dd8fb5937de79d42e4cea7ff8316c7300243ec1f1bd209b28d94d9f29a526314f8ffb408e4655a5748a21c741252b3d415f6a08973c9f8b9e3845f6
data/README.md CHANGED
@@ -42,9 +42,8 @@ kvs.get('cat')
42
42
  ### Agent
43
43
 
44
44
  ```
45
- agent = Agent.new
46
- agent.register(Agent::Service.for_name('my_service'))
47
- agent.services
45
+ # Register a service named 'my_service'
46
+ Consul::Client::Agent.new.register(Agent::Service.for_name('my_service'))
48
47
  ```
49
48
 
50
49
  ### Catalog
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env bash
2
+
3
+ rm -f consul-ruby-client-*.gem && \
4
+ gem build consul-ruby-client.gemspec && \
5
+ gem install consul-ruby-client-*.gem
data/build/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/build/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in build.gemspec
4
+ gemspec
data/build/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Michael Hotan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/build/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # Build
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/build`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'build'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install build
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ 1. Fork it ( https://github.com/[my-github-username]/build/fork )
36
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
37
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
38
+ 4. Push to the branch (`git push origin my-new-feature`)
39
+ 5. Create a new Pull Request
data/build/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/build/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "build"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/build/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'build/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "build"
8
+ spec.version = Build::VERSION
9
+ spec.authors = ["Michael Hotan"]
10
+ spec.email = ["michael.hotan@socrata.com"]
11
+
12
+ spec.summary = %q{TODO: Write a short summary, because Rubygems requires one.}
13
+ spec.description = %q{TODO: Write a longer description or delete this line.}
14
+ spec.homepage = "TODO: Put your gem's website or public repo URL here."
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "bundler", "~> 1.9"
31
+ spec.add_development_dependency "rake", "~> 10.0"
32
+ end
@@ -0,0 +1,3 @@
1
+ module Build
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,5 @@
1
+ require "build/version"
2
+
3
+ module Build
4
+ # Your code goes here...
5
+ end
@@ -127,7 +127,7 @@ module Consul
127
127
 
128
128
  # Public: deregisters an existing ConsulHealthCheck or ConsulService
129
129
  #
130
- # entity - ConsulHealthCheck or ConsulService to unregister from this
130
+ # entity - Consul::Model::HealthCheck or Consul::Model::ConsulService to unregister from this
131
131
  #
132
132
  # Returns - the HTTP Response
133
133
  def deregister(entity)
@@ -273,15 +273,12 @@ module Consul
273
273
  end
274
274
  end
275
275
 
276
- # Public: Creates a health check meant to be used when registering a service.
277
- #
278
- #
279
- #
280
276
  # Returns: Consul::Model::HealthCheck instance that represents a script
281
277
  def self.script_health_check(script, interval)
282
278
  Consul::Model::HealthCheck.new(script: script, interval: interval)
283
279
  end
284
280
 
281
+ # Returns: Consul::Model::HealthCheck instance that represents a http health check.
285
282
  def self.http_health_check(http, interval)
286
283
  Consul::Model::HealthCheck.new(http: http, interval: interval)
287
284
  end
@@ -50,7 +50,14 @@ module Consul
50
50
  opts[:params] = params unless params.nil?
51
51
  opts[:accept] = :json if json_only
52
52
  begin
53
- return RestClient.get url, opts
53
+ resp = RestClient.get url, opts
54
+ success = (resp.code == 200 or resp.code == 201)
55
+ if success
56
+ logger.debug("Successful GET at endpoint #{url}")
57
+ else
58
+ logger.warn("Unable to GET from endpoint #{url} returned code: #{resp.code}")
59
+ end
60
+ return resp
54
61
  rescue Exception => e
55
62
  # Unable to communicate with consul agent.
56
63
  logger.warn(e.message)
@@ -71,16 +78,22 @@ module Consul
71
78
  # Validation
72
79
  validate_url(url)
73
80
 
74
- p = {}
75
- p[:params] = params unless params.nil?
81
+ # If possible, Convert value to json
82
+ unless Consul::Utils.valid_json?(value)
83
+ value = value.to_json if value.respond_to?(:to_json)
84
+ end
85
+
86
+ opts = {}
87
+ opts[:params] = params unless params.nil?
76
88
  begin
77
- if Consul::Utils.valid_json?(value)
78
- resp = RestClient.put(url, value, :content_type => :json) {|response, req, res| response }
89
+ opts[:content_type] = :json if Consul::Utils.valid_json?(value)
90
+ resp = RestClient.put(url, value, opts) {|response, req, res| response }
91
+ success = (resp.code == 200 or resp.code == 201)
92
+ if success
93
+ logger.debug("Successful PUT #{value} at endpoint #{url}")
79
94
  else
80
- resp = RestClient.put(url, value) {|response, req, res| response }
95
+ logger.warn("Unable to PUT #{value} at endpoint #{url} returned code: #{resp.code}")
81
96
  end
82
- success = (resp.code == 200 or resp.code == 201)
83
- logger.warn("Unable to send #{value} to endpoint #{url} returned code: #{resp.code}") unless success
84
97
  return success, resp.body
85
98
  rescue Exception => e
86
99
  logger.error('RestClient.put Error: Unable to reach consul agent')
@@ -25,24 +25,22 @@ module Consul
25
25
  #
26
26
  # Reference: https://www.consul.io/docs/agent/http/kv.html
27
27
  #
28
- # key - Key to get value for, if recurse = true the key is treated by a prefix
29
- # recurse - Flag to signify treating the key as a prefix
30
- # index - Can be used to establish blocking queries by setting
31
- # only_keys - Flag to return only keys
32
- # separator - list only up to a given separator
28
+ # Params:
29
+ # key - Key to get value for
30
+ # params - Parameter hash for Consul
31
+ # params[:recurse] - existence of any value with tell consul to remove all keys
32
+ # with the same prefix
33
+ # params[:index] - Existence of :index, indicates to use a blocking call
34
+ # params[:keys] - Existence of :keys, indicates to only return keys
35
+ # params[:separator] - List only up to a given separator
33
36
  #
34
37
  # Returns: An array of Consul::Model::KeyValue objects, if only
35
- def get(key,
36
- recurse = false,
37
- index = false,
38
- only_keys = false,
39
- separator = nil)
38
+ def get(key, params = {})
40
39
  key = sanitize(key)
41
- params = {}
42
- params[:recurse] = nil if recurse
43
- params[:index] = nil if index
44
- params[:keys] = nil if only_keys
45
- params[:separator] = separator unless separator.nil?
40
+ params = {} if params.nil?
41
+ params[:recurse] = nil if params.has_key?(:recurse)
42
+ params[:index] = nil if params.has_key?(:index)
43
+ params[:keys] = nil if params.has_key?(:keys)
46
44
  begin
47
45
  resp = _get build_url(compose_key(key)), params
48
46
  rescue Exception => e
@@ -51,10 +49,10 @@ module Consul
51
49
  end
52
50
  return nil if resp.code == 404
53
51
  json = JSON.parse(resp)
54
- return json if only_keys
52
+ return json if params.has_key?(:keys)
55
53
  json.map { |kv|
56
54
  kv = Consul::Model::KeyValue.new.extend(Consul::Model::KeyValue::Representer).from_hash(kv)
57
- kv.value = Base64.decode64(kv.value)
55
+ kv.value = Base64.decode64(kv.value) unless kv.value.nil?
58
56
  kv
59
57
  }
60
58
  end
@@ -65,46 +63,39 @@ module Consul
65
63
  #
66
64
  # Reference: https://www.consul.io/docs/agent/http/kv.html
67
65
  #
68
- # key - Key
69
- # value - Value to assign for Key
70
- # flags - Client specified value [0, 2e64-1]
71
- # cas - Check and Set operation
72
- # acquire - Session id to acquire the lock with a valid session.
73
- # release - Session id to release the lock with a valid session.
66
+ # key - Key
67
+ # value - Value to assign for Key
68
+ # params - Consul Parameter Hash
69
+ # params[:flags] - Unsigned value between 0 and 2^(64-1). General purpose parameter.
70
+ # params[:cas] - Modify index for Check and set operation.
71
+ # params[:acquire] - session id to use to lock.
72
+ # params[:release] - session id to use to unlock.
74
73
  #
75
74
  # Returns: True on success, False on failure
76
75
  # Throws: IOError: Unable to contact Consul Agent.
77
- def put(key,
78
- value,
79
- flags = nil,
80
- cas = nil,
81
- acquire_session = nil,
82
- release_session = nil)
76
+ def put(key, value, params = {})
83
77
  key = sanitize(key)
84
- params = {}
85
- params[:flags] = flags unless flags.nil?
86
- params[:cas] = cas unless cas.nil?
87
- params[:acquire] = acquire_session unless acquire_session.nil?
88
- params[:release_session] = release_session unless release_session.nil?
78
+ params = {} if params.nil?
89
79
  begin
90
80
  value = JSON.generate(value)
91
81
  rescue JSON::GeneratorError
92
- logger.debug("Using non-JSON value for key #{key}")
82
+ logger.debug("Using non-JSON value: #{value} for key #{key}")
93
83
  end
94
- _put build_url(compose_key(key)), value, {:params => params}
84
+ _put build_url(compose_key(key)), value, params
95
85
  end
96
86
 
97
87
  # Public: Delete the Key Value pair in consul.
98
88
  #
99
- # key - Key
100
- # recurse - Delete all keys as the 'key' is a prefix for
101
- # cas - Check and Set
102
- def delete(key, recurse = false, cas = nil)
89
+ # key - Key
90
+ # params - Parameter Hash
91
+ # params[:recurse] - Existence of key notifies that all sub keys will be deleted
92
+ # params[:cas] - Modify index for Check and set operation.
93
+ #
94
+ def delete(key, params = {})
103
95
  key = sanitize(key)
104
96
  params = {}
105
- params[:recurse] = nil if recurse
106
- params[:cas] = cas unless cas.nil?
107
- RestClient.delete build_url(key), {:params => params}
97
+ params[:recurse] = nil if params.has_key?(:recurse)
98
+ RestClient.delete build_url(compose_key(key)), {:params => params}
108
99
  end
109
100
 
110
101
  # Public: Returns the name space of this KeyValue Store. This allows you to
@@ -131,10 +122,11 @@ module Consul
131
122
  key[key.length - 1] = ''
132
123
  end
133
124
  end
125
+ key
134
126
  end
135
127
 
136
128
  def compose_key(key)
137
- ns = namespace.strip
129
+ ns = sanitize(namespace.strip)
138
130
  return "#{key}" if ns.empty?
139
131
  "#{ns}/#{key}"
140
132
  end
@@ -42,14 +42,14 @@ module Consul
42
42
  # session - Session to create.
43
43
  # dc - Consul data center
44
44
  #
45
- # Returns The Session ID a
45
+ # Returns The Session ID
46
46
  def create(session, dc = nil)
47
47
  raise TypeError, 'Session must be of type Consul::Model::Session' unless session.kind_of? Consul::Model::Session
48
48
  params = {}
49
49
  params[:dc] = dc unless dc.nil?
50
50
  success, body = _put(build_url('create'), session.extend(Consul::Model::Session::Representer).to_json, params)
51
51
  return Consul::Model::Session.new.extend(Consul::Model::Service::Representer).from_json(body) if success
52
- logger.warn("Unable to create session with #{session}")
52
+ logger.warn("Unable to create session with #{session} reason: #{body}")
53
53
  nil
54
54
  end
55
55
 
@@ -98,7 +98,7 @@ module Consul
98
98
  session = extract_session_id(session)
99
99
  params = {}
100
100
  params[:dc] = dc unless dc.nil?
101
- success, _ = _put build_url("renew/#{session.name}"), session.to_json
101
+ success, _ = _put build_url("renew/#{session}"), session.to_json
102
102
  success
103
103
  end
104
104
 
@@ -1,5 +1,5 @@
1
1
  module Consul
2
2
  module Client
3
- VERSION = "0.0.4"
3
+ VERSION = "0.0.5"
4
4
  end
5
5
  end
@@ -1,8 +1,12 @@
1
+ require 'logger'
2
+ require_relative '../../../lib/consul/client/agent'
3
+ require_relative '../../../lib/consul/client/key_value'
4
+ require_relative '../../../lib/consul/client/session'
1
5
 
2
6
  module Consul
3
7
  module Extensions
4
8
  class Base
5
-
9
+ include Consul::Client
6
10
  # Public: Constructor for this extension. Ensures a global unique ID for this client for a given namespace.
7
11
  #
8
12
  # options - (Optional) Hash of Consul Client and extension options.
@@ -27,12 +31,20 @@ module Consul
27
31
 
28
32
  # The Consul Agent Client to use
29
33
  def agent
30
- @agent = Agent.new(options)
34
+ @agent ||= Agent.new(options)
31
35
  end
32
36
 
33
37
  # The Key Value Store to use.
34
38
  def key_value_store
35
- @kvs = KeyValue.new(options)
39
+ @kvs ||= KeyValue.new(options)
40
+ end
41
+
42
+ def session
43
+ @session || Session.new(options)
44
+ end
45
+
46
+ def logger
47
+ @logger ||= options[:logger] || Logger.new(STDOUT)
36
48
  end
37
49
 
38
50
  # TODO Add other clients here.
@@ -1,5 +1,6 @@
1
1
  require_relative 'base'
2
2
  require_relative '../../consul/client/key_value'
3
+ require_relative '../model/member'
3
4
 
4
5
  module Consul
5
6
  module Extensions
@@ -11,6 +12,8 @@ module Consul
11
12
  class UID < Base
12
13
  include Consul::Client
13
14
 
15
+ MAX_ATTEMPTS = 10
16
+
14
17
  # Public: Constructor for this extension. Ensures a global unique ID for this client for a given namespace.
15
18
  #
16
19
  # options - (Required) Hash of Consul Client and extension options.
@@ -28,44 +31,106 @@ module Consul
28
31
  # Extension instance capable of generating GUID.
29
32
  def initialize(options)
30
33
  raise TypeError.new "Options must not be a Hash that contains \":name\"" unless options.is_a?(Hash)
31
- if options.has_key?(:name) or options[:name].strip.empty?
34
+ if options[:name].nil? or options[:name].strip.empty?
32
35
  raise ArgumentError.new "Illegal GUID Name: \"#{options[:name]}\". Must not be nil or empty"
33
36
  end
34
- raise ArgumentError.new "GUID Name cannot start with special character"
37
+ raise ArgumentError.new "GUID Name cannot start with special character" unless /^[^0-9A-Za-z].*/.match(options[:name]).nil?
38
+ @name = options[:name]
35
39
  options[:namespace] = namespace
36
40
  @options = options.clone
37
41
  end
38
42
 
39
- # Public: Generate a global unique id syncronously with other
40
- def generate
43
+ # Public: Generate a global unique id synchronously with other
44
+ def get
41
45
  # TODO Generation implementation
42
46
  # Create a Consul Session the the underlying namespace
43
- # Get the current available value this namespace, acquire the lock
44
- # if unable to get the lock then try again a FIXED number of times
45
- # else (Lock Acquired)
46
- # if value is nil then we need to set the available value to one assuming this id is 0
47
- # if value is not nil then we need to set the available value to one plus that value.
48
- # if unable to set the lock then get the value and try again.
47
+ cur_session = session.create(Session.for_name(namespace))
48
+ raise 'Unable to create session to generate UID.' if cur_session.nil?
49
+
50
+ # Check if there is already an UID associated with this client_id.
51
+ existing_uid = key_value_store.get(client_uid_path)
52
+ unless existing_uid.nil? or (existing_uid.respond_to?(:empty?) and existing_uid.empty?)
53
+ return existing_uid[0].value.to_i
54
+ end
55
+
56
+ # No existing UID so let provision one for this node.
57
+ for i in 1..MAX_ATTEMPTS
58
+ session.renew cur_session # Renew the current session so we can obtain a lock
59
+
60
+ # Get the current available uid with
61
+ auid = key_value_store.get(available_uid_path, {:index => nil})
62
+ if auid.nil? # Key does not exists. Which also means its the first ever UID.
63
+ logger.debug("First ever UID for #{namespace}")
64
+ auid = 0
65
+ else
66
+ auid = auid[0].value.to_i
67
+ logger.debug("Found available UID for #{namespace} value: #{auid}")
68
+ end
69
+ # Acquire the lock
70
+ member = agent.describe.member.to_json
71
+ acquire_lock_success, body = key_value_store.put(available_lock_path,
72
+ member,
73
+ {:acquire => cur_session.id})
74
+ unless acquire_lock_success
75
+ logger.warn("Attempt: #{i} Unable to acquire lock for #{namespace} reason: #{body}")
76
+ next
77
+ end
78
+
79
+ # Update the available uid with the next value
80
+ available_uid_update_success, body = key_value_store.put(available_uid_path, auid + 1)
81
+ unless available_uid_update_success
82
+ logger.warn("Attempt: #{i} Unable to update available uid for #{namespace} reason: #{body}")
83
+ next
84
+ end
85
+
86
+ # Release the lock
87
+ release_lock_success, body = key_value_store.put(available_lock_path,
88
+ member,
89
+ {:release => cur_session.id})
90
+ logger.warn("Unable to release lock for #{namespace} reason: #{body}. Resorting to Timeout.") unless release_lock_success
91
+
92
+ # Update the Key Value store for this client id so we don't provision another one.
93
+ client_id_update_success, body = key_value_store.put(client_uid_path, auid.to_s)
94
+ unless client_id_update_success
95
+ logger.warn("Attempt: #{i} Unable to update id for client #{client_id} with value #{auid} due to #{body}")
96
+ next
97
+ end
98
+
99
+ # After successfully and synchronously updating available universal id and this client id continue
100
+ return auid
101
+ end
102
+ logger.error("Unable to generate key after #{MAX_ATTEMPTS} attempts")
103
+ nil
49
104
  end
50
105
 
51
- private
106
+ # Path to getting the next available UID.
107
+ def available_uid_path
108
+ '.available.uid'
109
+ end
52
110
 
53
- # The FQ namespace for this GUID
54
- def namespace
55
- @namespace ||= "#{extensions_namespace}/uid/#{@options[:name]}"
111
+ def available_lock_path
112
+ '.available.lock'
56
113
  end
57
114
 
58
- def available_uid
59
- "#{namespace}/.available"
115
+ # Path to this specific Client UID.
116
+ def client_uid_path
117
+ client_id
60
118
  end
61
119
 
62
120
  # The individual client id for this uid generator
63
121
  def client_id
64
- client_id = nil
122
+ c_id = nil
65
123
  unless @options[:client_id].nil? or @options[:client_id].strip.empty?
66
- client_id = client_id.strip
124
+ c_id = @options[:client_id].strip
67
125
  end
68
- @client_id ||= client_id || agent.describe.member.name
126
+ @client_id ||= c_id || agent.describe.member.name
127
+ end
128
+
129
+ private
130
+
131
+ # The FQ namespace for this GUID
132
+ def namespace
133
+ @namespace ||= "#{extensions_namespace}/uid/#{@name}"
69
134
  end
70
135
 
71
136
  end
data/lib/setup.rb ADDED
@@ -0,0 +1,8 @@
1
+ # Convenience Script for testing in IRB
2
+ #
3
+ # To run in local IRB and preload some namespaces run the following command from project root.
4
+ # bin/build_install.sh && irb -Ilib -rsetup.rb
5
+
6
+ require 'consul/client'
7
+ include Consul::Client
8
+ include Consul::Extensions
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: consul-ruby-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Hotan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-29 00:00:00.000000000 Z
11
+ date: 2015-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -127,7 +127,8 @@ description: |-
127
127
  layer.
128
128
  email:
129
129
  - michael.hotan@socrata.com
130
- executables: []
130
+ executables:
131
+ - build_install.sh
131
132
  extensions: []
132
133
  extra_rdoc_files: []
133
134
  files:
@@ -137,6 +138,18 @@ files:
137
138
  - LICENSE.txt
138
139
  - README.md
139
140
  - Rakefile
141
+ - bin/build_install.sh
142
+ - build/.gitignore
143
+ - build/CODE_OF_CONDUCT.md
144
+ - build/Gemfile
145
+ - build/LICENSE.txt
146
+ - build/README.md
147
+ - build/Rakefile
148
+ - build/bin/console
149
+ - build/bin/setup
150
+ - build/build.gemspec
151
+ - build/lib/build.rb
152
+ - build/lib/build/version.rb
140
153
  - consul-ruby-client.gemspec
141
154
  - lib/consul/client.rb
142
155
  - lib/consul/client/agent.rb
@@ -157,6 +170,7 @@ files:
157
170
  - lib/consul/model/service.rb
158
171
  - lib/consul/model/session.rb
159
172
  - lib/consul/util/utils.rb
173
+ - lib/setup.rb
160
174
  - spec/base_client_spec.rb
161
175
  - spec/spec_helper.rb
162
176
  homepage: https://github.com/mhotan-s/consul-ruby-client