zk 0.9.1 → 1.0.0.rc.1
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/.gitignore +2 -2
- data/Gemfile +3 -4
- data/README.markdown +14 -5
- data/RELEASES.markdown +69 -1
- data/Rakefile +50 -18
- data/docs/examples/block_until_node_deleted_ex.rb +63 -0
- data/docs/examples/events_01.rb +36 -0
- data/docs/examples/events_02.rb +41 -0
- data/lib/{z_k → zk}/client/base.rb +87 -30
- data/lib/{z_k → zk}/client/conveniences.rb +0 -1
- data/lib/{z_k → zk}/client/state_mixin.rb +0 -0
- data/lib/zk/client/threaded.rb +196 -0
- data/lib/{z_k → zk}/client/unixisms.rb +0 -0
- data/lib/zk/client.rb +59 -0
- data/lib/zk/core_ext.rb +75 -0
- data/lib/{z_k → zk}/election.rb +0 -0
- data/lib/zk/event.rb +168 -0
- data/lib/{z_k → zk}/event_handler.rb +53 -28
- data/lib/zk/event_handler_subscription.rb +68 -0
- data/lib/{z_k → zk}/exceptions.rb +38 -23
- data/lib/zk/extensions.rb +79 -0
- data/lib/{z_k → zk}/find.rb +0 -0
- data/lib/{z_k → zk}/locker.rb +0 -0
- data/lib/{z_k → zk}/logging.rb +0 -0
- data/lib/{z_k → zk}/message_queue.rb +8 -4
- data/lib/{z_k → zk}/mongoid.rb +0 -0
- data/lib/{z_k → zk}/pool.rb +0 -0
- data/lib/zk/stat.rb +115 -0
- data/lib/{z_k → zk}/threadpool.rb +52 -4
- data/lib/zk/version.rb +3 -0
- data/lib/zk.rb +238 -1
- data/spec/message_queue_spec.rb +2 -2
- data/spec/shared/client_contexts.rb +8 -20
- data/spec/shared/client_examples.rb +136 -2
- data/spec/spec_helper.rb +4 -2
- data/spec/support/event_catcher.rb +11 -0
- data/spec/support/exist_matcher.rb +6 -0
- data/spec/support/logging.rb +2 -1
- data/spec/watch_spec.rb +194 -10
- data/spec/{z_k → zk}/client/locking_and_session_death_spec.rb +0 -32
- data/spec/zk/client_spec.rb +23 -0
- data/spec/{z_k → zk}/election_spec.rb +0 -0
- data/spec/{z_k → zk}/extensions_spec.rb +0 -0
- data/spec/{z_k → zk}/locker_spec.rb +0 -40
- data/spec/zk/module_spec.rb +185 -0
- data/spec/{z_k → zk}/mongoid_spec.rb +0 -2
- data/spec/{z_k → zk}/pool_spec.rb +0 -2
- data/spec/{z_k → zk}/threadpool_spec.rb +32 -4
- data/spec/zookeeper_spec.rb +1 -6
- data/zk.gemspec +2 -2
- metadata +64 -56
- data/lib/z_k/client/continuation_proxy.rb +0 -109
- data/lib/z_k/client/drop_box.rb +0 -98
- data/lib/z_k/client/multiplexed.rb +0 -28
- data/lib/z_k/client/threaded.rb +0 -76
- data/lib/z_k/client.rb +0 -35
- data/lib/z_k/event_handler_subscription.rb +0 -36
- data/lib/z_k/extensions.rb +0 -155
- data/lib/z_k/version.rb +0 -3
- data/lib/z_k.rb +0 -97
- data/spec/z_k/client/drop_box_spec.rb +0 -90
- data/spec/z_k/client/multiplexed_spec.rb +0 -20
- data/spec/z_k/client_spec.rb +0 -7
data/lib/z_k/extensions.rb
DELETED
@@ -1,155 +0,0 @@
|
|
1
|
-
module ZK
|
2
|
-
module Extensions
|
3
|
-
# some extensions to the ZookeeperCallbacks classes, mainly convenience
|
4
|
-
# interrogators
|
5
|
-
module Callbacks
|
6
|
-
module Callback
|
7
|
-
# allow access to the connection that fired this callback
|
8
|
-
attr_accessor :zk
|
9
|
-
|
10
|
-
def self.included(mod)
|
11
|
-
mod.extend(ZK::Extensions::Callbacks::Callback::ClassMethods)
|
12
|
-
end
|
13
|
-
|
14
|
-
module ClassMethods
|
15
|
-
# allows for easier construction of a user callback block that will be
|
16
|
-
# called with the callback object itself as an argument.
|
17
|
-
#
|
18
|
-
# *args, if given, will be passed on *after* the callback
|
19
|
-
#
|
20
|
-
# @example
|
21
|
-
#
|
22
|
-
# WatcherCallback.create do |cb|
|
23
|
-
# puts "watcher callback called with argument: #{cb.inspect}"
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# "watcher callback called with argument: #<ZookeeperCallbacks::WatcherCallback:0x1018a3958 @state=3, @type=1, ...>"
|
27
|
-
#
|
28
|
-
#
|
29
|
-
def create(*args, &block)
|
30
|
-
# honestly, i have no idea how this could *possibly* work, but it does...
|
31
|
-
cb_inst = new { block.call(cb_inst) }
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
module WatcherCallbackExt
|
37
|
-
include ZookeeperConstants
|
38
|
-
|
39
|
-
EVENT_NAME_MAP = {
|
40
|
-
1 => 'created',
|
41
|
-
2 => 'deleted',
|
42
|
-
3 => 'changed',
|
43
|
-
4 => 'child',
|
44
|
-
-1 => 'session',
|
45
|
-
-2 => 'notwatching',
|
46
|
-
}.freeze
|
47
|
-
|
48
|
-
STATES = %w[connecting associating connected auth_failed expired_session].freeze unless defined?(STATES)
|
49
|
-
|
50
|
-
EVENT_TYPES = %w[created deleted changed child session notwatching].freeze unless defined?(EVENT_TYPES)
|
51
|
-
|
52
|
-
STATES.each do |state|
|
53
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
54
|
-
def state_#{state}?
|
55
|
-
@state == ZOO_#{state.upcase}_STATE
|
56
|
-
end
|
57
|
-
RUBY
|
58
|
-
end
|
59
|
-
|
60
|
-
EVENT_TYPES.each do |ev|
|
61
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
62
|
-
def node_#{ev}?
|
63
|
-
@type == ZOO_#{ev.upcase}_EVENT
|
64
|
-
end
|
65
|
-
RUBY
|
66
|
-
end
|
67
|
-
|
68
|
-
alias :node_not_watching? :node_notwatching?
|
69
|
-
|
70
|
-
# has this watcher been called because of a change in connection state?
|
71
|
-
def state_event?
|
72
|
-
path.nil? or path.empty?
|
73
|
-
end
|
74
|
-
alias session_event? state_event?
|
75
|
-
|
76
|
-
# has this watcher been called because of a change to a zookeeper node?
|
77
|
-
def node_event?
|
78
|
-
path and not path.empty?
|
79
|
-
end
|
80
|
-
|
81
|
-
# cause this watch to be re-registered
|
82
|
-
# def renew_watch!
|
83
|
-
# zk.stat(path, :watch => true)
|
84
|
-
# nil
|
85
|
-
# end
|
86
|
-
end
|
87
|
-
end # Callbacks
|
88
|
-
|
89
|
-
# aliases for long-names of properties from mb-zookeeper version
|
90
|
-
module Stat
|
91
|
-
[ %w[created_zxid czxid],
|
92
|
-
%w[last_modified_zxid mzxid],
|
93
|
-
%w[created_time ctime],
|
94
|
-
%w[last_modified_time mtime],
|
95
|
-
%w[child_list_version cversion],
|
96
|
-
%w[acl_list_version aversion] ].each do |long, short|
|
97
|
-
|
98
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
99
|
-
def #{long}
|
100
|
-
#{short}
|
101
|
-
end
|
102
|
-
RUBY
|
103
|
-
end
|
104
|
-
|
105
|
-
MEMBERS = [:version, :exists, :czxid, :mzxid, :ctime, :mtime, :cversion, :aversion, :ephemeralOwner, :dataLength, :numChildren, :pzxid]
|
106
|
-
|
107
|
-
def self.included(mod)
|
108
|
-
mod.class_eval do
|
109
|
-
unless method_defined?(:exists?)
|
110
|
-
alias :exists? :exists
|
111
|
-
end
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def ==(other)
|
116
|
-
MEMBERS.all? { |m| self.__send__(m) == other.__send__(m) }
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end # Extensions
|
120
|
-
end # ZK
|
121
|
-
|
122
|
-
# ZookeeperCallbacks::Callback.extend(ZK::Extensions::Callbacks::Callback)
|
123
|
-
ZookeeperCallbacks::Callback.send(:include, ZK::Extensions::Callbacks::Callback)
|
124
|
-
ZookeeperCallbacks::WatcherCallback.send(:include, ZK::Extensions::Callbacks::WatcherCallbackExt)
|
125
|
-
ZookeeperStat::Stat.send(:include, ZK::Extensions::Stat)
|
126
|
-
|
127
|
-
# Include the InterruptedSession module in key ZookeeperExceptions to allow
|
128
|
-
# clients to catch a single error type when waiting on a node (for example)
|
129
|
-
|
130
|
-
[:ConnectionClosed, :NotConnected, :SessionExpired, :SessionMoved, :ConnectionLoss].each do |class_name|
|
131
|
-
ZookeeperExceptions::ZookeeperException.const_get(class_name).tap do |klass|
|
132
|
-
klass.__send__(:include, ZK::Exceptions::InterruptedSession)
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
class ::Exception
|
137
|
-
unless method_defined?(:to_std_format)
|
138
|
-
def to_std_format
|
139
|
-
ary = ["#{self.class}: #{message}"]
|
140
|
-
ary.concat(backtrace || [])
|
141
|
-
ary.join("\n\t")
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
class ::Thread
|
147
|
-
def zk_mongoid_lock_registry
|
148
|
-
self[:_zk_mongoid_lock_registry]
|
149
|
-
end
|
150
|
-
|
151
|
-
def zk_mongoid_lock_registry=(obj)
|
152
|
-
self[:_zk_mongoid_lock_registry] = obj
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
data/lib/z_k/version.rb
DELETED
data/lib/z_k.rb
DELETED
@@ -1,97 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
|
3
|
-
require 'logger'
|
4
|
-
require 'zookeeper'
|
5
|
-
require 'forwardable'
|
6
|
-
require 'thread'
|
7
|
-
require 'monitor'
|
8
|
-
require 'set'
|
9
|
-
|
10
|
-
require 'z_k/logging'
|
11
|
-
require 'z_k/exceptions'
|
12
|
-
require 'z_k/threadpool'
|
13
|
-
require 'z_k/event_handler_subscription'
|
14
|
-
require 'z_k/event_handler'
|
15
|
-
require 'z_k/message_queue'
|
16
|
-
# require 'z_k/locker_base'
|
17
|
-
require 'z_k/locker'
|
18
|
-
require 'z_k/extensions'
|
19
|
-
require 'z_k/election'
|
20
|
-
require 'z_k/mongoid'
|
21
|
-
require 'z_k/client'
|
22
|
-
require 'z_k/pool'
|
23
|
-
require 'z_k/find'
|
24
|
-
|
25
|
-
module ZK
|
26
|
-
ZK_ROOT = File.expand_path('../..', __FILE__)
|
27
|
-
|
28
|
-
KILL_TOKEN = Object.new unless defined?(KILL_TOKEN)
|
29
|
-
|
30
|
-
unless @logger
|
31
|
-
@logger = Logger.new($stderr).tap { |n| n.level = Logger::ERROR }
|
32
|
-
end
|
33
|
-
|
34
|
-
# The logger used by the ZK library. uses a Logger stderr with Logger::ERROR
|
35
|
-
# level. The only thing that should ever be logged are exceptions that are
|
36
|
-
# swallowed by background threads.
|
37
|
-
#
|
38
|
-
# You can change this logger by setting ZK#logger= to an object that
|
39
|
-
# implements the stdllb Logger API.
|
40
|
-
#
|
41
|
-
def self.logger
|
42
|
-
@logger
|
43
|
-
end
|
44
|
-
|
45
|
-
# Assign the Logger instance to be used by ZK
|
46
|
-
def self.logger=(logger)
|
47
|
-
@logger = logger
|
48
|
-
end
|
49
|
-
|
50
|
-
# Create a new ZK::Client instance. If no arguments are given, the default
|
51
|
-
# config of 'localhost:2181' will be used. Otherwise all args will be passed
|
52
|
-
# to ZK::Client#new
|
53
|
-
#
|
54
|
-
# if a block is given, it will be yielded the client *before* the connection
|
55
|
-
# is established, this is useful for registering connected-state handlers.
|
56
|
-
#
|
57
|
-
def self.new(*args, &block)
|
58
|
-
# XXX: might need to do some param parsing here
|
59
|
-
|
60
|
-
opts = args.pop if args.last.kind_of?(Hash)
|
61
|
-
args = %w[localhost:2181] if args.empty?
|
62
|
-
|
63
|
-
# ignore opts for now
|
64
|
-
Client.new(*args, &block)
|
65
|
-
end
|
66
|
-
|
67
|
-
# Like new, yields a connection to the given block and closes it when the
|
68
|
-
# block returns
|
69
|
-
def self.open(*args)
|
70
|
-
cnx = new(*args)
|
71
|
-
yield cnx
|
72
|
-
ensure
|
73
|
-
cnx.close! if cnx
|
74
|
-
end
|
75
|
-
|
76
|
-
# creates a new ZK::Pool::Bounded with the default options.
|
77
|
-
def self.new_pool(host, opts={})
|
78
|
-
ZK::Pool::Bounded.new(host, opts)
|
79
|
-
end
|
80
|
-
|
81
|
-
# Eventually this will implement proper File.join-like behavior, but only
|
82
|
-
# using the '/' char for a separator. for right now, this simply delegates to
|
83
|
-
# File.join
|
84
|
-
#--
|
85
|
-
# like File.join but ignores $INPUT_RECORD_SEPARATOR (i.e. $/, which is
|
86
|
-
# platform dependent) and only uses the '/' character
|
87
|
-
def self.join(*paths)
|
88
|
-
File.join(*paths)
|
89
|
-
end
|
90
|
-
|
91
|
-
protected
|
92
|
-
def self.chomp_sep(str)
|
93
|
-
p = (p[0] == ?/ ) ? p[1..-1] : p
|
94
|
-
p = (p[-1] == ?/) ? p[0..-2] : p
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
@@ -1,90 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module ZK
|
4
|
-
module Client
|
5
|
-
describe 'ZK::Client::DropBox' do
|
6
|
-
let(:drop_box) { DropBox.new }
|
7
|
-
|
8
|
-
after do
|
9
|
-
DropBox.remove_current
|
10
|
-
end
|
11
|
-
|
12
|
-
it %[should start out with an undefined value] do
|
13
|
-
drop_box.value.should == DropBox::UNDEFINED
|
14
|
-
end
|
15
|
-
|
16
|
-
it %[should block the caller waiting for a response] do
|
17
|
-
@rv = nil
|
18
|
-
|
19
|
-
th1 = Thread.new do
|
20
|
-
Thread.current.abort_on_exception = true
|
21
|
-
@rv = drop_box.pop
|
22
|
-
end
|
23
|
-
|
24
|
-
wait_until(2) { th1.status == 'sleep' }
|
25
|
-
|
26
|
-
th1.status.should == 'sleep'
|
27
|
-
|
28
|
-
th2 = Thread.new do
|
29
|
-
drop_box.push :result
|
30
|
-
end
|
31
|
-
|
32
|
-
th2.join(2).should == th2
|
33
|
-
th1.join(2).should == th1
|
34
|
-
|
35
|
-
@rv.should == :result
|
36
|
-
end
|
37
|
-
|
38
|
-
describe :oh_noes! do
|
39
|
-
let(:error_class) { SpecialHappyFuntimeError }
|
40
|
-
let(:error_msg) { 'this is a unique message' }
|
41
|
-
|
42
|
-
it %[should wake the caller by raising the exception class and message given] do
|
43
|
-
drop_box.should_not be_done # sanity check
|
44
|
-
|
45
|
-
th1 = Thread.new do
|
46
|
-
drop_box.pop
|
47
|
-
end
|
48
|
-
|
49
|
-
wait_until(2) { th1.status == 'sleep' }
|
50
|
-
|
51
|
-
th1.status.should == 'sleep'
|
52
|
-
|
53
|
-
drop_box.oh_noes!(error_class, error_msg).should_not be_nil
|
54
|
-
|
55
|
-
lambda { th1.join(2) }.should raise_error(error_class, error_msg)
|
56
|
-
|
57
|
-
drop_box.should be_done
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
describe :done? do
|
62
|
-
it %[should be done if the value is defined] do
|
63
|
-
drop_box.should_not be_done
|
64
|
-
drop_box.push :defined
|
65
|
-
drop_box.should be_done
|
66
|
-
end
|
67
|
-
|
68
|
-
it %[should not be done once cleared] do
|
69
|
-
drop_box.push :defined
|
70
|
-
drop_box.should be_done
|
71
|
-
drop_box.clear
|
72
|
-
drop_box.should_not be_done
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe :with_current do
|
77
|
-
it %[should clear the current thread's drop_box once the block exits] do
|
78
|
-
DropBox.with_current do |c|
|
79
|
-
c.should_not be_done
|
80
|
-
c.push 'yo_mama'
|
81
|
-
c.should be_done
|
82
|
-
end
|
83
|
-
|
84
|
-
DropBox.current.should_not be_done
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe 'ZK::Client::Multiplexed', :client => :multiplexed do
|
4
|
-
before do
|
5
|
-
@zk = ZK::Client::Multiplexed.new("localhost:#{ZK_TEST_PORT}").tap do |zk|
|
6
|
-
wait_until { zk.connected? }
|
7
|
-
end
|
8
|
-
|
9
|
-
@zk.rm_rf('/test')
|
10
|
-
end
|
11
|
-
|
12
|
-
after do
|
13
|
-
@zk.rm_rf('/test')
|
14
|
-
@zk.close!
|
15
|
-
|
16
|
-
wait_until(2) { @zk.closed? }
|
17
|
-
end
|
18
|
-
|
19
|
-
it_should_behave_like 'client'
|
20
|
-
end
|