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 +4 -4
 - data/Rakefile +1 -0
 - data/lib/ruby_doozer.rb +4 -0
 - data/lib/ruby_doozer/cached_registry.rb +33 -28
 - data/lib/ruby_doozer/json/deserializer.rb +62 -0
 - data/lib/ruby_doozer/json/serializer.rb +53 -0
 - data/lib/ruby_doozer/registry.rb +80 -76
 - data/lib/ruby_doozer/version.rb +1 -1
 - data/test/cached_registry_test.rb +19 -6
 - data/test/registry_test.rb +8 -2
 - metadata +18 -2
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: bb1a71fd888931d010aeffdf2a732c921672a28d
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: e31970bb09b093c59ee6e221dd302c4ce1a00d81
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: a8a41f827035cf8a419c4eaa3f95965d6aa390660d6d0af404bd3971bbb7ffaaa0203ffd2bb5ad9e0ee770b9247d3c1425a5faebfe16e2279a63c55b7db46e81
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 24666f05f96fda73696d672ff0d4b1a83b27d0e4ab5dca2248eb0bf3ea50aa2ee7dac854d446dccf1cc792c736231597fe4f4cb81ac2b7731484488523c51846
         
     | 
    
        data/Rakefile
    CHANGED
    
    
    
        data/lib/ruby_doozer.rb
    CHANGED
    
    | 
         @@ -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  
     | 
| 
       14 
     | 
    
         
            -
            # is never returned, nor is it required when a  
     | 
| 
      
 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  
     | 
| 
      
 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 
     | 
    
         
            -
                   
     | 
