ruby_doozer 0.6.0 → 0.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6d35c5108fdd5c6d848eba0575c8950f7112f67a
4
- data.tar.gz: feab4e9400b886c736d5813ed362f14b0af171a1
3
+ metadata.gz: bb1a71fd888931d010aeffdf2a732c921672a28d
4
+ data.tar.gz: e31970bb09b093c59ee6e221dd302c4ce1a00d81
5
5
  SHA512:
6
- metadata.gz: c13324138a81aeb313ea82361d1047309f751b0820a476c5d5e4ae5ee404856e5609e75c7eeb2db49f3cfb8fbff59644f6de357e02b984fda12544bb28c4155e
7
- data.tar.gz: 37d8d12800d7a96ef2372a85be8f68c2df716e3f9f29c515d1b100c96bb7bc99cab677a4223c5dbdf013f17a4099f66c871b2d61a62316117d52b92a242a02ca
6
+ metadata.gz: a8a41f827035cf8a419c4eaa3f95965d6aa390660d6d0af404bd3971bbb7ffaaa0203ffd2bb5ad9e0ee770b9247d3c1425a5faebfe16e2279a63c55b7db46e81
7
+ data.tar.gz: 24666f05f96fda73696d672ff0d4b1a83b27d0e4ab5dca2248eb0bf3ea50aa2ee7dac854d446dccf1cc792c736231597fe4f4cb81ac2b7731484488523c51846
data/Rakefile CHANGED
@@ -28,6 +28,7 @@ task :gem do |t|
28
28
  spec.add_dependency 'ruby_protobuf', '>= 0.4.11'
29
29
  spec.add_dependency 'gene_pool', '>= 1.3.0'
30
30
  spec.add_dependency 'sync_attr', '>= 1.0.0'
31
+ spec.add_dependency 'multi_json', '>= 1.6.1'
31
32
  end
32
33
  Gem::Package.build gemspec
33
34
  end
@@ -4,4 +4,8 @@ module RubyDoozer
4
4
  autoload :Client, 'ruby_doozer/client'
5
5
  autoload :Registry, 'ruby_doozer/registry'
6
6
  autoload :CachedRegistry, 'ruby_doozer/cached_registry'
7
+ module Json
8
+ autoload :Serializer, 'ruby_doozer/json/serializer'
9
+ autoload :Deserializer, 'ruby_doozer/json/deserializer'
10
+ end
7
11
  end
@@ -10,8 +10,8 @@ require 'semantic_logger'
10
10
  #
11
11
  # Notifies registered subscribers when information has changed
12
12
  #
13
- # All paths specified are relative to the root_path. As such the root path
14
- # is never returned, nor is it required when a path is supplied as input.
13
+ # All paths specified are relative to the root_path. As such the root key
14
+ # is never returned, nor is it required when a key is supplied as input.
15
15
  # For example, with a root_path of /foo/bar, any paths passed in will leave
16
16
  # out the root_path: host/name
17
17
  #
@@ -23,7 +23,12 @@ module RubyDoozer
23
23
  # Logging instance for this class
24
24
  include SemanticLogger::Loggable
25
25
 
26
- # Create a Registry instance to manage a path of information within doozer
26
+ # Create a Registry instance to manage information within doozer
27
+ # and keep a local cached copy of the data in doozer to support
28
+ # high-speed or frequent reads.
29
+ #
30
+ # Writes are sent to doozer and then replicate back to the local cache
31
+ # only once doozer has updated its store
27
32
  #
28
33
  # See RubyDoozer::Registry for complete list of options
29
34
  #
@@ -31,12 +36,12 @@ module RubyDoozer
31
36
  super
32
37
  @cache = ThreadSafe::Hash.new
33
38
 
34
- path = "#{@root_path}/**"
39
+ key = "#{@root}/**"
35
40
  doozer_pool.with_connection do |doozer|
36
41
  @current_revision = doozer.current_revision
37
42
  # Fetch all the configuration information from Doozer and set the internal copy
38
- doozer.walk(path, @current_revision) do |path, value, revision|
39
- set_cached_value(relative_path(path), value)
43
+ doozer.walk(key, @current_revision) do |key, value, revision|
44
+ set_cached_value(relative_key(key), value)
40
45
  end
