zk 1.9.3 → 1.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/build.yml +55 -0
- data/.gitignore +1 -0
- data/Gemfile +18 -8
- data/README.markdown +9 -9
- data/RELEASES.markdown +28 -1
- data/lib/zk/client/base.rb +15 -0
- data/lib/zk/client/threaded.rb +3 -3
- data/lib/zk/client.rb +1 -1
- data/lib/zk/election.rb +1 -1
- data/lib/zk/event_handler.rb +16 -8
- data/lib/zk/event_handler_subscription/base.rb +1 -1
- data/lib/zk/fork_hook.rb +9 -4
- data/lib/zk/locker/locker_base.rb +14 -2
- data/lib/zk/locker/semaphore.rb +1 -3
- data/lib/zk/logger.rb +34 -0
- data/lib/zk/node_deletion_watcher.rb +4 -5
- data/lib/zk/pool.rb +12 -12
- data/lib/zk/subscription.rb +1 -1
- data/lib/zk/threaded_callback.rb +1 -1
- data/lib/zk/threadpool.rb +1 -1
- data/lib/zk/version.rb +1 -1
- data/lib/zk.rb +1 -5
- data/spec/event_catcher_spec.rb +1 -1
- data/spec/logging_progress_bar_formatter.rb +1 -1
- data/spec/message_queue_spec.rb +6 -6
- data/spec/shared/client_examples.rb +81 -81
- data/spec/shared/locker_examples.rb +13 -13
- data/spec/spec_helper.rb +12 -13
- data/spec/support/bogus_mongoid.rb +1 -1
- data/spec/support/client_forker.rb +1 -1
- data/spec/support/event_catcher.rb +1 -1
- data/spec/support/logging.rb +15 -47
- data/spec/zk/00_forked_client_integration_spec.rb +3 -3
- data/spec/zk/client/locking_and_session_death_spec.rb +2 -2
- data/spec/zk/client_spec.rb +19 -19
- data/spec/zk/election_spec.rb +44 -44
- data/spec/zk/extensions_spec.rb +2 -2
- data/spec/zk/locker/exclusive_locker_spec.rb +41 -41
- data/spec/zk/locker/locker_basic_spec.rb +55 -33
- data/spec/zk/locker/semaphore_spec.rb +39 -32
- data/spec/zk/locker/shared_exclusive_integration_spec.rb +37 -37
- data/spec/zk/locker/shared_locker_spec.rb +43 -43
- data/spec/zk/locker_spec.rb +2 -2
- data/spec/zk/module_spec.rb +25 -25
- data/spec/zk/mongoid_spec.rb +47 -47
- data/spec/zk/node_deletion_watcher_spec.rb +39 -31
- data/spec/zk/pool_spec.rb +56 -65
- data/spec/zk/threaded_callback_spec.rb +10 -10
- data/spec/zk/threadpool_spec.rb +25 -25
- data/spec/zk/watch_spec.rb +67 -79
- data/spec/zk/zookeeper_spec.rb +36 -30
- data/zk.gemspec +1 -2
- metadata +26 -47
- data/.travis.yml +0 -25
- data/lib/zk/logging.rb +0 -36
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c011796ca41504b7a8618ce83fe5eb497422160ce4cee31e7ab1ed45c208bb12
|
4
|
+
data.tar.gz: fe7d1be9ed832ba2f3bb41d89e3e945cabc52cdd01fe62ff09a79ae79802b93c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5689fd5376c5378d03617f95d9443279a708ad7b8090bf555de9c85b813b76663d9a0d76d4f29eb32cd1ac398b28265168f1a5e87ddbd08457eb0f55cf83c0cd
|
7
|
+
data.tar.gz: 941e497e7f174e6420bab78d45f320d6939f892ed06b26473d38c8c4b3e68608d7f93f2f53f911bdf680b0cdb5a9801e0c1af5722096c50ad8645a81e80e3f19
|
@@ -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
|
+
- jruby-9.1.17.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/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -12,20 +12,25 @@ source "https://rubygems.org"
|
|
12
12
|
# gem 'zookeeper', '~> 1.3.0'
|
13
13
|
# end
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
group :development, :test do
|
16
|
+
if RUBY_VERSION >= '1.9.3'
|
17
|
+
gem 'rake'
|
18
|
+
else
|
19
|
+
gem 'rake', '~> 10.5'
|
20
|
+
end
|
21
|
+
end
|
17
22
|
|
18
23
|
group :docs do
|
19
|
-
gem 'yard', '
|
24
|
+
gem 'yard', '>= 0.9.20'
|
20
25
|
|
21
26
|
platform :mri_19 do
|
22
27
|
gem 'redcarpet'
|
23
28
|
end
|
24
29
|
end
|
25
30
|
|
26
|
-
platform :mri_19 do
|
27
|
-
|
28
|
-
end
|
31
|
+
# platform :mri_19 do
|
32
|
+
# gem 'simplecov', :group => :coverage, :require => false
|
33
|
+
# end
|
29
34
|
|
30
35
|
group :development do
|
31
36
|
gem 'guard', :require => false
|
@@ -37,12 +42,17 @@ group :development do
|
|
37
42
|
gem 'growl', :require => false
|
38
43
|
gem 'rb-readline', :platform => :ruby
|
39
44
|
end
|
45
|
+
|
46
|
+
platform :mri do
|
47
|
+
gem 'pry-byebug'
|
48
|
+
end
|
40
49
|
end
|
41
50
|
|
42
51
|
group :test do
|
43
|
-
gem '
|
44
|
-
gem '
|
52
|
+
gem 'pry'
|
53
|
+
gem 'rspec', '~> 3.6.0'
|
45
54
|
gem 'zk-server', '~> 1.1.4'
|
55
|
+
gem 'test-unit', :platforms => [:ruby_22, :ruby_23, :ruby_24]
|
46
56
|
end
|
47
57
|
|
48
58
|
# Specify your gem's dependencies in zk.gemspec
|
data/README.markdown
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# ZK #
|
2
2
|
|
3
|
-
|
3
|
+
![Build Status](https://github.com/zk-ruby/zk/actions/workflows/build.yml/badge.svg)
|
4
4
|
|
5
|
-
ZK is an application programmer's interface to the Apache [ZooKeeper][] server. It is based on the [zookeeper gem][] which is a multi-Ruby low-level driver. Currently MRI 1.8.7, 1.9.2, 1.9.3, REE, and JRuby are supported. Rubinius 2.0.testing is supported-ish (it's expected to work, but upstream is unstable, so YMMV).
|
5
|
+
ZK is an application programmer's interface to the Apache [ZooKeeper][] server. It is based on the [zookeeper gem][] which is a multi-Ruby low-level driver. Currently MRI 1.8.7, 1.9.2, 1.9.3, REE, and JRuby are supported. Rubinius 2.0.testing is supported-ish (it's expected to work, but upstream is unstable, so YMMV).
|
6
6
|
|
7
|
-
ZK is licensed under the [MIT][] license.
|
7
|
+
ZK is licensed under the [MIT][] license.
|
8
8
|
|
9
9
|
The key place to start in the documentation is with ZK::Client::Base ([rubydoc.info][ZK::Client::Base], [local](/docs/ZK/Client/Base)).
|
10
10
|
|
@@ -27,11 +27,11 @@ ZooKeeper is a multi-purpose tool that is designed to allow you to write code th
|
|
27
27
|
|
28
28
|
One of the most useful aspects of ZooKeeper is the ability to set "[watches][]" on nodes. This allows one to be notified when a node has been deleted, created, changed, or has had its list of child znodes modified. The asynchronous nature of these watches enables you to write code that can _react_ to changes in your environment without polling and busy-waiting.
|
29
29
|
|
30
|
-
Znodes can be _ephemeral_, which means that when the connection that created them goes away, they're automatically cleaned up, and all the clients that were watching them are notified of the deletion. This is an incredibly useful mechanism for providing _presence_ in a cluster ("which of my thingamabobers are up?). If you've ever run across a stale pid file or lock, you can imagine how useful this feature can be.
|
30
|
+
Znodes can be _ephemeral_, which means that when the connection that created them goes away, they're automatically cleaned up, and all the clients that were watching them are notified of the deletion. This is an incredibly useful mechanism for providing _presence_ in a cluster ("which of my thingamabobers are up?). If you've ever run across a stale pid file or lock, you can imagine how useful this feature can be.
|
31
31
|
|
32
32
|
Znodes can also be created as _sequence_ nodes, which means that beneath a given path, a node can be created with a given prefix and assigned a unique integer. This, along with the _ephemeral_ property, provide the basis for most of the coordination classes such as [groups][] and [locks][].
|
33
33
|
|
34
|
-
ZooKeeper is easy to deploy in a [Highly Available][ha-config] configuration, and the clients natively understand the clustering and how to resume a session transparently when one of the cluster nodes goes away.
|
34
|
+
ZooKeeper is easy to deploy in a [Highly Available][ha-config] configuration, and the clients natively understand the clustering and how to resume a session transparently when one of the cluster nodes goes away.
|
35
35
|
|
36
36
|
[watches]: http://zookeeper.apache.org/doc/current/zookeeperProgrammers.html#ch_zkWatches
|
37
37
|
[locking]: http://zookeeper.apache.org/doc/current/recipes.html#sc_recipes_Locks
|
@@ -64,7 +64,7 @@ In addition to all of that, I would like to think that the public API the ZK::Cl
|
|
64
64
|
[EventMachine]: https://github.com/eventmachine/eventmachine
|
65
65
|
[zk-eventmachine]: https://github.com/zk-ruby/zk-eventmachine
|
66
66
|
|
67
|
-
## Release info / Changelog
|
67
|
+
## Release info / Changelog
|
68
68
|
|
69
69
|
See the [RELEASES][] page for more info on features and bugfixes in each release.
|
70
70
|
|
@@ -74,9 +74,9 @@ ZK strives to be a complete, correct, and convenient way of interacting with Zoo
|
|
74
74
|
|
75
75
|
* In versions < 0.9 there is only *one* event dispatch thread. It is *very important* that you don't block the event delivery thread. In 1.0, there is one delivery thread by default, but you can adjust the level of concurrency, allowing more control and convenience for building your event-driven app.
|
76
76
|
|
77
|
-
* ZK uses threads. You will have to use synchronization primitives if you want to avoid getting hurt. There are use cases that do not require you to think about this, but as soon as you want to register for events, you're using multiple threads.
|
77
|
+
* ZK uses threads. You will have to use synchronization primitives if you want to avoid getting hurt. There are use cases that do not require you to think about this, but as soon as you want to register for events, you're using multiple threads.
|
78
78
|
|
79
|
-
* If you're not familiar with developing solutions with zookeeper, you should read about [sessions][] and [watches][] in the Programmer's Guide. Even if you *are* familiar, you should probably go read it again.
|
79
|
+
* If you're not familiar with developing solutions with zookeeper, you should read about [sessions][] and [watches][] in the Programmer's Guide. Even if you *are* familiar, you should probably go read it again.
|
80
80
|
|
81
81
|
* It is very important that you not ignore connection state events if you're using watches.
|
82
82
|
|
@@ -88,7 +88,7 @@ ZK strives to be a complete, correct, and convenient way of interacting with Zoo
|
|
88
88
|
[async-branch]: https://github.com/zk-ruby/zk/tree/dev%2Fasync-conveniences
|
89
89
|
[chroot]: http://zookeeper.apache.org/doc/current/zookeeperProgrammers.html#ch_zkSessions
|
90
90
|
[YARD]: http://yardoc.org/
|
91
|
-
[sessions]: http://zookeeper.apache.org/doc/current/zookeeperProgrammers.html#ch_zkSessions
|
91
|
+
[sessions]: http://zookeeper.apache.org/doc/current/zookeeperProgrammers.html#ch_zkSessions
|
92
92
|
[watches]: http://zookeeper.apache.org/doc/r3.3.5/zookeeperProgrammers.html#ch_zkWatches
|
93
93
|
|
94
94
|
## Users
|
data/RELEASES.markdown
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
This file notes feature differences and bugfixes contained between releases.
|
2
2
|
|
3
|
+
### v1.10.0 ###
|
4
|
+
|
5
|
+
* Updates dependency on zookeeper gem to 1.5.0 #90 (h/t: @malmckay)
|
6
|
+
* Move build to Github Actions, drop support for older Rubies (#104) (h/t: @malmckay)
|
7
|
+
* bump yard revision to ~> 0.9.11 (Fixes #101) (#102) (h/t: @slyphon)
|
8
|
+
* Add other Ruby versions with currently breaking tests (h/t: @berlincount)
|
9
|
+
* RSpec 3 support and cleanups (h/t: @nerdrew)
|
10
|
+
* Interrupt blocked locker (h/t: @lmarburger)
|
11
|
+
|
12
|
+
### v1.9.6 ###
|
13
|
+
|
14
|
+
* Fixes from @rickypai for ruby 2.2 (#89)
|
15
|
+
* Remove dependency on logging gem #90 (h/t: @eric)
|
16
|
+
|
17
|
+
### v1.9.5 ###
|
18
|
+
|
19
|
+
* Really clear hooks when clear! is called #83 (h/t: Liam Stewart)
|
20
|
+
* implement `add_auth` method to send credentials to zookeeper #86 (h/t: ajf8)
|
21
|
+
|
22
|
+
### v1.9.4 ###
|
23
|
+
|
24
|
+
* Forward options to underlying connection #69 (h/t: avalanche123)
|
25
|
+
* Don't check connection state in Locker#assert! - leads to better retry behavior
|
26
|
+
* allow specifying session-id
|
27
|
+
* upgrade logging gem dependency
|
28
|
+
|
29
|
+
|
3
30
|
### v1.9.3 ###
|
4
31
|
|
5
32
|
* Fix deadlocks between watchers and reconnecting
|
@@ -241,7 +268,7 @@ You are __STRONGLY ENCOURAGED__ to go and look at the [CHANGELOG](http://git.io/
|
|
241
268
|
* add zk.register(:all) to recevie node updates for all nodes (i.e. not filtered on path)
|
242
269
|
|
243
270
|
* add 'interest' feature to zk.register, now you can indicate what kind of events should be delivered to the given block (previously you had to do that filtering inside the block). The default behavior is still the same, if no 'interest' is given, then all event types for the given path will be delivered to that block.
|
244
|
-
|
271
|
+
|
245
272
|
zk.register('/path', :created) do |event|
|
246
273
|
# event.node_created? will always be true
|
247
274
|
end
|
data/lib/zk/client/base.rb
CHANGED
@@ -870,6 +870,21 @@ module ZK
|
|
870
870
|
opts[:callback] ? rv : rv[:stat]
|
871
871
|
end
|
872
872
|
|
873
|
+
# Send authentication
|
874
|
+
#
|
875
|
+
# @param opts [String] :scheme authentication scheme being provided for.
|
876
|
+
#
|
877
|
+
# @param opts [String] :cert the authentication data.
|
878
|
+
#
|
879
|
+
# @example send digest authentication
|
880
|
+
#
|
881
|
+
# zk.add_auth({ :scheme => 'digest', :cert => 'username:password' })
|
882
|
+
#
|
883
|
+
def add_auth(*args)
|
884
|
+
opts = args.extract_options!
|
885
|
+
call_and_check_rc(:add_auth, opts )
|
886
|
+
end
|
887
|
+
|
873
888
|
# @private
|
874
889
|
# @todo need to document this a little more
|
875
890
|
def set_debug_level(level)
|
data/lib/zk/client/threaded.rb
CHANGED
@@ -39,7 +39,7 @@ module ZK
|
|
39
39
|
include StateMixin
|
40
40
|
include Unixisms
|
41
41
|
include Conveniences
|
42
|
-
include
|
42
|
+
include Logger
|
43
43
|
|
44
44
|
DEFAULT_THREADPOOL_SIZE = 1
|
45
45
|
|
@@ -180,7 +180,7 @@ module ZK
|
|
180
180
|
|
181
181
|
ObjectSpace.define_finalizer(self, self.class.finalizer(@fork_subs))
|
182
182
|
|
183
|
-
connect if opts.fetch(:connect, true)
|
183
|
+
connect(opts) if opts.fetch(:connect, true)
|
184
184
|
end
|
185
185
|
|
186
186
|
# ensure that the initializer and the reopen code set up the mutexes
|
@@ -626,7 +626,7 @@ module ZK
|
|
626
626
|
# create the connection.
|
627
627
|
@last_cnx_state = Zookeeper::ZOO_CONNECTING_STATE
|
628
628
|
|
629
|
-
@cnx = create_connection(@host, timeout, @event_handler.get_default_watcher_block)
|
629
|
+
@cnx = create_connection(@host, timeout, @event_handler.get_default_watcher_block, opts)
|
630
630
|
|
631
631
|
spawn_reconnect_thread
|
632
632
|
|
data/lib/zk/client.rb
CHANGED
@@ -6,7 +6,7 @@ module ZK
|
|
6
6
|
# Once you've had a look there, take a look at {Client::Conveniences},
|
7
7
|
# {Client::StateMixin}, and {Client::Unixisms}
|
8
8
|
#
|
9
|
-
# @todo ACL support is pretty much unused currently.
|
9
|
+
# @todo ACL support is pretty much unused currently.
|
10
10
|
# If anyone has suggestions, hints, use-cases, examples, etc. by all means please file a bug.
|
11
11
|
#
|
12
12
|
module Client
|
data/lib/zk/election.rb
CHANGED
data/lib/zk/event_handler.rb
CHANGED
@@ -6,7 +6,7 @@ module ZK
|
|
6
6
|
# you never really need to initialize this yourself
|
7
7
|
class EventHandler
|
8
8
|
include Java::OrgApacheZookeeper::Watcher if defined?(JRUBY_VERSION)
|
9
|
-
include ZK::
|
9
|
+
include ZK::Logger
|
10
10
|
|
11
11
|
# @private
|
12
12
|
VALID_WATCH_TYPES = [:data, :child].freeze
|
@@ -36,7 +36,7 @@ module ZK
|
|
36
36
|
@mutex = nil
|
37
37
|
@setup_watcher_mutex = nil
|
38
38
|
|
39
|
-
@callbacks = Hash.new
|
39
|
+
@callbacks = Hash.new
|
40
40
|
|
41
41
|
@outstanding_watches = VALID_WATCH_TYPES.inject({}) do |h,k|
|
42
42
|
h.tap { |x| x[k] = Set.new }
|
@@ -84,7 +84,9 @@ module ZK
|
|
84
84
|
end
|
85
85
|
|
86
86
|
EventHandlerSubscription.new(self, path, block, hash).tap do |subscription|
|
87
|
-
synchronize
|
87
|
+
synchronize do
|
88
|
+
(@callbacks[path] ||= []) << subscription
|
89
|
+
end
|
88
90
|
end
|
89
91
|
end
|
90
92
|
alias :subscribe :register
|
@@ -131,15 +133,21 @@ module ZK
|
|
131
133
|
subscription = args[1]
|
132
134
|
else
|
133
135
|
path, index = args[0..1]
|
134
|
-
synchronize
|
136
|
+
synchronize do
|
137
|
+
if @callbacks[path] && @callbacks[path][index]
|
138
|
+
@callbacks[path][index] = nil
|
139
|
+
end
|
140
|
+
end
|
135
141
|
return
|
136
142
|
end
|
137
143
|
|
138
144
|
synchronize do
|
139
|
-
ary = @callbacks[subscription.path]
|
140
|
-
|
141
|
-
|
142
|
-
|
145
|
+
if ary = @callbacks[subscription.path]
|
146
|
+
idx = ary.index(subscription) and ary.delete_at(idx)
|
147
|
+
if ary.empty?
|
148
|
+
@callbacks.delete(subscription.path)
|
149
|
+
end
|
150
|
+
end
|
143
151
|
end
|
144
152
|
|
145
153
|
nil
|
data/lib/zk/fork_hook.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
module ZK
|
2
2
|
module ForkHook
|
3
|
-
include ZK::
|
3
|
+
include ZK::Logger
|
4
4
|
extend self
|
5
5
|
|
6
|
-
@mutex = Mutex.new unless @mutex
|
6
|
+
@mutex = Mutex.new unless defined?(@mutex)
|
7
7
|
|
8
8
|
@hooks = {
|
9
9
|
:prepare => [],
|
10
10
|
:after_child => [],
|
11
11
|
:after_parent => [],
|
12
|
-
} unless @hooks
|
12
|
+
} unless defined?(@hooks)
|
13
13
|
|
14
14
|
attr_reader :hooks, :mutex
|
15
15
|
|
@@ -39,7 +39,7 @@ module ZK
|
|
39
39
|
|
40
40
|
# @private
|
41
41
|
def clear!
|
42
|
-
@mutex.synchronize { @hooks.values(&:clear) }
|
42
|
+
@mutex.synchronize { @hooks.values.each(&:clear) }
|
43
43
|
end
|
44
44
|
|
45
45
|
# @private
|
@@ -94,6 +94,10 @@ module ZK
|
|
94
94
|
register(:after_child, callable || blk)
|
95
95
|
end
|
96
96
|
|
97
|
+
def self.logger
|
98
|
+
@logger ||= ::ZK.logger || Zookeeper::Logger::ForwardingLogger.for(::ZK::Logger.wrapped_logger, _zk_logger_name)
|
99
|
+
end
|
100
|
+
|
97
101
|
class ForkSubscription < Subscription::Base
|
98
102
|
attr_reader :hook_type
|
99
103
|
|
@@ -108,4 +112,5 @@ module ZK
|
|
108
112
|
def self.install_fork_hook
|
109
113
|
require 'zk/install_fork_hooks'
|
110
114
|
end
|
115
|
+
|
111
116
|
end # ZK
|
@@ -8,7 +8,7 @@ module ZK
|
|
8
8
|
# author, and it may be corrected sometime in the future.
|
9
9
|
#
|
10
10
|
class LockerBase
|
11
|
-
include ZK::
|
11
|
+
include ZK::Logger
|
12
12
|
include ZK::Exceptions
|
13
13
|
|
14
14
|
# @private
|
@@ -277,7 +277,6 @@ module ZK
|
|
277
277
|
def assert!
|
278
278
|
@mutex.synchronize do
|
279
279
|
raise LockAssertionFailedError, "have not obtained the lock yet" unless locked?
|
280
|
-
raise LockAssertionFailedError, "not connected" unless zk.connected?
|
281
280
|
raise LockAssertionFailedError, "lock_path was #{lock_path.inspect}" unless lock_path
|
282
281
|
raise LockAssertionFailedError, "the lock path #{lock_path} did not exist!" unless zk.exists?(lock_path)
|
283
282
|
raise LockAssertionFailedError, "the parent node was replaced!" unless root_lock_path_same?
|
@@ -292,6 +291,19 @@ module ZK
|
|
292
291
|
false
|
293
292
|
end
|
294
293
|
|
294
|
+
# interrupt caller blocked on acquring a lock by delegating to
|
295
|
+
# ZK::NodeDeletionWatcher#interrupt!
|
296
|
+
#
|
297
|
+
# this does nothing if the watcher is not currently blocked.
|
298
|
+
#
|
299
|
+
# @raise [WakeUpException] raised when caller interrupted
|
300
|
+
#
|
301
|
+
def interrupt!
|
302
|
+
synchronize do
|
303
|
+
@node_deletion_watcher and @node_deletion_watcher.interrupt!
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
295
307
|
private
|
296
308
|
def synchronize
|
297
309
|
@mutex.synchronize { yield }
|
data/lib/zk/locker/semaphore.rb
CHANGED
@@ -2,8 +2,6 @@ module ZK
|
|
2
2
|
module Locker
|
3
3
|
# A semaphore implementation
|
4
4
|
class Semaphore < LockerBase
|
5
|
-
include Exceptions
|
6
|
-
|
7
5
|
@default_root_node = '/_zksemaphore'.freeze unless @default_root_node
|
8
6
|
|
9
7
|
class << self
|
@@ -13,7 +11,7 @@ module ZK
|
|
13
11
|
end
|
14
12
|
|
15
13
|
def initialize(client, name, semaphore_size, root_node=nil)
|
16
|
-
raise
|
14
|
+
raise ZK::Exceptions::BadArguments, <<-EOMESSAGE unless semaphore_size.kind_of? Integer
|
17
15
|
semaphore_size must be Integer, not #{semaphore_size.inspect}
|
18
16
|
EOMESSAGE
|
19
17
|
|
data/lib/zk/logger.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module ZK
|
2
|
+
# use the ZK.logger if non-nil (to allow users to override the logger)
|
3
|
+
# otherwise, use a Loggging logger based on the class name
|
4
|
+
module Logger
|
5
|
+
def self.wrapped_logger
|
6
|
+
if defined?(@@wrapped_logger)
|
7
|
+
@@wrapped_logger
|
8
|
+
else
|
9
|
+
@@wrapped_logger = ::Logger.new(STDERR).tap { |l| l.level = ::Logger::FATAL }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.wrapped_logger=(log)
|
14
|
+
@@wrapped_logger = log
|
15
|
+
end
|
16
|
+
|
17
|
+
# @private
|
18
|
+
module ClassMethods
|
19
|
+
def logger
|
20
|
+
::ZK.logger || Zookeeper::Logger::ForwardingLogger.for(::ZK::Logger.wrapped_logger, _zk_logger_name)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.included(base)
|
25
|
+
# return false if base < self # avoid infinite recursion
|
26
|
+
base.extend(ClassMethods)
|
27
|
+
end
|
28
|
+
|
29
|
+
def logger
|
30
|
+
@logger ||= (::ZK.logger || self.class.logger)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -1,8 +1,7 @@
|
|
1
1
|
module ZK
|
2
2
|
class NodeDeletionWatcher
|
3
3
|
include Zookeeper::Constants
|
4
|
-
include
|
5
|
-
include Logging
|
4
|
+
include Logger
|
6
5
|
|
7
6
|
# @private
|
8
7
|
module Constants
|
@@ -42,7 +41,7 @@ module ZK
|
|
42
41
|
@paths = paths.dup
|
43
42
|
@options = options.dup
|
44
43
|
@threshold = options[:threshold] || 0
|
45
|
-
raise
|
44
|
+
raise ZK::Exceptions::BadArguments, <<-EOBADARG unless @threshold.kind_of? Integer
|
46
45
|
options[:threshold] must be an Integer. Got #{@threshold.inspect}."
|
47
46
|
EOBADARG
|
48
47
|
|
@@ -89,7 +88,7 @@ module ZK
|
|
89
88
|
start = Time.now
|
90
89
|
time_to_stop = timeout ? (start + timeout) : nil
|
91
90
|
|
92
|
-
logger.debug { "#{__method__} @blocked: #{@blocked.inspect} about to wait" }
|
91
|
+
logger.debug { "#{__method__} @blocked: #{@blocked.inspect} about to wait" }
|
93
92
|
@cond.wait(timeout)
|
94
93
|
|
95
94
|
if (time_to_stop and (Time.now > time_to_stop)) and (@blocked == NOT_YET)
|
@@ -101,7 +100,7 @@ module ZK
|
|
101
100
|
end
|
102
101
|
|
103
102
|
# cause a thread blocked by us to be awakened and have a WakeUpException
|
104
|
-
# raised.
|
103
|
+
# raised.
|
105
104
|
#
|
106
105
|
# if a result has already been delivered, then this does nothing
|
107
106
|
#
|
data/lib/zk/pool.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
module ZK
|
2
2
|
module Pool
|
3
|
-
# Base class for a ZK connection pool. There are some applications that may
|
3
|
+
# Base class for a ZK connection pool. There are some applications that may
|
4
4
|
# require high synchronous throughput, which would be a suitable use for a
|
5
5
|
# connection pool. The ZK::Client::Threaded class is threadsafe, so it's
|
6
6
|
# not a problem accessing it from multiple threads, but it is limited to
|
7
7
|
# one outgoing synchronous request at a time, which could cause throughput
|
8
|
-
# issues for apps that are making very heavy use of zookeeper.
|
8
|
+
# issues for apps that are making very heavy use of zookeeper.
|
9
9
|
#
|
10
10
|
# The problem with using a connection pool is the added complexity when you
|
11
11
|
# try to use watchers. It may be possible to register a watch with one
|
12
12
|
# connection, and then call `:watch => true` on a different connection if
|
13
13
|
# you're not careful. Events delivered as part of an event handler have a
|
14
14
|
# `zk` attribute which can be used to access the connection that the
|
15
|
-
# callback is registered with.
|
15
|
+
# callback is registered with.
|
16
16
|
#
|
17
17
|
# Unless you're sure you *need* a connection pool, then avoid the added
|
18
18
|
# complexity.
|
19
19
|
#
|
20
20
|
class Base
|
21
|
-
include
|
21
|
+
include Logger
|
22
22
|
|
23
23
|
attr_reader :connections #:nodoc:
|
24
24
|
|
@@ -27,7 +27,7 @@ module ZK
|
|
27
27
|
|
28
28
|
@mutex = Monitor.new
|
29
29
|
@checkin_cond = @mutex.new_cond
|
30
|
-
|
30
|
+
|
31
31
|
@connections = [] # all connections we control
|
32
32
|
@pool = [] # currently available connections
|
33
33
|
|
@@ -58,7 +58,7 @@ module ZK
|
|
58
58
|
|
59
59
|
# close all the connections on the pool
|
60
60
|
def close_all!
|
61
|
-
@mutex.synchronize do
|
61
|
+
@mutex.synchronize do
|
62
62
|
return unless open?
|
63
63
|
@state = :closing
|
64
64
|
|
@@ -86,7 +86,7 @@ module ZK
|
|
86
86
|
|
87
87
|
@state = :closed
|
88
88
|
|
89
|
-
# free any waiting
|
89
|
+
# free any waiting
|
90
90
|
@checkin_cond.broadcast
|
91
91
|
end
|
92
92
|
end
|
@@ -146,7 +146,7 @@ module ZK
|
|
146
146
|
end
|
147
147
|
|
148
148
|
def assert_open!
|
149
|
-
raise Exceptions::PoolIsShuttingDownException, "pool is shutting down" unless open?
|
149
|
+
raise Exceptions::PoolIsShuttingDownException, "pool is shutting down" unless open?
|
150
150
|
end
|
151
151
|
|
152
152
|
end # Base
|
@@ -211,7 +211,7 @@ module ZK
|
|
211
211
|
@mutex.synchronize { @count_waiters }
|
212
212
|
end
|
213
213
|
|
214
|
-
def checkout(blocking=true)
|
214
|
+
def checkout(blocking=true)
|
215
215
|
raise ArgumentError, "checkout does not take a block, use .with_connection" if block_given?
|
216
216
|
@mutex.lock
|
217
217
|
begin
|
@@ -224,7 +224,7 @@ module ZK
|
|
224
224
|
# XXX(slyphon): not really sure how this case happens, but protect against it as we're
|
225
225
|
# seeing an issue in production
|
226
226
|
next if cnx.nil?
|
227
|
-
|
227
|
+
|
228
228
|
# if the connection isn't connected, then set up an on_connection
|
229
229
|
# handler and try the next one in the pool
|
230
230
|
unless cnx.connected?
|
@@ -263,7 +263,7 @@ module ZK
|
|
263
263
|
def add_connection!
|
264
264
|
@mutex.synchronize do
|
265
265
|
cnx = create_connection
|
266
|
-
@connections << cnx
|
266
|
+
@connections << cnx
|
267
267
|
|
268
268
|
handle_checkin_on_connection(cnx)
|
269
269
|
end # synchronize
|
@@ -281,7 +281,7 @@ module ZK
|
|
281
281
|
else
|
282
282
|
@on_connected_subs.synchronize do
|
283
283
|
|
284
|
-
sub = cnx.on_connected do
|
284
|
+
sub = cnx.on_connected do
|
285
285
|
# this synchronization is to prevent a race between setting up the subscription
|
286
286
|
# and assigning it to the @on_connected_subs hash. It's possible that the callback
|
287
287
|
# would fire before we had a chance to add the sub to the hash.
|
data/lib/zk/subscription.rb
CHANGED
data/lib/zk/threaded_callback.rb
CHANGED
data/lib/zk/threadpool.rb
CHANGED
data/lib/zk/version.rb
CHANGED