jones 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/client.rb +124 -0
  2. metadata +62 -0
data/lib/client.rb ADDED
@@ -0,0 +1,124 @@
1
+ =begin
2
+ Licensed under the Apache License, Version 2.0 (the "License");
3
+ you may not use this file except in compliance with the License.
4
+ You may obtain a copy of the License at
5
+
6
+ http://www.apache.org/licenses/LICENSE-2.0
7
+
8
+ Unless required by applicable law or agreed to in writing, software
9
+ distributed under the License is distributed on an "AS IS" BASIS,
10
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ See the License for the specific language governing permissions and
12
+ limitations under the License.
13
+ =end
14
+
15
+
16
+ require 'forwardable'
17
+ require 'json'
18
+ require 'socket'
19
+ require 'zk'
20
+
21
+
22
+ class JonesClient
23
+ extend Forwardable
24
+ attr_accessor :data
25
+ def_delegators :@data, :[]
26
+
27
+ def initialize(options = {})
28
+ @data = nil
29
+ @callbacks = []
30
+ @conf_sub = nil
31
+ @conf_path = nil
32
+ @logger = Logger.new(STDOUT)
33
+
34
+ parse_options(options)
35
+ setup_zk
36
+ read_nodemap
37
+ end
38
+
39
+ def register_callback(&block)
40
+ @callbacks += [block]
41
+ end
42
+
43
+ private
44
+
45
+ def nodemap_changed(event)
46
+ if event.node_changed?
47
+ read_nodemap
48
+ else
49
+ @logger.error("Unknown ZK node event: #{event.inspect}")
50
+ end
51
+ end
52
+
53
+ def read_nodemap
54
+ data = @zk.get(nodemap_path, :watch => true).first
55
+ if data.nil?
56
+ conf_path = conf_root
57
+ else
58
+ mapping = JSON.load(data)
59
+ conf_path = mapping.fetch(@host, conf_root)
60
+ end
61
+
62
+ setup_conf(conf_path)
63
+ end
64
+
65
+ def setup_conf(conf_path)
66
+ if conf_path != @conf_path
67
+ # path changed so we need to register a new handler
68
+ @conf_path = conf_path
69
+ @conf_sub.unsubscribe unless @conf_sub.nil?
70
+ @conf_sub = @zk.register(@conf_path) { |event| conf_changed(event) }
71
+ read_conf
72
+ end
73
+ end
74
+
75
+ def conf_changed(event)
76
+ if event.node_changed?
77
+ read_conf
78
+ else
79
+ logger.error("Unknown ZK node event: #{event.inspect}")
80
+ end
81
+ end
82
+
83
+ def read_conf()
84
+ @data = JSON.load(@zk.get(@conf_path, :watch => true).first)
85
+ @callbacks.each { |cb| cb.call(@data) }
86
+ end
87
+
88
+ def setup_zk
89
+ @zk = ZK.new(@zkservers) if @zkservers
90
+ @zk.on_expired_session { setup_zk }
91
+ @zk.register(nodemap_path, :only => :changed) { |event| nodemap_changed(event) }
92
+ # reset watch in case of disconnect
93
+ @zk.on_connected { read_nodemap }
94
+ end
95
+
96
+ def parse_options(options)
97
+ @zk, @zkservers = options.values_at(:zk, :zkservers)
98
+ if [@zk, @zkservers].all? || [@zk, @zkservers].none?
99
+ raise ArgumentError, 'must specify :zk or :zkservers'
100
+ end
101
+
102
+ @service = options[:service]
103
+ @host = options.fetch(:host, Socket.gethostname)
104
+ @zkroot = "/services/#{options[:service]}"
105
+ end
106
+
107
+ def nodemap_path
108
+ "#{@zkroot}/nodemaps"
109
+ end
110
+
111
+ def conf_root
112
+ "#{@zkroot}/conf"
113
+ end
114
+ end
115
+
116
+
117
+ #zk = ZK.new('localhost:2181')
118
+
119
+ jc = JonesClient.new(:zkservers => 'localhost:2181', :service => 'test')
120
+ jc.register_callback { |data| puts data['field'] }
121
+ puts jc['field']
122
+
123
+ sleep(20)
124
+ puts jc['field']
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jones
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Matthew Hooker
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-08-05 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: zk
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - '='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.8.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - '='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.8.0
30
+ description:
31
+ email: mwhooker@gmail.com
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - lib/client.rb
37
+ homepage: https://github.com/mwhooker/jones
38
+ licenses:
39
+ - Apache 2.0
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 1.8.23
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: Client for Jones configuration management server
62
+ test_files: []