41
46
  end
42
47
 
@@ -44,9 +49,9 @@ module RubyDoozer
44
49
  monitor_thread
45
50
  end
46
51
 
47
- # Retrieve the latest value from a specific path from the registry
48
- def [](path)
49
- @cache[path]
52
+ # Retrieve the latest value from a specific key from the registry
53
+ def [](key)
54
+ @cache[key]
50
55
  end
51
56
 
52
57
  # Iterate over every key, value pair in the registry at the root_path
@@ -59,8 +64,8 @@ module RubyDoozer
59
64
  @cache.dup.each_pair(&block)
60
65
  end
61
66
 
62
- # Returns [Array<String>] all paths in the registry
63
- def paths
67
+ # Returns [Array<String>] all keys in the registry
68
+ def keys
64
69
  @cache.keys
65
70
  end
66
71
 
@@ -71,26 +76,26 @@ module RubyDoozer
71
76
 
72
77
  # When an entry is created the block will be called
73
78
  # Parameters
74
- # path
75
- # The relative path to watch for changes
79
+ # key
80
+ # The relative key to watch for changes
76
81
  # block
77
82
  # The block to be called
78
83
  #
79
84
  # Parameters passed to the block:
80
- # path
81
- # The path that was created
82
- # Supplying a path of '*' means all paths
85
+ # key
86
+ # The key that was created
87
+ # Supplying a key of '*' means all paths
83
88
  # Default: '*'
84
89
  #
85
90
  # value
86
91
  # New value from doozer
87
92
  #
88
93
  # Example:
89
- # registry.on_update do |path, value|
90
- # puts "#{path} was created with #{value}"
94
+ # registry.on_update do |key, value, revision|
95
+ # puts "#{key} was created with #{value}"
91
96
  # end
92
- def on_create(path='*', &block)
93
- ((@create_subscribers ||= ThreadSafe::Hash.new)[path] ||= ThreadSafe::Array.new) << block
97
+ def on_create(key='*', &block)
98
+ ((@create_subscribers ||= ThreadSafe::Hash.new)[key] ||= ThreadSafe::Array.new) << block
94
99
  end
95
100
 
96
101
  ############################
@@ -113,30 +118,30 @@ module RubyDoozer
113
118
  @cache[doozer_path]
114
119
  end
115
120
 
116
- # The path has been added or updated in the registry
117
- def changed(path, value)
118
- previous_value = get_cached_value(path)
121
+ # The key has been added or updated in the registry
122
+ def changed(key, value, revision)
123
+ previous_value = get_cached_value(key)
119
124
 
120
125
  # Update in memory copy
121
- set_cached_value(path, value)
126
+ set_cached_value(key, value)
122
127
 
123
128
  # It is an update if we already have a value
124
129
  if previous_value
125
130
  # Call parent which will notify Updated Subscribers
126
131
  super
127
132
  else
128
- logger.debug { "Created: #{path} => #{value}" }
133
+ logger.debug "Created: #{key}", value
129
134
 
130
135
  return unless @create_subscribers
131
136
 
132
137
  # Subscribers to specific paths
133
- if subscribers = @create_subscribers[path]
134
- subscribers.each{|subscriber| subscriber.call(path, value)}
138
+ if subscribers = @create_subscribers[key]
139
+ subscribers.each{|subscriber| subscriber.call(key, value, revision)}
135
140
  end
136
141
 
137
142
  # Any subscribers for all events?
138
143
  if all_subscribers = @create_subscribers['*']
139
- all_subscribers.each{|subscriber| subscriber.call(path, value)}
144
+ all_subscribers.each{|subscriber| subscriber.call(key, value, revision)}
140
145
  end
141
146
  end
142
147
  end