| 
      
 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( 
     | 
| 
       39 
     | 
    
         
            -
                      set_cached_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  
     | 
| 
       48 
     | 
    
         
            -
                def []( 
     | 
| 
       49 
     | 
    
         
            -
                  @cache[ 
     | 
| 
      
 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  
     | 
| 
       63 
     | 
    
         
            -
                def  
     | 
| 
      
 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 
     | 
    
         
            -
                #     
     | 
| 
       75 
     | 
    
         
            -
                #      The relative  
     | 
| 
      
 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 
     | 
    
         
            -
                #     
     | 
| 
       81 
     | 
    
         
            -
                #      The  
     | 
| 
       82 
     | 
    
         
            -
                #      Supplying a  
     | 
| 
      
 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 | 
     | 
| 
       90 
     | 
    
         
            -
                #     puts "#{ 
     | 
| 
      
 94 
     | 
    
         
            +
                #   registry.on_update do |key, value, revision|
         
     | 
| 
      
 95 
     | 
    
         
            +
                #     puts "#{key} was created with #{value}"
         
     | 
| 
       91 
96 
     | 
    
         
             
                #   end
         
     | 
| 
       92 
     | 
    
         
            -
                def on_create( 
     | 
| 
       93 
     | 
    
         
            -
                  ((@create_subscribers ||= ThreadSafe::Hash.new)[ 
     | 
| 
      
 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  
     | 
| 
       117 
     | 
    
         
            -
                def changed( 
     | 
| 
       118 
     | 
    
         
            -
                  previous_value = get_cached_value( 
     | 
| 
      
 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( 
     | 
| 
      
 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  
     | 
| 
      
 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[ 
     | 
| 
       134 
     | 
    
         
            -
                      subscribers.each{|subscriber| subscriber.call( 
     | 
| 
      
 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( 
     | 
| 
      
 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
         
     | 
    
        data/lib/ruby_doozer/registry.rb
    CHANGED
    
    | 
         @@ -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  
     | 
| 
       14 
     | 
    
         
            -
            # is never returned, nor is it required when a  
     | 
| 
       15 
     | 
    
         
            -
            # For example, with a  
     | 
| 
       16 
     | 
    
         
            -
            # out the  
     | 
| 
      
 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, : 
     | 
| 
      
 25 
     | 
    
         
            +
                attr_reader :doozer_config, :doozer_pool, :current_revision, :root
         
     | 
| 
       25 
26 
     | 
    
         | 
| 
       26 
     | 
    
         
            -
                # Create a Registry instance to manage a  
     | 
| 
      
 27 
     | 
    
         
            +
                # Create a Registry instance to manage a information within doozer
         
     | 
| 
       27 
28 
     | 
    
         
             
                #
         
     | 
| 
       28 
     | 
    
         
            -
                # : 
     | 
| 
       29 
     | 
    
         
            -
                #   Root  
     | 
| 
       30 
     | 
    
         
            -
                #   It is not recommended to set the  
     | 
| 
      
 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 
     | 
    
         
            -
                  @ 
     | 
| 
       88 
     | 
    
         
            -
                  raise "Missing mandatory parameter : 
     | 
| 
      
 88 
     | 
    
         
            +
                  @root = params.delete(:root) || params.delete(:root_path)
         
     | 
| 
      
 89 
     | 
    
         
            +
                  raise "Missing mandatory parameter :root" unless @root
         
     | 
| 
       89 
90 
     | 
    
         | 
| 
       90 
     | 
    
         
            -
                  # Add leading '/' to  
     | 
| 
       91 
     | 
    
         
            -
                  @ 
     | 
| 
      
 91 
     | 
    
         
            +
                  # Add leading '/' to root if missing
         
     | 
| 
      
 92 
     | 
    
         
            +
                  @root = "/#{@root}" unless @root.start_with?('/')
         
     | 
| 
       92 
93 
     | 
    
         | 
| 
       93 
94 
     | 
    
         
             
                  # Strip trailing '/' if supplied
         
     | 
| 
       94 
     | 
    
         
            -
                  @ 
     | 
| 
       95 
     | 
    
         
            -
                  @ 
     | 
| 
      
 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 []( 
     | 
| 
       129 
     | 
    
         
            -
                  doozer_pool.with_connection do |doozer|
         
     | 
| 
       130 
     | 
    
         
            -
                    doozer[ 
     | 
| 
      
 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  
     | 
| 
       135 
     | 
    
         
            -
                def []=( 
     | 
| 
      
 140 
     | 
    
         
            +
                # Replace the latest value at a specific key
         
     | 
| 
      
 141 
     | 
    
         
            +
                def []=(key,value)
         
     | 
| 
       136 
142 
     | 
    
         
             
                  doozer_pool.with_connection do |doozer|
         
     | 
| 
       137 
     | 
    
         
            -
                    doozer[ 
     | 
| 
      
 143 
     | 
    
         
            +
                    doozer[full_key(key)] = @serializer.serialize(value)
         
     | 
| 
       138 
144 
     | 
    
         
             
                  end
         
     | 
| 
       139 
145 
     | 
    
         
             
                end
         
     | 
| 
       140 
146 
     | 
    
         | 
| 
       141 
     | 
    
         
            -
                # Delete the value at a specific  
     | 
| 
       142 
     | 
    
         
            -
                def delete( 
     | 
| 
      
 147 
     | 
    
         
            +
                # Delete the value at a specific key
         
     | 
| 
      
 148 
     | 
    
         
            +
                def delete(key)
         
     | 
| 
       143 
149 
     | 
    
         
             
                  doozer_pool.with_connection do |doozer|
         
     | 
| 
       144 
     | 
    
         
            -
                    doozer.delete( 
     | 
| 
      
 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  
     | 
| 
      
 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 
     | 
    
         
            -
                   
     | 
| 
      
 163 
     | 
    
         
            +
                  key = "#{@root}/**"
         
     | 
| 
       158 
164 
     | 
    
         
             
                  doozer_pool.with_connection do |doozer|
         
     | 
| 
       159 
     | 
    
         
            -
                    doozer.walk( 
     | 
| 
       160 
     | 
    
         
            -
                      block.call( 
     | 
| 
      
 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  
     | 
| 
       166 
     | 
    
         
            -
                def  
     | 
| 
       167 
     | 
    
         
            -
                   
     | 
| 
       168 
     | 
    
         
            -
                  each_pair {|k,v|  
     | 
| 
       169 
     | 
    
         
            -
                   
     | 
| 
      
 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 
     | 
    
         
            -
                #     
     | 
| 
       193 
     | 
    
         
            -
                #      The relative  
     | 
| 
      
 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 
     | 
    
         
            -
                #     
     | 
| 
       199 
     | 
    
         
            -
                #      The  
     | 
| 
       200 
     | 
    
         
            -
                #      Supplying a  
     | 
| 
      
 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 | 
     | 
| 
       208 
     | 
    
         
            -
                #     puts "#{ 
     | 
| 
      
 213 
     | 
    
         
            +
                #   registry.on_update do |key, value, revision|
         
     | 
| 
      
 214 
     | 
    
         
            +
                #     puts "#{key} was updated to #{value}"
         
     | 
| 
       209 
215 
     | 
    
         
             
                #   end
         
     | 
| 
       210 
     | 
    
         
            -
                def on_update( 
     | 
| 
      
 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)[ 
     | 
| 
      
 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 
     | 
    
         
            -
                #     
     | 
| 
       219 
     | 
    
         
            -
                #      The relative  
     | 
| 
      
 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 
     | 
    
         
            -
                #     
     | 
| 
       225 
     | 
    
         
            -
                #      The  
     | 
| 
       226 
     | 
    
         
            -
                #      Supplying a  
     | 
| 
      
 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 | 
     | 
| 
       231 
     | 
    
         
            -
                #     puts "#{ 
     | 
| 
      
 236 
     | 
    
         
            +
                #   registry.on_delete do |key, revision|
         
     | 
| 
      
 237 
     | 
    
         
            +
                #     puts "#{key} was deleted"
         
     | 
| 
       232 
238 
     | 
    
         
             
                #   end
         
     | 
| 
       233 
     | 
    
         
            -
                def on_delete( 
     | 
| 
      
 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)[ 
     | 
| 
      
 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  
     | 
| 
       243 
     | 
    
         
            -
                def  
     | 
| 
       244 
     | 
    
         
            -
                  "#{@ 
     | 
| 
      
 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  
     | 
| 
       248 
     | 
    
         
            -
                def  
     | 
| 
       249 
     | 
    
         
            -
                   
     | 
| 
      
 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  
     | 
| 
       253 
     | 
    
         
            -
                def changed( 
     | 
| 
       254 
     | 
    
         
            -
                  logger.debug  
     | 
| 
      
 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[ 
     | 
| 
       260 
     | 
    
         
            -
                    subscribers.each{|subscriber| subscriber.call( 
     | 
| 
      
 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( 
     | 
| 
      
 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( 
     | 
| 
       271 
     | 
    
         
            -
                  logger.debug { "Deleted: #{ 
     | 
| 
      
 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[ 
     | 
| 
       277 
     | 
    
         
            -
                    subscribers.each{|subscriber| subscriber.call( 
     | 
| 
      
 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( 
     | 
| 
      
 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 = "#{@ 
     | 
| 
      
 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  
     | 
| 
       303 
     | 
    
         
            -
                     
     | 
| 
      
 308 
     | 
    
         
            +
                    # Remove the Root key
         
     | 
| 
      
 309 
     | 
    
         
            +
                    key = relative_key(node.path)
         
     | 
| 
       304 
310 
     | 
    
         | 
| 
       305 
311 
     | 
    
         
             
                    case node.flags
         
     | 
| 
       306 
312 
     | 
    
         
             
                    when 4
         
     | 
| 
       307 
     | 
    
         
            -
                      changed( 
     | 
| 
      
 313 
     | 
    
         
            +
                      changed(key,  @deserializer.deserialize(node.value), node.rev)
         
     | 
| 
       308 
314 
     | 
    
         
             
                    when 8
         
     | 
| 
       309 
     | 
    
         
            -
                      deleted( 
     | 
| 
      
 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 
     | 
    
         
            -
                 
     | 
| 
       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
         
     | 
    
        data/lib/ruby_doozer/version.rb
    CHANGED
    
    
| 
         @@ -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. 
     | 
| 
      
 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. 
     | 
| 
      
 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 
     | 
    
         
            -
                         
     | 
| 
      
 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. 
     | 
| 
      
 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
         
     | 
    
        data/test/registry_test.rb
    CHANGED
    
    | 
         @@ -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 
     | 
    
         
            -
                         
     | 
| 
      
 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. 
     | 
| 
      
 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- 
     | 
| 
      
 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
         
     |