ruby_doozer 0.6.0 → 0.7.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: 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