@@ -0,0 +1,62 @@
1
+ require 'yaml'
2
+ require 'multi_json'
3
+ module RubyDoozer
4
+ module Json
5
+
6
+ # Deserialize from JSON entries in Doozer
7
+ module Deserializer
8
+ def self.deserialize(value)
9
+ return nil unless value
10
+
11
+ if value.strip.start_with?('{') || value.strip.start_with?('[{')
12
+ symbolize(MultiJson.load(value))
13
+ else
14
+ symbolize_string(value)
15
+ end
16
+ end
17
+
18
+ # Returns the supplied value symbolized
19
+ def self.symbolize(v)
20
+ if v.is_a?(Hash)
21
+ symbolize_hash(v)
22
+ elsif v.is_a?(Array)
23
+ symbolize_array(v)
24
+ elsif v.is_a?(String)
25
+ symbolize_string(v)
26
+ else
27
+ v
28
+ end
29
+ end
30
+
31
+ # Returns a new hash updated with keys and values that are strings
32
+ # starting with ':' are turned into symbols
33
+ def self.symbolize_hash(hash)
34
+ h = hash.dup
35
+ hash.each_pair do |k, v|
36
+ # Convert values in the hash
37
+ h[k] = symbolize(v)
38
+
39
+ # Convert key to a symbol if it is a symbol string
40
+ h[k[1..-1].to_sym] = h.delete(k) if k.is_a?(String) && k.start_with?(':')
41
+ end
42
+ h
43
+ end
44
+
45
+ # Returns a new Array with any symbols strings returned as symbols
46
+ def self.symbolize_array(a)
47
+ a.collect {|v| symbolize(v)}
48
+ end
49
+
50
+ # Returns a new string with the string parsed and symbol string converted to a symbol
51
+ def self.symbolize_string(s)
52
+ # JSON Parser cannot parse non-hash/array values
53
+ value = YAML.load(s)
54
+ # Now check for symbols which are strings starting with ':'
55
+ value.is_a?(String) && value.start_with?(':') ? value[1..-1].to_sym : value
56
+ rescue Exception
57
+ s
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,53 @@
1
+ require 'multi_json'
2
+ module RubyDoozer
3
+ module Json
4
+
5
+ # Serialize to JSON for storing in Doozer
6
+ module Serializer
7
+ def self.serialize(value)
8
+ if value.is_a?(Hash) || value.is_a?(Array)
9
+ MultiJson.encode(desymbolize(value))
10
+ else
11
+ value.to_s
12
+ end
13
+ end
14
+
15
+ # Returns the supplied value with symbols converted to a string prefixed
16
+ # with ':'
17
+ def self.desymbolize(v)
18
+ if v.is_a?(Hash)
19
+ desymbolize_hash(v)
20
+ elsif v.is_a?(Array)
21
+ desymbolize_array(v)
22
+ elsif v.is_a?(Symbol)
23
+ desymbolize_symbol(v)
24
+ else
25
+ v.to_s
26
+ end
27
+ end
28
+
29
+ # Returns a new hash with all symbol keys and values as strings starting with ':'
30
+ def self.desymbolize_hash(hash)
31
+ h = hash.dup
32
+ hash.each_pair do |k, v|
33
+ # Convert values in the hash
34
+ h[k] = desymbolize(v)
35
+
36
+ # Convert key to a string if it is a symbol
37
+ h[desymbolize_symbol(k)] = h.delete(k) if k.is_a?(Symbol)
38
+ end
39
+ h
40
+ end
41
+
42
+ # Returns a new Array with any symbols returned as symbol strings
43
+ def self.desymbolize_array(a)
44
+ a.collect {|v| desymbolize(v)}
45
+ end
46
+
47
+ def self.desymbolize_symbol(s)
48
+ ":#{s}"
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -2,6 +2,7 @@ require 'thread_safe'
2
2
  require 'gene_pool'
3
3
  require 'semantic_logger'
4
4
  require 'sync_attr'
5
+ require 'ruby_doozer/json/deserializer'
5
6
 
6
7
  #
7
8
  # Registry
@@ -10,10 +11,10 @@ require 'sync_attr'
10
11
  #
11
12
  # Notifies registered subscribers when information has changed
12
13
  #
13
- # All paths specified are relative to the root_path. As such the root path
14
- # is never returned, nor is it required when a path is supplied as input.
15
- # For example, with a root_path of /foo/bar, any paths passed in will leave
16
- # out the root_path: host/name
14
+ # All paths specified are relative to the root. As such the root key
15
+ # is never returned, nor is it required when a key is supplied as input.
16
+ # For example, with a root of /foo/bar, any paths passed in will leave
17
+ # out the root: host/name
17
18
  #
18
19
  module RubyDoozer
