jones 0.1.0

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.
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: []