zookeeper 1.4.8-java → 1.5.0-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 685552eca5c4354d806942534b167347942cf401f730cfcaf513acb012752d1a
4
+ data.tar.gz: 287a77f92a9b0837f95bfe571b797d48f794c01a823ba26870fe1f748605bbcd
5
+ SHA512:
6
+ metadata.gz: 2ac56db44459c3e4112559679363f99ff391795c38b4fb5fd5be081ebd2debfd505cc11c4e6d34d898caa39a68dfd36519d8d8c6205e7d34d15ba229a3e6ee68
7
+ data.tar.gz: 7d20d7af6bee9fd1d191b6f8094cf6fc59a097469ba2ccc375120f99b5bc5a4175ea6b714f6587da55c31ae5ca2842372a74a85e6c7a9871cd0f910c1355b61c
@@ -0,0 +1,55 @@
1
+ on:
2
+ pull_request:
3
+ branches:
4
+ - master
5
+ push:
6
+ branches:
7
+ - master
8
+
9
+ jobs:
10
+ build:
11
+ name: Ruby ${{ matrix.ruby }} / GCC ${{ matrix.gcc }} / ${{ matrix.os }}
12
+ runs-on: ${{ matrix.os }}
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ os:
17
+ - ubuntu-latest
18
+ - macos-latest
19
+ ruby:
20
+ - 2.5
21
+ - 2.6
22
+ - 2.7
23
+ - 3.0
24
+ - jruby
25
+ gcc:
26
+ - 7
27
+ - latest
28
+ exclude:
29
+ - os: macos-latest
30
+ gcc: 7
31
+
32
+ steps:
33
+ - uses: actions/checkout@v2
34
+ with:
35
+ submodules: recursive
36
+
37
+ - name: Set up GCC
38
+ if: ${{ matrix.gcc != 'latest' }}
39
+ uses: egor-tensin/setup-gcc@v1
40
+ with:
41
+ version: ${{ matrix.gcc }}
42
+ platform: x64
43
+
44
+ - name: Set up Ruby
45
+ uses: ruby/setup-ruby@v1
46
+ with:
47
+ ruby-version: ${{ matrix.ruby }}
48
+ bundler-cache: true
49
+
50
+ - name: Run Tests
51
+ env:
52
+ RAILS_ENV: test
53
+ SPAWN_ZOOKEEPER: true
54
+ run: |
55
+ bundle exec rake
data/CHANGELOG CHANGED
@@ -1,3 +1,24 @@
1
+ v1.5.0
2
+ * (housekeeping) Moves build to Github Actions from TravisCI
3
+ * (housekeeping) Drops build support for MRI Ruby < 2.5 and other rubies
4
+ * Build on Ruby 3 (#99) (h/t: @malmckay)
5
+ * Build on MacOS (#98) (h/t: @malmckay)
6
+ * Work around compiler errors on newer versions of gcc (#97) (h/t: @nickmarden)
7
+ * Fix a typo on a has_key (#83) (h/t: @lexspoon)
8
+ * Adds support macOS dylib (#86) (h/t: @pftg)
9
+ * Fix compilation on ARM (#82) (h/t: @cdonati)
10
+
11
+ v1.4.11
12
+ * backported fix for ZOOKEEPER-2253 by @chchen - #76
13
+
14
+ v1.4.10
15
+
16
+ * fix for ruby 2.2.0 build - #74 (h/t: fbernier)
17
+
18
+ v1.4.9
19
+
20
+ * Fix for build on OS-X 10.10 by @e0en
21
+
1
22
  v1.4.8
2
23
 
3
24
  * Fix deadlock related to state checks that can happen during reconnecting
data/Gemfile CHANGED
@@ -6,7 +6,7 @@ gem 'rake', '~> 0.9.0'
6
6
 
7
7
  group :test do
8
8
  gem "rspec" , "~> 2.11"
9
- gem 'eventmachine', '1.0.0'
9
+ gem 'eventmachine', '1.0.4'
10
10
  gem 'evented-spec', '~> 0.9.0'
11
11
  gem 'zk-server', '~> 1.0', :git => 'https://github.com/zk-ruby/zk-server.git'
12
12
  end
data/README.markdown CHANGED
@@ -1,6 +1,7 @@
1
1
  # zookeeper #
2
2
 
3
- [![Build Status](https://secure.travis-ci.org/zk-ruby/zookeeper.png?branch=master)](http://travis-ci.org/zk-ruby/zookeeper)
3
+ ![Build Status](https://github.com/zk-ruby/zookeeper/actions/workflows/build.yml/badge.svg)
4
+
4
5
 
5
6
  An interface to the Zookeeper cluster coordination server.
6
7
 
@@ -10,14 +11,10 @@ For a higher-level interface with a more convenient API and features such as loc
10
11
 
11
12
  As of 1.1.0, this library is fork-safe (which was not easy to accomplish). This means you can use it without worry in unicorn, resque, and whatever other fork-philic frameworks you sick little monkeys are using this week. The only rule is that after a fork(), you need to call `#reopen` on the client ASAP, because if you try to peform any other action, an exception will be raised. Other than that, there is no special action that is needed in the parent.
12
13
 
13
- ## Big Plans for 1.0 ##
14
-
15
- The 1.0 release will feature a reorganization of the heirarchy. There will be a single top-level `Zookeeper` namespace (as opposed to the current layout, with 5-6 different top-level constants), and for the next several releases, there will be a backwards compatible require for users that still need to use the old names.
16
-
17
14
  ## License
18
15
 
19
- Copyright 2008 Phillip Pearson, and 2010 Twitter, Inc.
20
- Licensed under the MIT License. See the included LICENSE file.
16
+ Copyright 2008 Phillip Pearson, and 2010 Twitter, Inc.
17
+ Licensed under the MIT License. See the included LICENSE file.
21
18
 
22
19
  Portions copyright 2008-2010 the Apache Software Foundation, licensed under the
23
20
  Apache 2 license, and used with permission.
@@ -28,26 +25,6 @@ Portions contributed to the open source community by HPDC, L.P.
28
25
 
29
26
  sudo gem install zookeeper
30
27
 
31
- ### rbenv is awesome
32
-
33
- UPDATE: this appears to have been fixed by @eric in [this patch](http://git.io/PEPgnA). If you use rbenv, please report any issues, but I believe it should work now.
34
-
35
- Let me start out by saying I prefer rvm, and that I really don't know a whole lot about linking on OS X. Or Linux. Any suggestions or constructive insults would be greatly appreciated if you have insight into what i'm doing wrong here.
36
-
37
- So, it seems that [ruby-build][] doesn't use `--enable-shared` by default. I'm told this is for speed.
38
-
39
- If you run into problems with installing this gem (specifically with linking ex. `Undefined symbols for architecture x86_64`) and you're using rbenv, for now you need to ensure that your ruby was built with `--enable-shared`. I'm sorry for the inconvenience. (no, really)
40
-
41
- ```shell
42
- ~ $ CONFIGURE_OPTS='--enable-shared --disable-install-doc' rbenv install 1.9.3-p194
43
- ```
44
-
45
- [ruby-build]: https://github.com/sstephenson/ruby-build
46
-
47
- ### A note for REE users
48
-
49
- The zookeeper client is required to send a heartbeat packet every N seconds to the server. If it misses its deadline 3 times in a row, the session will be lost. The way the client is implemented in versions `>= 1.2`, a *ruby* thread acts as the event thread (this was necessary to provide a fork-safe client with a parent process that is able to preserve state). Some users have reported issues where under load in "massive codebases," they have problems where calls will time out. Given the nature of the thread scheduler in 1.8, one should be careful if upgrading from `0.4.4` to `>= 1.2`.
50
-
51
28
  ## Usage
52
29
 
53
30
  Connect to a server:
@@ -75,7 +52,7 @@ Calls take a dictionary of parameters. With the exception of set\_acl, the only
75
52
 
76
53
  ### A Bit about this repository ###
77
54
 
78
- Twitter's open source office was kind enough to transfer this repository to facilitate development and administration of this repository. The `zookeeper` gem's last three releases were recorded in branches `v0.4.2`, `v0.4.3` and `v0.4.4`. Releases of the `slyphon-zookeeper` gem were cut off of the fork, and unfortunately (due to an oversight on my part) were tagged with unrelated versions. Those were tagged with names `release/0.9.2`.
55
+ Twitter's open source office was kind enough to transfer this repository to facilitate development and administration of this repository. The `zookeeper` gem's last three releases were recorded in branches `v0.4.2`, `v0.4.3` and `v0.4.4`. Releases of the `slyphon-zookeeper` gem were cut off of the fork, and unfortunately (due to an oversight on my part) were tagged with unrelated versions. Those were tagged with names `release/0.9.2`.
79
56
 
80
57
  The plan is to keep the `slyphon-zookeeper` tags, and to tag the `zookeeper` releases `twitter/release/0.4.x`.
81
58
 
data/Rakefile CHANGED
@@ -38,7 +38,7 @@ if File.exists?(release_ops_path)
38
38
 
39
39
  orig_dir = Dir.getwd
40
40
 
41
- cd tmpdir do
41
+ Dir.chdir tmpdir do
42
42
  sh "git co #{tag} && git reset --hard && git clean -fdx"
43
43
 
44
44
  ENV['JAVA_GEM'] = nil
@@ -77,7 +77,7 @@ end
77
77
  VALGRIND_BASIC_OPTS = '--num-callers=50 --error-limit=no --partial-loads-ok=yes --undef-value-errors=no --trace-children=yes'
78
78
 
79
79
  task 'valgrind' do
80
- cd 'ext' do
80
+ Dir.chdir 'ext' do
81
81
  sh "rake clean build"
82
82
  end
83
83
 
@@ -86,7 +86,7 @@ end
86
86
 
87
87
  namespace :build do
88
88
  task :clean do
89
- cd 'ext' do
89
+ Dir.chdir 'ext' do
90
90
  sh 'rake clean'
91
91
  end
92
92
 
@@ -94,7 +94,7 @@ namespace :build do
94
94
  end
95
95
 
96
96
  task :clobber do
97
- cd 'ext' do
97
+ Dir.chdir 'ext' do
98
98
  sh 'rake clobber'
99
99
  end
100
100
 
@@ -104,7 +104,7 @@ end
104
104
 
105
105
  desc "Build C component"
106
106
  task :build do
107
- cd 'ext' do
107
+ Dir.chdir 'ext' do
108
108
  sh "rake"
109
109
  end
110
110
  end
data/ext/c_zookeeper.rb CHANGED
@@ -48,7 +48,7 @@ class CZookeeper
48
48
 
49
49
  # keep track of the pid that created us
50
50
  update_pid!
51
-
51
+
52
52
  # used by the C layer. CZookeeper sets this to true when the init method
53
53
  # has completed. once this is set to true, it stays true.
54
54
  #
@@ -68,7 +68,7 @@ class CZookeeper
68
68
  @_receive_timeout_msec = opts[:receive_timeout_msec] || DEFAULT_RECEIVE_TIMEOUT_MSEC
69
69
 
70
70
  @mutex = Monitor.new
71
-
71
+
72
72
  # used to signal that we're running
73
73
  @running_cond = @mutex.new_cond
74
74
 
@@ -80,7 +80,7 @@ class CZookeeper
80
80
  @state = ZOO_CLOSED_STATE
81
81
 
82
82
  @pipe_read, @pipe_write = IO.pipe
83
-
83
+
84
84
  @event_thread = nil
85
85
 
86
86
  # hash of in-flight Continuation instances
@@ -142,7 +142,7 @@ class CZookeeper
142
142
 
143
143
  nil
144
144
  end
145
-
145
+
146
146
  # call this to stop the event loop, you can resume with the
147
147
  # resume method
148
148
  #
@@ -157,7 +157,7 @@ class CZookeeper
157
157
  def resume_after_fork_in_parent
158
158
  logger.debug { "##{__method__}" }
159
159
 
160
- @mutex.synchronize do
160
+ @mutex.synchronize do
161
161
  @_shutting_down = nil
162
162
  start_event_thread
163
163
  end
@@ -181,7 +181,7 @@ class CZookeeper
181
181
  return false unless wait_until_running(timeout)
182
182
 
183
183
  @state_mutex.synchronize do
184
- while true
184
+ while true
185
185
  if timeout
186
186
  now = Time.now
187
187
  break if (@state == ZOO_CONNECTED_STATE) || unhealthy? || (now > time_to_stop)
@@ -212,7 +212,7 @@ class CZookeeper
212
212
  !unhealthy?
213
213
  end
214
214
 
215
- # submits a job for processing
215
+ # submits a job for processing
216
216
  # blocks the caller until result has returned
217
217
  def submit_and_block(meth, *args)
218
218
  @mutex.synchronize do
@@ -230,9 +230,9 @@ class CZookeeper
230
230
  wake_event_loop!
231
231
  cnt.value
232
232
  end
233
-
233
+
234
234
  # this method is part of the reopen/close code, and is responsible for
235
- # shutting down the dispatch thread.
235
+ # shutting down the dispatch thread.
236
236
  #
237
237
  # this method must be EXTERNALLY SYNCHRONIZED!
238
238
  #
@@ -243,7 +243,7 @@ class CZookeeper
243
243
  logger.debug { "##{__method__}" }
244
244
  shut_down!
245
245
  wake_event_loop!
246
- @event_thread.join
246
+ @event_thread.join
247
247
  @event_thread = nil
248
248
  end
249
249
  end
@@ -259,7 +259,7 @@ class CZookeeper
259
259
  # or until timeout seconds have passed.
260
260
  #
261
261
  # returns true if we're running, false if we timed out
262
- def wait_until_running(timeout=5)
262
+ def wait_until_running(timeout=5)
263
263
  @mutex.synchronize do
264
264
  return true if @_running
265
265
  @running_cond.wait(timeout)
@@ -279,7 +279,7 @@ class CZookeeper
279
279
  submit_pending_calls
280
280
  end
281
281
 
282
- zkrb_iterate_event_loop
282
+ zkrb_iterate_event_loop
283
283
  iterate_event_delivery
284
284
  end
285
285
 
@@ -328,7 +328,7 @@ class CZookeeper
328
328
  end
329
329
 
330
330
  def wake_event_loop!
331
- @pipe_write && @pipe_write.write('1')
331
+ @pipe_write && !@pipe_write.closed? && @pipe_write.write('1')
332
332
  end
333
333
 
334
334
  def iterate_event_delivery
@@ -345,10 +345,10 @@ class CZookeeper
345
345
  end
346
346
  end
347
347
  end
348
-
348
+
349
349
  cntn = @reg.in_flight.delete(hash[:req_id])
350
350
 
351
- if cntn and not cntn.user_callback? # this is one of "our" continuations
351
+ if cntn and not cntn.user_callback? # this is one of "our" continuations
352
352
  cntn.call(hash) # so we handle delivering it
353
353
  next # and skip handing it to the dispatcher
354
354
  end
@@ -374,7 +374,7 @@ class CZookeeper
374
374
  def shut_down!
375
375
  logger.debug { "##{__method__}" }
376
376
 
377
- @mutex.synchronize do
377
+ @mutex.synchronize do
378
378
  @_shutting_down = true
379
379
  # ollie ollie oxen all home free!
380
380
  @running_cond.broadcast
data/ext/extconf.rb CHANGED
@@ -68,7 +68,7 @@ Dir.chdir(HERE) do
68
68
  # clean up stupid apple rsrc fork bullshit
69
69
  FileUtils.rm_f(Dir['**/._*'].select{|p| test(?f, p)})
70
70
 
71
- Dir.chdir(BUNDLE_PATH) do
71
+ Dir.chdir(BUNDLE_PATH) do
72
72
  configure = "./configure --prefix=#{HERE} --with-pic --without-cppunit --disable-dependency-tracking #{$EXTRA_CONF} 2>&1"
73
73
  configure = "env CFLAGS='#{DEBUG_CFLAGS}' #{configure}" if ZK_DEBUG
74
74
 
@@ -84,14 +84,19 @@ end
84
84
  # Absolutely prevent the linker from picking up any other zookeeper_mt
85
85
  Dir.chdir("#{HERE}/lib") do
86
86
  %w[st mt].each do |stmt|
87
- %w[a la].each do |ext|
88
- system("cp -f libzookeeper_#{stmt}.#{ext} libzookeeper_#{stmt}_gem.#{ext}")
87
+ %w[a la dylib].each do |ext|
88
+ origin_lib_name = "libzookeeper_#{stmt}.#{ext}"
89
+ dest_lib_name = "libzookeeper_#{stmt}_gem.#{ext}"
90
+ system("cp -f #{origin_lib_name} #{dest_lib_name}") if File.exists?(origin_lib_name)
89
91
  end
90
92
  end
91
93
  end
92
- $LIBS << " -lzookeeper_st_gem"
94
+
95
+ # -lm must come after lzookeeper_st_gem to ensure proper link
96
+ $LIBS << " -lzookeeper_st_gem -lm"
93
97
 
94
98
  have_func('rb_thread_blocking_region')
99
+ have_func('rb_thread_fd_select')
95
100
 
96
101
  $CFLAGS << ' -Wall' if ZK_DEV
97
102
  create_makefile 'zookeeper_c'
@@ -0,0 +1,11 @@
1
+ --- zkc-3.4.5.orig/c/src/zookeeper.c 2020-08-13 03:04:49.631654715 -0400
2
+ +++ zkc-3.4.5/c/src/zookeeper.c 2020-08-13 03:03:24.983922697 -0400
3
+ @@ -3411,7 +3411,7 @@
4
+
5
+ static const char* format_endpoint_info(const struct sockaddr_storage* ep)
6
+ {
7
+ - static char buf[128];
8
+ + static char buf[128+6];
9
+ char addrstr[128];
10
+ void *inaddr;
11
+ #ifdef WIN32
@@ -0,0 +1,16 @@
1
+ diff -ur zkc-3.4.5-orig/c/src/mt_adaptor.c zkc-3.4.5/c/src/mt_adaptor.c
2
+ --- zkc-3.4.5-orig/c/src/mt_adaptor.c 2012-09-30 10:53:32.000000000 -0700
3
+ +++ zkc-3.4.5/c/src/mt_adaptor.c 2016-09-07 16:55:13.787553837 -0700
4
+ @@ -484,11 +484,7 @@
5
+ {
6
+ #ifndef WIN32
7
+ int32_t result;
8
+ - asm __volatile__(
9
+ - "lock xaddl %0,%1\n"
10
+ - : "=r"(result), "=m"(*(int *)operand)
11
+ - : "0"(incr)
12
+ - : "memory");
13
+ + result = __sync_fetch_and_add(operand, incr);
14
+ return result;
15
+ #else
16
+ volatile int32_t result;
@@ -0,0 +1,163 @@
1
+ diff --git zkc-3.4.5-orig/c/src/zookeeper.c zkc-3.4.5/c/src/zookeeper.c
2
+ index de58c62..2347ff4 100644
3
+ --- zkc-3.4.5-orig/c/src/zookeeper.c
4
+ +++ zkc-3.4.5/c/src/zookeeper.c
5
+ @@ -1167,25 +1167,20 @@ void free_completions(zhandle_t *zh,int callCompletion,int reason)
6
+ zh->outstanding_sync--;
7
+ destroy_completion_entry(cptr);
8
+ } else if (callCompletion) {
9
+ - if(cptr->xid == PING_XID){
10
+ - // Nothing to do with a ping response
11
+ - destroy_completion_entry(cptr);
12
+ - } else {
13
+ - // Fake the response
14
+ - buffer_list_t *bptr;
15
+ - h.xid = cptr->xid;
16
+ - h.zxid = -1;
17
+ - h.err = reason;
18
+ - oa = create_buffer_oarchive();
19
+ - serialize_ReplyHeader(oa, "header", &h);
20
+ - bptr = calloc(sizeof(*bptr), 1);
21
+ - assert(bptr);
22
+ - bptr->len = get_buffer_len(oa);
23
+ - bptr->buffer = get_buffer(oa);
24
+ - close_buffer_oarchive(&oa, 0);
25
+ - cptr->buffer = bptr;
26
+ - queue_completion(&zh->completions_to_process, cptr, 0);
27
+ - }
28
+ + // Fake the response
29
+ + buffer_list_t *bptr;
30
+ + h.xid = cptr->xid;
31
+ + h.zxid = -1;
32
+ + h.err = reason;
33
+ + oa = create_buffer_oarchive();
34
+ + serialize_ReplyHeader(oa, "header", &h);
35
+ + bptr = calloc(sizeof(*bptr), 1);
36
+ + assert(bptr);
37
+ + bptr->len = get_buffer_len(oa);
38
+ + bptr->buffer = get_buffer(oa);
39
+ + close_buffer_oarchive(&oa, 0);
40
+ + cptr->buffer = bptr;
41
+ + queue_completion(&zh->completions_to_process, cptr, 0);
42
+ }
43
+ }
44
+ a_list.completion = NULL;
45
+ @@ -1526,7 +1521,6 @@ static struct timeval get_timeval(int interval)
46
+ rc = serialize_RequestHeader(oa, "header", &h);
47
+ enter_critical(zh);
48
+ gettimeofday(&zh->last_ping, 0);
49
+ - rc = rc < 0 ? rc : add_void_completion(zh, h.xid, 0, 0);
50
+ rc = rc < 0 ? rc : queue_buffer_bytes(&zh->to_send, get_buffer(oa),
51
+ get_buffer_len(oa));
52
+ leave_critical(zh);
53
+ @@ -2063,12 +2057,8 @@ static void deserialize_response(int type, int xid, int failed, int rc, completi
54
+ case COMPLETION_VOID:
55
+ LOG_DEBUG(("Calling COMPLETION_VOID for xid=%#x failed=%d rc=%d",
56
+ cptr->xid, failed, rc));
57
+ - if (xid == PING_XID) {
58
+ - // We want to skip the ping
59
+ - } else {
60
+ - assert(cptr->c.void_result);
61
+ - cptr->c.void_result(rc, cptr->data);
62
+ - }
63
+ + assert(cptr->c.void_result);
64
+ + cptr->c.void_result(rc, cptr->data);
65
+ break;
66
+ case COMPLETION_MULTI:
67
+ LOG_DEBUG(("Calling COMPLETION_MULTI for xid=%#x failed=%d rc=%d",
68
+ @@ -2184,7 +2174,15 @@ int zookeeper_process(zhandle_t *zh, int events)
69
+ // fprintf(stderr, "Got %#x for %#x\n", hdr.zxid, hdr.xid);
70
+ }
71
+
72
+ - if (hdr.xid == WATCHER_EVENT_XID) {
73
+ + if (hdr.xid == PING_XID) {
74
+ + // Ping replies can arrive out-of-order
75
+ + int elapsed = 0;
76
+ + struct timeval now;
77
+ + gettimeofday(&now, 0);
78
+ + elapsed = calculate_interval(&zh->last_ping, &now);
79
+ + LOG_DEBUG(("Got ping response in %d ms", elapsed));
80
+ + free_buffer(bptr);
81
+ + } else if (hdr.xid == WATCHER_EVENT_XID) {
82
+ struct WatcherEvent evt;
83
+ int type = 0;
84
+ char *path = NULL;
85
+ @@ -2250,22 +2248,9 @@ int zookeeper_process(zhandle_t *zh, int events)
86
+ activateWatcher(zh, cptr->watcher, rc);
87
+
88
+ if (cptr->c.void_result != SYNCHRONOUS_MARKER) {
89
+ - if(hdr.xid == PING_XID){
90
+ - int elapsed = 0;
91
+ - struct timeval now;
92
+ - gettimeofday(&now, 0);
93
+ - elapsed = calculate_interval(&zh->last_ping, &now);
94
+ - LOG_DEBUG(("Got ping response in %d ms", elapsed));
95
+ -
96
+ - // Nothing to do with a ping response
97
+ - free_buffer(bptr);
98
+ - destroy_completion_entry(cptr);
99
+ - } else {
100
+ - LOG_DEBUG(("Queueing asynchronous response"));
101
+ -
102
+ - cptr->buffer = bptr;
103
+ - queue_completion(&zh->completions_to_process, cptr, 0);
104
+ - }
105
+ + LOG_DEBUG(("Queueing asynchronous response"));
106
+ + cptr->buffer = bptr;
107
+ + queue_completion(&zh->completions_to_process, cptr, 0);
108
+ } else {
109
+ struct sync_completion
110
+ *sc = (struct sync_completion*)cptr->data;
111
+ diff --git zkc-3.4.5-orig/c/tests/TestOperations.cc zkc-3.4.5/c/tests/TestOperations.cc
112
+ index b0370e9..27d9270 100644
113
+ --- zkc-3.4.5-orig/c/tests/TestOperations.cc
114
+ +++ zkc-3.4.5/c/tests/TestOperations.cc
115
+ @@ -29,6 +29,7 @@ class Zookeeper_operations : public CPPUNIT_NS::TestFixture
116
+ CPPUNIT_TEST_SUITE(Zookeeper_operations);
117
+ #ifndef THREADED
118
+ CPPUNIT_TEST(testPing);
119
+ + CPPUNIT_TEST(testUnsolicitedPing);
120
+ CPPUNIT_TEST(testTimeoutCausedByWatches1);
121
+ CPPUNIT_TEST(testTimeoutCausedByWatches2);
122
+ #else
123
+ @@ -305,6 +306,40 @@ public:
124
+ CPPUNIT_ASSERT_EQUAL(1,zkServer.pingCount_);
125
+ }
126
+
127
+ + // ZOOKEEPER-2253: Permit unsolicited pings
128
+ + void testUnsolicitedPing()
129
+ + {
130
+ + const int TIMEOUT=9; // timeout in secs
131
+ + Mock_gettimeofday timeMock;
132
+ + PingCountingServer zkServer;
133
+ + // must call zookeeper_close() while all the mocks are in scope
134
+ + CloseFinally guard(&zh);
135
+ +
136
+ + // receive timeout is in milliseconds
137
+ + zh=zookeeper_init("localhost:1234",watcher,TIMEOUT*1000,TEST_CLIENT_ID,0,0);
138
+ + CPPUNIT_ASSERT(zh!=0);
139
+ + // simulate connected state
140
+ + forceConnected(zh);
141
+ +
142
+ + int fd=0;
143
+ + int interest=0;
144
+ + timeval tv;
145
+ +
146
+ + int rc=zookeeper_interest(zh,&fd,&interest,&tv);
147
+ + CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
148
+ +
149
+ + // verify no ping sent
150
+ + CPPUNIT_ASSERT(zkServer.pingCount_==0);
151
+ +
152
+ + // we're going to receive a unsolicited PING response; ensure
153
+ + // that the client has updated its last_recv timestamp
154
+ + timeMock.tick(tv);
155
+ + zkServer.addRecvResponse(new PingResponse);
156
+ + rc=zookeeper_process(zh,interest);
157
+ + CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
158
+ + CPPUNIT_ASSERT(timeMock==zh->last_recv);
159
+ + }
160
+ +
161
+ // simulate a watch arriving right before a ping is due
162
+ // assert the ping is sent nevertheless
163
+ void testTimeoutCausedByWatches1()
@@ -0,0 +1,102 @@
1
+ diff -ur zkc-3.4.5-orig/c/include/recordio.h zkc-3.4.5/c/include/recordio.h
2
+ --- zkc-3.4.5-orig/c/include/recordio.h 2012-09-30 13:53:32.000000000 -0400
3
+ +++ zkc-3.4.5/c/include/recordio.h 2014-07-29 03:13:27.000000000 -0400
4
+ @@ -73,7 +73,7 @@
5
+ char *get_buffer(struct oarchive *);
6
+ int get_buffer_len(struct oarchive *);
7
+
8
+ -int64_t htonll(int64_t v);
9
+ +int64_t zk_htonll(int64_t v);
10
+
11
+ #ifdef __cplusplus
12
+ }
13
+ diff -ur zkc-3.4.5-orig/c/src/recordio.c zkc-3.4.5/c/src/recordio.c
14
+ --- zkc-3.4.5-orig/c/src/recordio.c 2012-09-30 13:53:32.000000000 -0400
15
+ +++ zkc-3.4.5/c/src/recordio.c 2014-07-29 03:13:35.000000000 -0400
16
+ @@ -80,7 +80,7 @@
17
+ priv->off+=sizeof(i);
18
+ return 0;
19
+ }
20
+ -int64_t htonll(int64_t v)
21
+ +int64_t zk_htonll(int64_t v)
22
+ {
23
+ int i = 0;
24
+ char *s = (char *)&v;
25
+ @@ -98,7 +98,7 @@
26
+
27
+ int oa_serialize_long(struct oarchive *oa, const char *tag, const int64_t *d)
28
+ {
29
+ - const int64_t i = htonll(*d);
30
+ + const int64_t i = zk_htonll(*d);
31
+ struct buff_struct *priv = oa->priv;
32
+ if ((priv->len - priv->off) < sizeof(i)) {
33
+ int rc = resize_buffer(priv, priv->len + sizeof(i));
34
+ @@ -207,7 +207,7 @@
35
+ }
36
+ memcpy(count, priv->buffer+priv->off, sizeof(*count));
37
+ priv->off+=sizeof(*count);
38
+ - v = htonll(*count); // htonll and ntohll do the same
39
+ + v = zk_htonll(*count); // zk_htonll and ntohll do the same
40
+ *count = v;
41
+ return 0;
42
+ }
43
+ diff -ur zkc-3.4.5-orig/c/src/zookeeper.c zkc-3.4.5/c/src/zookeeper.c
44
+ --- zkc-3.4.5-orig/c/src/zookeeper.c 2012-09-30 13:53:32.000000000 -0400
45
+ +++ zkc-3.4.5/c/src/zookeeper.c 2014-07-29 03:13:45.000000000 -0400
46
+ @@ -1408,7 +1408,7 @@
47
+ memcpy(buffer + offset, &req->protocolVersion, sizeof(req->protocolVersion));
48
+ offset = offset + sizeof(req->protocolVersion);
49
+
50
+ - req->lastZxidSeen = htonll(req->lastZxidSeen);
51
+ + req->lastZxidSeen = zk_htonll(req->lastZxidSeen);
52
+ memcpy(buffer + offset, &req->lastZxidSeen, sizeof(req->lastZxidSeen));
53
+ offset = offset + sizeof(req->lastZxidSeen);
54
+
55
+ @@ -1416,7 +1416,7 @@
56
+ memcpy(buffer + offset, &req->timeOut, sizeof(req->timeOut));
57
+ offset = offset + sizeof(req->timeOut);
58
+
59
+ - req->sessionId = htonll(req->sessionId);
60
+ + req->sessionId = zk_htonll(req->sessionId);
61
+ memcpy(buffer + offset, &req->sessionId, sizeof(req->sessionId));
62
+ offset = offset + sizeof(req->sessionId);
63
+
64
+ @@ -1447,7 +1447,7 @@
65
+ memcpy(&req->sessionId, buffer + offset, sizeof(req->sessionId));
66
+ offset = offset + sizeof(req->sessionId);
67
+
68
+ - req->sessionId = htonll(req->sessionId);
69
+ + req->sessionId = zk_htonll(req->sessionId);
70
+ memcpy(&req->passwd_len, buffer + offset, sizeof(req->passwd_len));
71
+ offset = offset + sizeof(req->passwd_len);
72
+
73
+ diff -ur zkc-3.4.5-orig/c/tests/ZKMocks.cc zkc-3.4.5/c/tests/ZKMocks.cc
74
+ --- zkc-3.4.5-orig/c/tests/ZKMocks.cc 2012-09-30 13:53:32.000000000 -0400
75
+ +++ zkc-3.4.5/c/tests/ZKMocks.cc 2014-07-29 03:13:59.000000000 -0400
76
+ @@ -41,7 +41,7 @@
77
+ int offset=sizeof(req->protocolVersion);
78
+
79
+ memcpy(&req->lastZxidSeen,buf.data()+offset,sizeof(req->lastZxidSeen));
80
+ - req->lastZxidSeen = htonll(req->lastZxidSeen);
81
+ + req->lastZxidSeen = zk_htonll(req->lastZxidSeen);
82
+ offset+=sizeof(req->lastZxidSeen);
83
+
84
+ memcpy(&req->timeOut,buf.data()+offset,sizeof(req->timeOut));
85
+ @@ -49,7 +49,7 @@
86
+ offset+=sizeof(req->timeOut);
87
+
88
+ memcpy(&req->sessionId,buf.data()+offset,sizeof(req->sessionId));
89
+ - req->sessionId = htonll(req->sessionId);
90
+ + req->sessionId = zk_htonll(req->sessionId);
91
+ offset+=sizeof(req->sessionId);
92
+
93
+ memcpy(&req->passwd_len,buf.data()+offset,sizeof(req->passwd_len));
94
+ @@ -322,7 +322,7 @@
95
+ buf.append((char*)&tmp,sizeof(tmp));
96
+ tmp=htonl(timeOut);
97
+ buf.append((char*)&tmp,sizeof(tmp));
98
+ - int64_t tmp64=htonll(sessionId);
99
+ + int64_t tmp64=zk_htonll(sessionId);
100
+ buf.append((char*)&tmp64,sizeof(sessionId));
101
+ tmp=htonl(passwd_len);
102
+ buf.append((char*)&tmp,sizeof(tmp));
data/ext/zkrb.c CHANGED
@@ -73,6 +73,17 @@
73
73
  #include "ruby/io.h"
74
74
  #endif
75
75
 
76
+ #ifndef HAVE_RB_THREAD_FD_SELECT
77
+ #define rb_fdset_t fd_set
78
+ #define rb_fd_isset(n, f) FD_ISSET(n, f)
79
+ #define rb_fd_init(f) FD_ZERO(f)
80
+ #define rb_fd_zero(f) FD_ZERO(f)
81
+ #define rb_fd_set(n, f) FD_SET(n, f)
82
+ #define rb_fd_clr(n, f) FD_CLR(n, f)
83
+ #define rb_fd_term(f)
84
+ #define rb_thread_fd_select rb_thread_select
85
+ #endif
86
+
76
87
  #include "zookeeper/zookeeper.h"
77
88
  #include <errno.h>
78
89
  #include <stdio.h>
@@ -787,8 +798,8 @@ inline static int get_self_pipe_read_fd(VALUE self) {
787
798
  static VALUE method_zkrb_iterate_event_loop(VALUE self) {
788
799
  FETCH_DATA_PTR(self, zk);
789
800
 
790
- fd_set rfds, wfds, efds;
791
- FD_ZERO(&rfds); FD_ZERO(&wfds); FD_ZERO(&efds);
801
+ rb_fdset_t rfds, wfds, efds;
802
+ rb_fd_init(&rfds); rb_fd_init(&wfds); rb_fd_init(&efds);
792
803
 
793
804
  int fd = 0, interest = 0, events = 0, rc = 0, maxfd = 0, irc = 0, prc = 0;
794
805
  struct timeval tv;
@@ -797,14 +808,14 @@ static VALUE method_zkrb_iterate_event_loop(VALUE self) {
797
808
 
798
809
  if (fd != -1) {
799
810
  if (interest & ZOOKEEPER_READ) {
800
- FD_SET(fd, &rfds);
811
+ rb_fd_set(fd, &rfds);
801
812
  } else {
802
- FD_CLR(fd, &rfds);
813
+ rb_fd_clr(fd, &rfds);
803
814
  }
804
815
  if (interest & ZOOKEEPER_WRITE) {
805
- FD_SET(fd, &wfds);
816
+ rb_fd_set(fd, &wfds);
806
817
  } else {
807
- FD_CLR(fd, &wfds);
818
+ rb_fd_clr(fd, &wfds);
808
819
  }
809
820
  } else {
810
821
  fd = 0;
@@ -813,22 +824,22 @@ static VALUE method_zkrb_iterate_event_loop(VALUE self) {
813
824
  // add our self-pipe to the read set, allow us to wake up in case our attention is needed
814
825
  int pipe_r_fd = get_self_pipe_read_fd(self);
815
826
 
816
- FD_SET(pipe_r_fd, &rfds);
827
+ rb_fd_set(pipe_r_fd, &rfds);
817
828
 
818
829
  maxfd = (pipe_r_fd > fd) ? pipe_r_fd : fd;
819
830
 
820
- rc = rb_thread_select(maxfd+1, &rfds, &wfds, &efds, &tv);
831
+ rc = rb_thread_fd_select(maxfd+1, &rfds, &wfds, &efds, &tv);
821
832
 
822
833
  if (rc > 0) {
823
- if (FD_ISSET(fd, &rfds)) {
834
+ if (rb_fd_isset(fd, &rfds)) {
824
835
  events |= ZOOKEEPER_READ;
825
836
  }
826
- if (FD_ISSET(fd, &wfds)) {
837
+ if (rb_fd_isset(fd, &wfds)) {
827
838
  events |= ZOOKEEPER_WRITE;
828
839
  }
829
840
 
830
841
  // we got woken up by the self-pipe
831
- if (FD_ISSET(pipe_r_fd, &rfds)) {
842
+ if (rb_fd_isset(pipe_r_fd, &rfds)) {
832
843
  // one event has awoken us, so we clear one event from the pipe
833
844
  char b[1];
834
845
 
@@ -853,6 +864,9 @@ static VALUE method_zkrb_iterate_event_loop(VALUE self) {
853
864
  prc, interest, fd, pipe_r_fd, maxfd, irc, tv.tv_sec + (tv.tv_usec/ 1000.0 / 1000.0));
854
865
  }
855
866
 
867
+ rb_fd_term(&rfds);
868
+ rb_fd_term(&wfds);
869
+ rb_fd_term(&efds);
856
870
  return INT2FIX(prc);
857
871
  }
858
872
 
data/java/java_base.rb CHANGED
@@ -183,8 +183,6 @@ class JavaBase
183
183
  attr_reader :event_queue
184
184
 
185
185
  def reopen(timeout=10, watcher=nil, opts = {})
186
- # watcher ||= @default_watcher
187
-
188
186
  @mutex.synchronize do
189
187
  @req_registry.clear_watchers!
190
188
 
@@ -490,7 +488,7 @@ class JavaBase
490
488
 
491
489
  def replace_jzk!(opts = {})
492
490
  orig_jzk = @jzk
493
- if opts.has_key?(:session_id) && opts.has_key(:session_passwd)
491
+ if opts.has_key?(:session_id) && opts.has_key?(:session_passwd)
494
492
  @jzk = JZK::ZooKeeper.new(@host, DEFAULT_SESSION_TIMEOUT, JavaCB::WatcherCallback.new(event_queue, :client => self), opts.fetch(:session_id), opts.fetch(:session_passwd).to_java_bytes)
495
493
  else
496
494
  @jzk = JZK::ZooKeeper.new(@host, DEFAULT_SESSION_TIMEOUT, JavaCB::WatcherCallback.new(event_queue, :client => self))
@@ -1,4 +1,4 @@
1
1
  module Zookeeper
2
- VERSION = '1.4.8'
2
+ VERSION = '1.5.0'
3
3
  DRIVER_VERSION = '3.4.5'
4
4
  end
@@ -4,7 +4,7 @@ unless defined?(::JRUBY_VERSION)
4
4
  describe %[forked connection] do
5
5
  let(:path) { "/_zktest_" }
6
6
  let(:pids_root) { "#{path}/pids" }
7
- let(:data) { "underpants" }
7
+ let(:data) { "underpants" }
8
8
  let(:connection_string) { Zookeeper.default_cnx_str }
9
9
 
10
10
  def process_alive?(pid)
@@ -15,7 +15,7 @@ unless defined?(::JRUBY_VERSION)
15
15
  end
16
16
 
17
17
  LBORDER = ('-' * 35) << '< '
18
- RBORDER = ' >' << ('-' * 35)
18
+ RBORDER = ' >' << ('-' * 35)
19
19
 
20
20
  def mark(thing)
21
21
  logger << "\n#{LBORDER}#{thing}#{RBORDER}\n\n"
@@ -25,8 +25,6 @@ unless defined?(::JRUBY_VERSION)
25
25
  mark "BEFORE: START"
26
26
  if defined?(::Rubinius)
27
27
  pending("this test is currently broken in rbx")
28
- # elsif ENV['TRAVIS']
29
- # pending("this test is currently hanging in travis")
30
28
  else
31
29
  @zk = Zookeeper.new(connection_string)
32
30
  rm_rf(@zk, path)
@@ -105,7 +103,7 @@ unless defined?(::JRUBY_VERSION)
105
103
  @zk.resume_after_fork_in_parent
106
104
 
107
105
  event_waiter_th = Thread.new do
108
- @latch.await(5) unless @event
106
+ @latch.await(5) unless @event
109
107
  @event
110
108
  end
111
109
 
@@ -1051,7 +1051,11 @@ shared_examples_for "connection" do
1051
1051
  zk.close
1052
1052
  end
1053
1053
 
1054
- zk.stat(:path => path, :callback => evil_cb)
1054
+ begin
1055
+ zk.stat(:path => path, :callback => evil_cb)
1056
+ rescue IOError
1057
+ # captures flaky IOError: stream closed in another thread
1058
+ end
1055
1059
 
1056
1060
  wait_until { zk.closed? }
1057
1061
  zk.should be_closed
@@ -3,10 +3,6 @@ module Zookeeper
3
3
  !!ENV['SPAWN_ZOOKEEPER']
4
4
  end
5
5
 
6
- def self.travis?
7
- !!ENV['TRAVIS']
8
- end
9
-
10
6
  def self.default_cnx_host
11
7
  ENV['ZK_DEFAULT_HOST'] || 'localhost'
12
8
  end
data/zookeeper.gemspec CHANGED
@@ -6,13 +6,21 @@ Gem::Specification.new do |s|
6
6
  s.name = 'zookeeper'
7
7
  s.version = Zookeeper::VERSION
8
8
 
9
- s.authors = ["Phillip Pearson", "Eric Maland", "Evan Weaver", "Brian Wickman", "Neil Conway", "Jonathan D. Simms"]
9
+ s.authors = [
10
+ "Phillip Pearson",
11
+ "Eric Maland",
12
+ "Evan Weaver",
13
+ "Brian Wickman",
14
+ "Neil Conway",
15
+ "Jonathan D. Simms",
16
+ "Mal McKay",
17
+ ]
10
18
  s.email = ["slyphon@gmail.com"]
11
19
  s.summary = %q{Apache ZooKeeper driver for Rubies}
12
20
  s.description = <<-EOS
13
21
  A low-level multi-Ruby wrapper around the ZooKeeper API bindings. For a
14
22
  friendlier interface, see http://github.com/slyphon/zk. Currently supported:
15
- MRI: {1.8.7, 1.9.2, 1.9.3}, JRuby: ~> 1.6.7, Rubinius: 2.0.testing, REE 1.8.7.
23
+ MRI: {2.5, 2.6, 2.7, 3.0}, JRuby: ~> 9.2.x.x
16
24
 
17
25
  This library uses version #{Zookeeper::DRIVER_VERSION} of zookeeper bindings.
18
26
 
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zookeeper
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.8
5
- prerelease:
4
+ version: 1.5.0
6
5
  platform: java
7
6
  authors:
8
7
  - Phillip Pearson
@@ -11,68 +10,60 @@ authors:
11
10
  - Brian Wickman
12
11
  - Neil Conway
13
12
  - Jonathan D. Simms
14
- autorequire:
13
+ - Mal McKay
14
+ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2014-01-16 00:00:00.000000000 Z
17
+ date: 2021-09-27 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
- name: slyphon-log4j
21
20
  requirement: !ruby/object:Gem::Requirement
22
- none: false
23
21
  requirements:
24
22
  - - '='
25
23
  - !ruby/object:Gem::Version
26
24
  version: 1.2.15
27
- type: :runtime
25
+ name: slyphon-log4j
28
26
  prerelease: false
27
+ type: :runtime
29
28
  version_requirements: !ruby/object:Gem::Requirement
30
- none: false
31
29
  requirements:
32
30
  - - '='
33
31
  - !ruby/object:Gem::Version
34
32
  version: 1.2.15
35
33
  - !ruby/object:Gem::Dependency
36
- name: slyphon-zookeeper_jar
37
34
  requirement: !ruby/object:Gem::Requirement
38
- none: false
39
35
  requirements:
40
36
  - - '='
41
37
  - !ruby/object:Gem::Version
42
38
  version: 3.3.5
43
- type: :runtime
39
+ name: slyphon-zookeeper_jar
44
40
  prerelease: false
41
+ type: :runtime
45
42
  version_requirements: !ruby/object:Gem::Requirement
46
- none: false
47
43
  requirements:
48
44
  - - '='
49
45
  - !ruby/object:Gem::Version
50
46
  version: 3.3.5
51
- description: ! 'A low-level multi-Ruby wrapper around the ZooKeeper API bindings.
52
- For a
53
-
47
+ description: |+
48
+ A low-level multi-Ruby wrapper around the ZooKeeper API bindings. For a
54
49
  friendlier interface, see http://github.com/slyphon/zk. Currently supported:
55
-
56
- MRI: {1.8.7, 1.9.2, 1.9.3}, JRuby: ~> 1.6.7, Rubinius: 2.0.testing, REE 1.8.7.
57
-
50
+ MRI: {2.5, 2.6, 2.7, 3.0}, JRuby: ~> 9.2.x.x
58
51
 
59
52
  This library uses version 3.4.5 of zookeeper bindings.
60
53
 
61
-
62
- '
63
54
  email:
64
55
  - slyphon@gmail.com
65
56
  executables: []
66
57
  extensions: []
67
58
  extra_rdoc_files: []
68
59
  files:
69
- - .ctags_paths
70
- - .dotfiles/ruby-gemset
71
- - .dotfiles/ruby-version
72
- - .dotfiles/rvmrc
73
- - .gitignore
74
- - .gitmodules
75
- - .travis.yml
60
+ - ".ctags_paths"
61
+ - ".dotfiles/ruby-gemset"
62
+ - ".dotfiles/ruby-version"
63
+ - ".dotfiles/rvmrc"
64
+ - ".github/workflows/build.yml"
65
+ - ".gitignore"
66
+ - ".gitmodules"
76
67
  - CHANGELOG
77
68
  - Gemfile
78
69
  - Guardfile
@@ -92,7 +83,11 @@ files:
92
83
  - ext/extconf.rb
93
84
  - ext/generate_gvl_code.rb
94
85
  - ext/patches/zkc-3.3.5-network.patch
86
+ - ext/patches/zkc-3.4.5-buffer-overflow.patch
87
+ - ext/patches/zkc-3.4.5-fetch-and-add.patch
95
88
  - ext/patches/zkc-3.4.5-logging.patch
89
+ - ext/patches/zkc-3.4.5-out-of-order-ping.patch
90
+ - ext/patches/zkc-3.4.5-yosemite-htonl-fix.patch
96
91
  - ext/zkc-3.4.5.tar.gz
97
92
  - ext/zkrb.c
98
93
  - ext/zkrb_wrapper.c
@@ -147,28 +142,27 @@ files:
147
142
  - zoomonkey/zoomonkey.rb
148
143
  homepage: https://github.com/slyphon/zookeeper
149
144
  licenses: []
150
- post_install_message:
145
+ metadata: {}
146
+ post_install_message:
151
147
  rdoc_options: []
152
148
  require_paths:
153
149
  - lib
154
150
  - java
155
151
  required_ruby_version: !ruby/object:Gem::Requirement
156
- none: false
157
152
  requirements:
158
- - - ! '>='
153
+ - - ">="
159
154
  - !ruby/object:Gem::Version
160
155
  version: '0'
161
156
  required_rubygems_version: !ruby/object:Gem::Requirement
162
- none: false
163
157
  requirements:
164
- - - ! '>='
158
+ - - ">="
165
159
  - !ruby/object:Gem::Version
166
160
  version: '0'
167
161
  requirements: []
168
- rubyforge_project:
169
- rubygems_version: 1.8.25
170
- signing_key:
171
- specification_version: 3
162
+ rubyforge_project:
163
+ rubygems_version: 2.7.9
164
+ signing_key:
165
+ specification_version: 4
172
166
  summary: Apache ZooKeeper driver for Rubies
173
167
  test_files:
174
168
  - spec/c_zookeeper_spec.rb
data/.travis.yml DELETED
@@ -1,37 +0,0 @@
1
- ---
2
- notifications:
3
- email:
4
- - slyphon@gmail.com
5
- - eric@5stops.com
6
-
7
- # pull in releaseops submodule
8
- before_install:
9
- - git submodule update --init --recursive
10
-
11
- env:
12
- - SPAWN_ZOOKEEPER='true'
13
-
14
- language: ruby
15
-
16
- rvm:
17
- - 1.9.3
18
- - 1.9.2
19
- - 1.8.7
20
- - ree
21
- - jruby-18mode
22
- - jruby-19mode
23
- - rbx-18mode
24
- - rbx-19mode
25
- - 2.0.0
26
- matrix:
27
- allow_failures:
28
- - rvm: rbx-18mode
29
- - rvm: rbx-19mode
30
-
31
- bundler_args: --without development docs coverage
32
-
33
- # blacklist
34
- branches:
35
- except:
36
- # - 'dev/zookeeper-st'
37
-