19
20
  class Registry
@@ -21,13 +22,13 @@ module RubyDoozer
21
22
  # Logging instance for this class
22
23
  include SemanticLogger::Loggable
23
24
 
24
- attr_reader :doozer_config, :doozer_pool, :current_revision, :root_path
25
+ attr_reader :doozer_config, :doozer_pool, :current_revision, :root
25
26
 
26
- # Create a Registry instance to manage a path of information within doozer
27
+ # Create a Registry instance to manage a information within doozer
27
28
  #
28
- # :root_path [String]
29
- # Root path to load and then monitor for changes
30
- # It is not recommended to set the root_path to "/" as it will generate
29
+ # :root [String]
30
+ # Root key to load and then monitor for changes
31
+ # It is not recommended to set the root to "/" as it will generate
31
32
  # significant traffic since it will also monitor Doozer Admin changes
32
33
  # Mandatory
33
34
  #
@@ -84,15 +85,15 @@ module RubyDoozer
84
85
  #
85
86
  def initialize(params)
86
87
  params = params.dup
87
- @root_path = params.delete(:root_path)
88
- raise "Missing mandatory parameter :root_path" unless @root_path
88
+ @root = params.delete(:root) || params.delete(:root_path)
89
+ raise "Missing mandatory parameter :root" unless @root
89
90
 
90
- # Add leading '/' to root_path if missing
91
- @root_path = "/#{@root_path}" unless @root_path.start_with?('/')
91
+ # Add leading '/' to root if missing
92
+ @root = "/#{@root}" unless @root.start_with?('/')
92
93
 
93
94
  # Strip trailing '/' if supplied
94
- @root_path = @root_path[0..-2] if @root_path.end_with?("/")
95
- @root_path_with_trail = "#{@root_path}/"
95
+ @root = @root[0..-2] if @root.end_with?("/")
96
+ @root_with_trail = "#{@root}/"
96
97
 
97
98
  @doozer_config = params.delete(:doozer) || {}
98
99
  @doozer_config[:servers] ||= ['127.0.0.1:8046']
@@ -102,6 +103,10 @@ module RubyDoozer
102
103
  @doozer_config[:connect_retry_count] ||= 10
103
104
  @doozer_config[:server_selector] ||= :random
104
105
 
106
+ # Allow the serializer and deserializer implementations to be replaced
107
+ @serializer = params.delete(:serializer) || RubyDoozer::Json::Serializer
108
+ @deserializer = params.delete(:deserializer) || RubyDoozer::Json::Deserializer
109
+
105
110
  # Connection pool settings
