zookeeper 1.2.4-java → 1.2.5-java
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.
- data/CHANGELOG +21 -0
 - data/ext/c_zookeeper.rb +4 -6
 - data/ext/extconf.rb +7 -0
 - data/ext/zkrb.c +0 -9
 - data/ext/zkrb_wrapper_compat.c +3 -3
 - data/ext/zookeeper_base.rb +15 -9
 - data/lib/zookeeper/continuation.rb +24 -3
 - data/lib/zookeeper/exceptions.rb +4 -0
 - data/lib/zookeeper/version.rb +1 -1
 - metadata +4 -4
 
    
        data/CHANGELOG
    CHANGED
    
    | 
         @@ -1,3 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            v1.2.5 cleanup locking in ZookeeperBase
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              * There were several situations where we would hold the lock before calling
         
     | 
| 
      
 4 
     | 
    
         
            +
                a method on CZookeeper (inquisitors and #create in particular). This
         
     | 
| 
      
 5 
     | 
    
         
            +
                exposed us to deadlocks in situations where an async event would be
         
     | 
| 
      
 6 
     | 
    
         
            +
                delivered (probably a SESSION_EXPIRED event), but the callback block could
         
     | 
| 
      
 7 
     | 
    
         
            +
                not be called because the dispatch thread would block on the mutex being
         
     | 
| 
      
 8 
     | 
    
         
            +
                held by the caller of create. 
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                This version cleans up that usage, and ensures that the only time we hold
         
     | 
| 
      
 11 
     | 
    
         
            +
                the mutex is during startup/shutdown (when the value of @czk may be changing),
         
     | 
| 
      
 12 
     | 
    
         
            +
                and in all other cases we grab the mutex, dereference, and unlock then perform
         
     | 
| 
      
 13 
     | 
    
         
            +
                whatever action on the reference. 
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              * Add a safety net to Continuation (which will soon be called 'Promise' or
         
     | 
| 
      
 16 
     | 
    
         
            +
                'Future' at the request of @eric). If any operation takes more than 30s
         
     | 
| 
      
 17 
     | 
    
         
            +
                an exception will be raised in the calling thread. The session timeout
         
     | 
| 
      
 18 
     | 
    
         
            +
                setting makes it so that no operation should take more than 20s, so we know
         
     | 
| 
      
 19 
     | 
    
         
            +
                if we haven't received a reply in *longer* than that, something has gone
         
     | 
| 
      
 20 
     | 
    
         
            +
                awry. 
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
       1 
22 
     | 
    
         
             
            v1.2.4 fix buffer overflow in CZookeeper client_id code
         
     | 
| 
       2 
23 
     | 
    
         | 
| 
       3 
24 
     | 
    
         
             
              * the 'passwd' part of the struct is a char[16], but isn't null terminated.
         
     | 
    
        data/ext/c_zookeeper.rb
    CHANGED
    
    | 
         @@ -176,6 +176,7 @@ class CZookeeper 
     | 
|
| 
       176 
176 
     | 
    
         
             
                return false unless wait_until_running(timeout)
         
     | 
| 
       177 
177 
     | 
    
         | 
| 
       178 
178 
     | 
    
         
             
                @mutex.synchronize do
         
     | 
| 
      
 179 
     | 
    
         
            +
                  # TODO: use deadline here
         
     | 
| 
       179 
180 
     | 
    
         
             
                  @state_cond.wait(timeout) unless (@state == ZOO_CONNECTED_STATE)
         
     | 
| 
       180 
181 
     | 
    
         
             
                end
         
     | 
| 
       181 
182 
     | 
    
         | 
| 
         @@ -191,15 +192,12 @@ class CZookeeper 
     | 
|
| 
       191 
192 
     | 
    
         
             
                  end
         
     | 
| 
       192 
193 
     | 
    
         | 
| 
       193 
194 
     | 
    
         
             
                  cnt = Continuation.new(meth, *args)
         
     | 
| 
       194 
     | 
    
         
            -
                  @reg. 
     | 
| 
       195 
     | 
    
         
            -
                  begin
         
     | 
| 
      
 195 
     | 
    
         
            +
                  @reg.synchronize do |r|
         
     | 
| 
       196 
196 
     | 
    
         
             
                    if meth == :state
         
     | 
| 
       197 
     | 
    
         
            -
                       
     | 
| 
      
 197 
     | 
    
         
            +
                      r.state_check << cnt
         
     | 
| 
       198 
198 
     | 
    
         
             
                    else
         
     | 
| 
       199 
     | 
    
         
            -
                       
     | 
| 
      
 199 
     | 
    
         
            +
                      r.pending << cnt
         
     | 
| 
       200 
200 
     | 
    
         
             
                    end
         
     | 
| 
       201 
     | 
    
         
            -
                  ensure
         
     | 
| 
       202 
     | 
    
         
            -
                    @reg.unlock rescue nil
         
     | 
| 
       203 
201 
     | 
    
         
             
                  end
         
     | 
| 
       204 
202 
     | 
    
         
             
                  wake_event_loop!
         
     | 
| 
       205 
203 
     | 
    
         
             
                  cnt.value
         
     | 
    
        data/ext/extconf.rb
    CHANGED
    
    | 
         @@ -42,6 +42,11 @@ $LDFLAGS = "#{$libraries} #{$LDFLAGS}" 
     | 
|
| 
       42 
42 
     | 
    
         
             
            $LIBPATH = ["#{HERE}/lib"]
         
     | 
| 
       43 
43 
     | 
    
         
             
            $DEFLIBPATH = []
         
     | 
| 
       44 
44 
     | 
    
         | 
| 
      
 45 
     | 
    
         
            +
            # fix for rbenv?
         
     | 
| 
      
 46 
     | 
    
         
            +
            if $LIBRUBYARG == ''
         
     | 
| 
      
 47 
     | 
    
         
            +
              $LIBRUBYARG = RbConfig::CONFIG['LIBRUBYARG']
         
     | 
| 
      
 48 
     | 
    
         
            +
            end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
       45 
50 
     | 
    
         
             
            def safe_sh(cmd)
         
     | 
| 
       46 
51 
     | 
    
         
             
              puts cmd
         
     | 
| 
       47 
52 
     | 
    
         
             
              system(cmd)
         
     | 
| 
         @@ -87,6 +92,8 @@ Dir.chdir("#{HERE}/lib") do 
     | 
|
| 
       87 
92 
     | 
    
         
             
            end
         
     | 
| 
       88 
93 
     | 
    
         
             
            $LIBS << " -lzookeeper_st_gem"
         
     | 
| 
       89 
94 
     | 
    
         | 
| 
      
 95 
     | 
    
         
            +
            have_func('rb_thread_blocking_region')
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
       90 
97 
     | 
    
         
             
            $CFLAGS << ' -Wall' if ZK_DEV
         
     | 
| 
       91 
98 
     | 
    
         
             
            create_makefile 'zookeeper_c'
         
     | 
| 
       92 
99 
     | 
    
         | 
    
        data/ext/zkrb.c
    CHANGED
    
    | 
         @@ -824,7 +824,6 @@ static VALUE method_zkrb_iterate_event_loop(VALUE self) { 
     | 
|
| 
       824 
824 
     | 
    
         
             
              return INT2FIX(rc);
         
     | 
| 
       825 
825 
     | 
    
         
             
            }
         
     | 
| 
       826 
826 
     | 
    
         | 
| 
       827 
     | 
    
         
            -
             
     | 
| 
       828 
827 
     | 
    
         
             
            static VALUE method_has_events(VALUE self) {
         
     | 
| 
       829 
828 
     | 
    
         
             
              VALUE rb_event;
         
     | 
| 
       830 
829 
     | 
    
         
             
              FETCH_DATA_PTR(self, zk);
         
     | 
| 
         @@ -882,16 +881,8 @@ static VALUE method_recv_timeout(VALUE self) { 
     | 
|
| 
       882 
881 
     | 
    
         
             
            // returns a CZookeeper::ClientId object with the values set for session_id and passwd
         
     | 
| 
       883 
882 
     | 
    
         
             
            static VALUE method_client_id(VALUE self) {
         
     | 
| 
       884 
883 
     | 
    
         
             
              FETCH_DATA_PTR(self, zk);
         
     | 
| 
       885 
     | 
    
         
            -
              char buf[32];
         
     | 
| 
       886 
884 
     | 
    
         
             
              const clientid_t *cid = zoo_client_id(zk->zh);
         
     | 
| 
       887 
885 
     | 
    
         | 
| 
       888 
     | 
    
         
            -
            /*  if (strlen(cid->passwd) != 16) { */
         
     | 
| 
       889 
     | 
    
         
            -
            /*    zkrb_debug("passwd is not null-terminated");*/
         
     | 
| 
       890 
     | 
    
         
            -
            /*  } else {*/
         
     | 
| 
       891 
     | 
    
         
            -
            /*    hexbufify(buf, cid->passwd, 16);*/
         
     | 
| 
       892 
     | 
    
         
            -
            /*    zkrb_debug("password in hex is: %s", buf);*/
         
     | 
| 
       893 
     | 
    
         
            -
            /*  }*/
         
     | 
| 
       894 
     | 
    
         
            -
             
     | 
| 
       895 
886 
     | 
    
         
             
              VALUE session_id = LL2NUM(cid->client_id);
         
     | 
| 
       896 
887 
     | 
    
         
             
              VALUE passwd = rb_str_new(cid->passwd, 16);
         
     | 
| 
       897 
888 
     | 
    
         | 
    
        data/ext/zkrb_wrapper_compat.c
    CHANGED
    
    | 
         @@ -4,10 +4,10 @@ 
     | 
|
| 
       4 
4 
     | 
    
         | 
| 
       5 
5 
     | 
    
         
             
            VALUE zkrb_thread_blocking_region(zkrb_blocking_function_t *func, void *data1) {
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
            #ifdef  
     | 
| 
       8 
     | 
    
         
            -
              return func(data1);
         
     | 
| 
       9 
     | 
    
         
            -
            #else
         
     | 
| 
      
 7 
     | 
    
         
            +
            #ifdef HAVE_RB_THREAD_BLOCKING_REGION
         
     | 
| 
       10 
8 
     | 
    
         
             
              return rb_thread_blocking_region((rb_blocking_function_t *)func, data1, RUBY_UBF_IO, 0);
         
     | 
| 
      
 9 
     | 
    
         
            +
            #else
         
     | 
| 
      
 10 
     | 
    
         
            +
              return func(data1);
         
     | 
| 
       11 
11 
     | 
    
         
             
            #endif
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
            }
         
     | 
    
        data/ext/zookeeper_base.rb
    CHANGED
    
    | 
         @@ -31,17 +31,15 @@ class ZookeeperBase 
     | 
|
| 
       31 
31 
     | 
    
         
             
              ZOO_LOG_LEVEL_DEBUG  = 4
         
     | 
| 
       32 
32 
     | 
    
         | 
| 
       33 
33 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
              def_delegators  
     | 
| 
      
 34 
     | 
    
         
            +
              def_delegators :czk, :get_children, :exists, :delete, :get, :set,
         
     | 
| 
       35 
35 
     | 
    
         
             
                :set_acl, :get_acl, :client_id, :sync, :wait_until_connected
         
     | 
| 
       36 
36 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
              # some state methods need to be more paranoid about locking to ensure the correct
         
     | 
| 
       38 
     | 
    
         
            -
              # state is returned
         
     | 
| 
       39 
     | 
    
         
            -
              # 
         
     | 
| 
       40 
37 
     | 
    
         
             
              def self.threadsafe_inquisitor(*syms)
         
     | 
| 
       41 
38 
     | 
    
         
             
                syms.each do |sym|
         
     | 
| 
       42 
39 
     | 
    
         
             
                  class_eval(<<-EOM, __FILE__, __LINE__+1)
         
     | 
| 
       43 
40 
     | 
    
         
             
                    def #{sym}
         
     | 
| 
       44 
     | 
    
         
            -
                       
     | 
| 
      
 41 
     | 
    
         
            +
                      c = @mutex.synchronize { @czk }
         
     | 
| 
      
 42 
     | 
    
         
            +
                      false|(c && c.#{sym})
         
     | 
| 
       45 
43 
     | 
    
         
             
                    end
         
     | 
| 
       46 
44 
     | 
    
         
             
                  EOM
         
     | 
| 
       47 
45 
     | 
    
         
             
                end
         
     | 
| 
         @@ -117,7 +115,7 @@ class ZookeeperBase 
     | 
|
| 
       117 
115 
     | 
    
         
             
              # if either of these happen, the user will need to renegotiate a connection via reopen
         
     | 
| 
       118 
116 
     | 
    
         
             
              def assert_open
         
     | 
| 
       119 
117 
     | 
    
         
             
                @mutex.synchronize do
         
     | 
| 
       120 
     | 
    
         
            -
                  raise Exceptions::NotConnected if closed?
         
     | 
| 
      
 118 
     | 
    
         
            +
                  raise Exceptions::NotConnected if !@czk or @czk.closed?
         
     | 
| 
       121 
119 
     | 
    
         
             
                  if forked?
         
     | 
| 
       122 
120 
     | 
    
         
             
                    raise InheritedConnectionError, <<-EOS.gsub(/(?:^|\n)\s*/, ' ').strip
         
     | 
| 
       123 
121 
     | 
    
         
             
                      You tried to use a connection inherited from another process 
         
     | 
| 
         @@ -152,7 +150,7 @@ class ZookeeperBase 
     | 
|
| 
       152 
150 
     | 
    
         
             
              # is pretty damn annoying. this is used to clean things up.
         
     | 
| 
       153 
151 
     | 
    
         
             
              def create(*args)
         
     | 
| 
       154 
152 
     | 
    
         
             
                # since we don't care about the inputs, just glob args
         
     | 
| 
       155 
     | 
    
         
            -
                rc, new_path =  
     | 
| 
      
 153 
     | 
    
         
            +
                rc, new_path = czk.create(*args)
         
     | 
| 
       156 
154 
     | 
    
         
             
                [rc, strip_chroot_from(new_path)]
         
     | 
| 
       157 
155 
     | 
    
         
             
              end
         
     | 
| 
       158 
156 
     | 
    
         | 
| 
         @@ -173,7 +171,7 @@ class ZookeeperBase 
     | 
|
| 
       173 
171 
     | 
    
         | 
| 
       174 
172 
     | 
    
         
             
              def state
         
     | 
| 
       175 
173 
     | 
    
         
             
                return ZOO_CLOSED_STATE if closed?
         
     | 
| 
       176 
     | 
    
         
            -
                 
     | 
| 
      
 174 
     | 
    
         
            +
                czk.state
         
     | 
| 
       177 
175 
     | 
    
         
             
              end
         
     | 
| 
       178 
176 
     | 
    
         | 
| 
       179 
177 
     | 
    
         
             
              def session_id
         
     | 
| 
         @@ -190,7 +188,9 @@ class ZookeeperBase 
     | 
|
| 
       190 
188 
     | 
    
         | 
| 
       191 
189 
     | 
    
         
             
              # we are closed if there is no @czk instance or @czk.closed?
         
     | 
| 
       192 
190 
     | 
    
         
             
              def closed?
         
     | 
| 
       193 
     | 
    
         
            -
                 
     | 
| 
      
 191 
     | 
    
         
            +
                czk.closed?
         
     | 
| 
      
 192 
     | 
    
         
            +
              rescue Exceptions::NotConnected
         
     | 
| 
      
 193 
     | 
    
         
            +
                true
         
     | 
| 
       194 
194 
     | 
    
         
             
              end
         
     | 
| 
       195 
195 
     | 
    
         | 
| 
       196 
196 
     | 
    
         
             
              def pause_before_fork_in_parent
         
     | 
| 
         @@ -243,6 +243,12 @@ protected 
     | 
|
| 
       243 
243 
     | 
    
         
             
                super(req_id, meth_name, call_opts)
         
     | 
| 
       244 
244 
     | 
    
         
             
              end
         
     | 
| 
       245 
245 
     | 
    
         | 
| 
      
 246 
     | 
    
         
            +
              def czk
         
     | 
| 
      
 247 
     | 
    
         
            +
                rval = @mutex.synchronize { @czk }
         
     | 
| 
      
 248 
     | 
    
         
            +
                raise Exceptions::NotConnected unless rval
         
     | 
| 
      
 249 
     | 
    
         
            +
                rval
         
     | 
| 
      
 250 
     | 
    
         
            +
              end
         
     | 
| 
      
 251 
     | 
    
         
            +
             
     | 
| 
       246 
252 
     | 
    
         
             
              # if we're chrooted, this method will strip the chroot prefix from +path+
         
     | 
| 
       247 
253 
     | 
    
         
             
              def strip_chroot_from(path)
         
     | 
| 
       248 
254 
     | 
    
         
             
                return path unless (chrooted? and path and path.start_with?(chroot_path))
         
     | 
| 
         @@ -6,6 +6,8 @@ module Zookeeper 
     | 
|
| 
       6 
6 
     | 
    
         
             
                include Constants
         
     | 
| 
       7 
7 
     | 
    
         
             
                include Logger
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
      
 9 
     | 
    
         
            +
                OPERATION_TIMEOUT = 30 # seconds
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
       9 
11 
     | 
    
         
             
                # for keeping track of which continuations are pending, and which ones have
         
     | 
| 
       10 
12 
     | 
    
         
             
                # been submitted and are awaiting a repsonse
         
     | 
| 
       11 
13 
     | 
    
         
             
                # 
         
     | 
| 
         @@ -79,8 +81,8 @@ module Zookeeper 
     | 
|
| 
       79 
81 
     | 
    
         
             
                def initialize(meth, *args)
         
     | 
| 
       80 
82 
     | 
    
         
             
                  @meth   = meth
         
     | 
| 
       81 
83 
     | 
    
         
             
                  @args   = args
         
     | 
| 
       82 
     | 
    
         
            -
                  @mutex  =  
     | 
| 
       83 
     | 
    
         
            -
                  @cond   =  
     | 
| 
      
 84 
     | 
    
         
            +
                  @mutex  = Monitor.new
         
     | 
| 
      
 85 
     | 
    
         
            +
                  @cond   = @mutex.new_cond
         
     | 
| 
       84 
86 
     | 
    
         
             
                  @rval   = nil
         
     | 
| 
       85 
87 
     | 
    
         | 
| 
       86 
88 
     | 
    
         
             
                  # make this error reporting more robust if necessary, right now, just set to state
         
     | 
| 
         @@ -88,9 +90,28 @@ module Zookeeper 
     | 
|
| 
       88 
90 
     | 
    
         
             
                end
         
     | 
| 
       89 
91 
     | 
    
         | 
| 
       90 
92 
     | 
    
         
             
                # the caller calls this method and receives the response from the async loop
         
     | 
| 
      
 93 
     | 
    
         
            +
                # this method has a hard-coded 30 second timeout as a safety feature. No
         
     | 
| 
      
 94 
     | 
    
         
            +
                # call should take more than 20s (as the session timeout is set to 20s)
         
     | 
| 
      
 95 
     | 
    
         
            +
                # so if any call takes longer than that, something has gone horribly wrong.
         
     | 
| 
      
 96 
     | 
    
         
            +
                #
         
     | 
| 
      
 97 
     | 
    
         
            +
                # @raise [ContinuationTimeoutError] if a response is not received within 30s
         
     | 
| 
      
 98 
     | 
    
         
            +
                #
         
     | 
| 
       91 
99 
     | 
    
         
             
                def value
         
     | 
| 
      
 100 
     | 
    
         
            +
                  time_to_stop = Time.now + OPERATION_TIMEOUT
         
     | 
| 
      
 101 
     | 
    
         
            +
                  now = nil
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
       92 
103 
     | 
    
         
             
                  @mutex.synchronize do
         
     | 
| 
       93 
     | 
    
         
            -
                     
     | 
| 
      
 104 
     | 
    
         
            +
                    while true
         
     | 
| 
      
 105 
     | 
    
         
            +
                      now = Time.now
         
     | 
| 
      
 106 
     | 
    
         
            +
                      break if @rval or @error or (now > time_to_stop)
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                      deadline = time_to_stop.to_f - now.to_f
         
     | 
| 
      
 109 
     | 
    
         
            +
                      @cond.wait(deadline)
         
     | 
| 
      
 110 
     | 
    
         
            +
                    end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                    if now > time_to_stop
         
     | 
| 
      
 113 
     | 
    
         
            +
                      raise ContinuationTimeoutError, "response for meth: #{meth.inspect}, args: #{args.inspect}, not received within #{OPERATION_TIMEOUT} seconds"
         
     | 
| 
      
 114 
     | 
    
         
            +
                    end
         
     | 
| 
       94 
115 
     | 
    
         | 
| 
       95 
116 
     | 
    
         
             
                    case @error
         
     | 
| 
       96 
117 
     | 
    
         
             
                    when nil
         
     | 
    
        data/lib/zookeeper/exceptions.rb
    CHANGED
    
    | 
         @@ -84,6 +84,10 @@ stacktrace: 
     | 
|
| 
       84 
84 
     | 
    
         
             
              # maybe use this for continuation
         
     | 
| 
       85 
85 
     | 
    
         
             
              class InterruptedException  < ZookeeperException ; end
         
     | 
| 
       86 
86 
     | 
    
         | 
| 
      
 87 
     | 
    
         
            +
              # raised when a continuation operation takes more time than is reasonable and
         
     | 
| 
      
 88 
     | 
    
         
            +
              # the thread should be awoken. (i.e. prevents a call that never returns)
         
     | 
| 
      
 89 
     | 
    
         
            +
              class ContinuationTimeoutError < ZookeeperException; end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
       87 
91 
     | 
    
         
             
              # raised when the user tries to use a connection after a fork()
         
     | 
| 
       88 
92 
     | 
    
         
             
              # without calling reopen() in the C client
         
     | 
| 
       89 
93 
     | 
    
         
             
              #
         
     | 
    
        data/lib/zookeeper/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,13 +1,13 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification 
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: zookeeper
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version 
         
     | 
| 
       4 
     | 
    
         
            -
              hash:  
     | 
| 
      
 4 
     | 
    
         
            +
              hash: 21
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: 
         
     | 
| 
       6 
6 
     | 
    
         
             
              segments: 
         
     | 
| 
       7 
7 
     | 
    
         
             
              - 1
         
     | 
| 
       8 
8 
     | 
    
         
             
              - 2
         
     | 
| 
       9 
     | 
    
         
            -
              -  
     | 
| 
       10 
     | 
    
         
            -
              version: 1.2. 
     | 
| 
      
 9 
     | 
    
         
            +
              - 5
         
     | 
| 
      
 10 
     | 
    
         
            +
              version: 1.2.5
         
     | 
| 
       11 
11 
     | 
    
         
             
            platform: java
         
     | 
| 
       12 
12 
     | 
    
         
             
            authors: 
         
     | 
| 
       13 
13 
     | 
    
         
             
            - Phillip Pearson
         
     | 
| 
         @@ -20,7 +20,7 @@ autorequire: 
     | 
|
| 
       20 
20 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       21 
21 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       22 
22 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
            date: 2012- 
     | 
| 
      
 23 
     | 
    
         
            +
            date: 2012-06-03 00:00:00 Z
         
     | 
| 
       24 
24 
     | 
    
         
             
            dependencies: 
         
     | 
| 
       25 
25 
     | 
    
         
             
            - !ruby/object:Gem::Dependency 
         
     | 
| 
       26 
26 
     | 
    
         
             
              name: backports
         
     |