106
111
  @doozer_pool = GenePool.new(
107
112
  :name =>"Doozer Connection Pool",
@@ -125,27 +130,28 @@ module RubyDoozer
125
130
  end
126
131
 
127
132
  # Retrieve the latest value from a specific path from the registry
128
- def [](path)
129
- doozer_pool.with_connection do |doozer|
130
- doozer[full_path(path)]
133
+ def [](key)
134
+ value = doozer_pool.with_connection do |doozer|
135
+ doozer[full_key(key)]
131
136
  end
137
+ @deserializer.deserialize(value)
132
138
  end
133
139
 
134
- # Replace the latest value at a specific path
135
- def []=(path,value)
140
+ # Replace the latest value at a specific key
141
+ def []=(key,value)
136
142
  doozer_pool.with_connection do |doozer|
137
- doozer[full_path(path)] = value
143
+ doozer[full_key(key)] = @serializer.serialize(value)
138
144
  end
139
145
  end
140
146
 
141
- # Delete the value at a specific path
142
- def delete(path)
147
+ # Delete the value at a specific key
148
+ def delete(key)
143
149
  doozer_pool.with_connection do |doozer|
144
- doozer.delete(full_path(path))
150
+ doozer.delete(full_key(key))
145
151
  end
146
152
  end
147
153
 
148
- # Iterate over every key, value pair in the registry at the root_path
154
+ # Iterate over every key, value pair in the registry at the root
149
155
  #
150
156
  # If :cache was set to false on the initializer this call will
151
157
  # make network calls to doozer to retrieve the current values
@@ -154,19 +160,19 @@ module RubyDoozer
154
160
  # Example:
155
161
  # registry.each_pair {|k,v| puts "#{k} => #{v}"}
156
162
  def each_pair(&block)
157
- path = "#{@root_path}/**"
163
+ key = "#{@root}/**"
158
164
  doozer_pool.with_connection do |doozer|
159
- doozer.walk(path) do |path, value, revision|
160
- block.call(relative_path(path), value)
165
+ doozer.walk(key) do |key, value, revision|
166
+ block.call(relative_key(key), @deserializer.deserialize(value))
161
167
  end
162
168
  end
163
169
  end
164
170
 
165
- # Returns [Array<String>] all paths in the registry
166
- def paths
167
- paths = []
168
- each_pair {|k,v| paths << k}
169
- paths
171
+ # Returns [Array<String>] all keys in the registry
172
+ def keys
173
+ keys = []
174
+ each_pair {|k,v| keys << k}
175
+ keys
170
176
  end
171
177
 
172
178
  # Returns a copy of the registry as a Hash
@@ -189,103 +195,103 @@ module RubyDoozer
189
195
 
190
196
  # When an entry is updated the block will be called
191
197
  # Parameters
192
- # path
193
- # The relative path to watch for changes
198
+ # key
199
+ # The relative key to watch for changes
194
200
  # block
195
201
  # The block to be called
196
202
  #
197
203
  # Parameters passed to the block:
198
- # path
199
- # The path that was updated in doozer
200
- # Supplying a path of '*' means all paths
204
+ # key
205
+ # The key that was updated in doozer
206
+ # Supplying a key of '*' means all paths
201
207
  # Default: '*'
202
208
  #
203
209
  # value
204
210
  # New value from doozer
205
211
  #
206
212
  # Example:
207
- # registry.on_update do |path, value, old_value|
208
- # puts "#{path} was updated to #{value}"
213
+ # registry.on_update do |key, value, revision|
214
+ # puts "#{key} was updated to #{value}"
209
215
  # end
210
- def on_update(path='*', &block)
216
+ def on_update(key='*', &block)
211
217
  # Start monitoring thread if not already started
212
218
  monitor_thread
213
- ((@update_subscribers ||= ThreadSafe::Hash.new)[path] ||= ThreadSafe::Array.new) << block
219
+ ((@update_subscribers ||= ThreadSafe::Hash.new)[key] ||= ThreadSafe::Array.new) << block
214
220
  end
215
221
 
216
222
  # When an entry is deleted the block will be called
217
223
  # Parameters
218
- # path
219
- # The relative path to watch for changes
224
+ # key
225
+ # The relative key to watch for changes
220
226
  # block
221
227
  # The block to be called
222
228
  #
223
229
  # Parameters passed to the block:
224
- # path
225
- # The path that was deleted from doozer
226
- # Supplying a path of '*' means all paths
230
+ # key
231
+ # The key that was deleted from doozer
232
+ # Supplying a key of '*' means all paths
227
233
  # Default: '*'
228
234
  #
229
235
  # Example:
230
- # registry.on_delete do |path|
231
- # puts "#{path} was deleted"
236
+ # registry.on_delete do |key, revision|
237
+ # puts "#{key} was deleted"
232
238
  # end
233
- def on_delete(path='*', &block)
239
+ def on_delete(key='*', &block)
234
240
  # Start monitoring thread if not already started
235
241
  monitor_thread
236
- ((@delete_subscribers ||= ThreadSafe::Hash.new)[path] ||= ThreadSafe::Array.new) << block
242
+ ((@delete_subscribers ||= ThreadSafe::Hash.new)[key] ||= ThreadSafe::Array.new) << block
237
243
  end
238
244
 
239
245
  ############################
240
246
  protected
241
247
 
242
- # Returns the full path given a relative path
243
- def full_path(relative_path)
244
- "#{@root_path}/#{relative_path}"
248
+ # Returns the full key given a relative key
249
+ def full_key(relative_key)
250
+ "#{@root}/#{relative_key}"
245
251
  end
246
252
 
247
- # Returns the full path given a relative path
248
- def relative_path(full_path)
249
- full_path.sub(@root_path_with_trail, '')
253
+ # Returns the full key given a relative key
254
+ def relative_key(full_key)
255
+ full_key.sub(@root_with_trail, '')
250
256
  end
251
257
 
252
- # The path has been added or updated in the registry
253
- def changed(path, value)
254
- logger.debug { "Updated: #{path} => #{value}" }
258
+ # The key has been added or updated in the registry
259
+ def changed(key, value, revision)
260
+ logger.debug "Updated: #{key}", value
255
261
 
256
262
  return unless @update_subscribers
257
263
 
258
264
  # Subscribers to specific paths
259
- if subscribers = @update_subscribers[path]
260
- subscribers.each{|subscriber| subscriber.call(path, value)}
265
+ if subscribers = @update_subscribers[key]
266
+ subscribers.each{|subscriber| subscriber.call(key, value, revision)}
261
267
  end
262
268
 
263
269
  # Any subscribers for all events?
264
270
  if all_subscribers = @update_subscribers['*']
265
- all_subscribers.each{|subscriber| subscriber.call(path, value)}
271
+ all_subscribers.each{|subscriber| subscriber.call(key, value, revision)}
266
272
  end
267
273
  end
268
274
 
269
275
  # Existing data has been removed from the registry
270
- def deleted(path)
271
- logger.debug { "Deleted: #{path}" }
276
+ def deleted(key, revision)
277
+ logger.debug { "Deleted: #{key}" }
272
278
 
273
279
  return unless @delete_subscribers
274
280
 
275
281
  # Subscribers to specific paths
276
- if subscribers = @delete_subscribers[path]
277
- subscribers.each{|subscriber| subscriber.call(path)}
282
+ if subscribers = @delete_subscribers[key]
283
+ subscribers.each{|subscriber| subscriber.call(key, revision)}
278
284
  end
279
285
 
280
286
  # Any subscribers for all events?
281
287
  if all_subscribers = @delete_subscribers['*']
282
- all_subscribers.each{|subscriber| subscriber.call(path)}
288
+ all_subscribers.each{|subscriber| subscriber.call(key, revision)}
283
289
  end
284
290
  end
285
291
 
286
292
  # Waits for any updates from Doozer and updates the internal service registry
287
293
  def watch_registry
288
- watch_path = "#{@root_path}/**"
294
+ watch_path = "#{@root}/**"
289
295
  logger.info "Start monitoring #{watch_path}"
290
296
  # This thread must use its own dedicated doozer connection
291
297
  doozer = RubyDoozer::Client.new(@doozer_config)
@@ -299,23 +305,21 @@ module RubyDoozer
299
305
  # Update the current_revision with every change notification
300
306
  @current_revision = node.rev
301
307
 
302
- # Remove the Root path
303
- path = relative_path(node.path)
308
+ # Remove the Root key
309
+ key = relative_key(node.path)
304
310
 
305
311
  case node.flags
306
312
  when 4
307
- changed(path, node.value)
313
+ changed(key, @deserializer.deserialize(node.value), node.rev)
308
314
  when 8
309
- deleted(path)
315
+ deleted(key, node.rev)
310
316
  else
311
317
  logger.error "Unknown flags returned by doozer:#{node.flags}"
312
318
  end
313
319
  end
314
320
  logger.info "Stopping monitoring thread normally"
315
321
 
316
- # #TODO need more exception handling here
317
-
318
- rescue Exception => exc
322
+ rescue ScriptError, NameError, StandardError, Exception => exc
319
323
  logger.error "Exception in monitoring thread", exc
320
324
  ensure
321
325
  doozer.close if doozer
@@ -1,3 +1,3 @@
1
1
  module RubyDoozer #:nodoc
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -62,42 +62,55 @@ class CachedRegistryTest < Test::Unit::TestCase
62
62
  [nil, '*'].each do |monitor_path|
63
63
  context "with monitor_path:#{monitor_path}" do
64
64
  should "callback on create" do
65
+ created_revision = nil
65
66
  created_path = nil
66
67
  created_value = nil
67
- @registry.on_create(monitor_path||'three') do |path, value|
68
+ @registry.on_create(monitor_path||'three') do |path, value, revision|
69
+ created_revision = revision
68
70
  created_path = path
69
71
  created_value = value
70
72
  end
71
73
  @registry['three'] = 'created'
72
74
  # Allow doozer to send back the change
73
- sleep 0.5
75
+ sleep 0.3
74
76
  assert_equal 'three', created_path
75
77
  assert_equal 'created', created_value
78
+ assert_equal true, created_revision > 0
76
79
  end
77
80
 
78
81
  should "callback on update" do
82
+ updated_revision = nil
79
83
  updated_path = nil
80
84
  updated_value = nil
81
- @registry.on_update(monitor_path||'bar') do |path, value|
85
+ @registry.on_update(monitor_path||'bar') do |path, value, revision|
86
+ updated_revision = revision
82
87
  updated_path = path
83
88
  updated_value = value
84
89
  end
90
+ # Allow monitoring thread to start
91
+ sleep 0.1
85
92
  @registry['bar'] = 'updated'
86
93
  # Allow doozer to send back the change
87
- sleep 0.5
94
+ sleep 0.3
88
95
  assert_equal 'bar', updated_path
89
96
  assert_equal 'updated', updated_value
97
+ assert_equal true, updated_revision > 0
90
98
  end
91
99
 
92
100
  should "callback on delete" do
93
101
  deleted_path = nil
94
- @registry.on_delete(monitor_path||'bar') do |path|
102
+ deleted_revision = nil
103
+ @registry.on_delete(monitor_path||'bar') do |path, revision|
95
104
  deleted_path = path
105
+ deleted_revision = revision
96
106
  end
107
+ # Allow monitoring thread to start
108
+ sleep 0.1
97
109
  # Allow doozer to send back the change
98
110
  @registry.delete('bar')
99
- sleep 0.5
111
+ sleep 0.3
100
112
  assert_equal 'bar', deleted_path
113
+ assert_equal true, deleted_revision > 0
101
114
  end
102
115
  end
103
116
  end
@@ -65,9 +65,11 @@ class RegistryTest < Test::Unit::TestCase
65
65
  [nil, '*'].each do |monitor_path|
66
66
  context "with monitor_path:#{monitor_path}" do
67
67
  should "callback on update" do
68
+ updated_revision = nil
68
69
  updated_path = nil
69
70
  updated_value = nil
70
- @registry.on_update(monitor_path||'bar') do |path, value|
71
+ @registry.on_update(monitor_path||'bar') do |path, value, revision|
72
+ updated_revision = revision
71
73
  updated_path = path
72
74
  updated_value = value
73
75
  end
@@ -78,12 +80,15 @@ class RegistryTest < Test::Unit::TestCase
78
80
  sleep 0.3
79
81
  assert_equal 'bar', updated_path
80
82
  assert_equal 'updated', updated_value
83
+ assert_equal true, updated_revision > 0
81
84
  end
82
85
 
83
86
  should "callback on delete" do
84
87
  deleted_path = nil
85
- @registry.on_delete(monitor_path||'bar') do |path|
88
+ deleted_revision = nil
89
+ @registry.on_delete(monitor_path||'bar') do |path, revision|
86
90
  deleted_path = path
91
+ deleted_revision = revision
87
92
  end
88
93
  # Allow monitoring thread to start
89
94
  sleep 0.1
@@ -91,6 +96,7 @@ class RegistryTest < Test::Unit::TestCase
91
96
  @registry.delete('bar')
92
97
  sleep 0.3
93
98
  assert_equal 'bar', deleted_path
99
+ assert_equal true, deleted_revision > 0
94
100
  end
95
101
  end
96
102
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_doozer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-04-03 00:00:00.000000000 Z
11
+ date: 2013-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: semantic_logger
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: 1.0.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: multi_json
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: 1.6.1
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: 1.6.1
83
97
  description: Ruby Client for doozer
84
98
  email:
85
99
  - reidmo@gmail.com
@@ -96,6 +110,8 @@ files:
96
110
  - lib/ruby_doozer/cached_registry.rb
97
111
  - lib/ruby_doozer/client.rb
98
112
  - lib/ruby_doozer/exceptions.rb
113
+ - lib/ruby_doozer/json/deserializer.rb
114
+ - lib/ruby_doozer/json/serializer.rb
99
115
  - lib/ruby_doozer/msg.pb.rb
100
116
  - lib/ruby_doozer/registry.rb
101
117
  - lib/ruby_doozer/version.rb