zk 0.9.1 → 1.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.gitignore +2 -2
  2. data/Gemfile +3 -4
  3. data/README.markdown +14 -5
  4. data/RELEASES.markdown +69 -1
  5. data/Rakefile +50 -18
  6. data/docs/examples/block_until_node_deleted_ex.rb +63 -0
  7. data/docs/examples/events_01.rb +36 -0
  8. data/docs/examples/events_02.rb +41 -0
  9. data/lib/{z_k → zk}/client/base.rb +87 -30
  10. data/lib/{z_k → zk}/client/conveniences.rb +0 -1
  11. data/lib/{z_k → zk}/client/state_mixin.rb +0 -0
  12. data/lib/zk/client/threaded.rb +196 -0
  13. data/lib/{z_k → zk}/client/unixisms.rb +0 -0
  14. data/lib/zk/client.rb +59 -0
  15. data/lib/zk/core_ext.rb +75 -0
  16. data/lib/{z_k → zk}/election.rb +0 -0
  17. data/lib/zk/event.rb +168 -0
  18. data/lib/{z_k → zk}/event_handler.rb +53 -28
  19. data/lib/zk/event_handler_subscription.rb +68 -0
  20. data/lib/{z_k → zk}/exceptions.rb +38 -23
  21. data/lib/zk/extensions.rb +79 -0
  22. data/lib/{z_k → zk}/find.rb +0 -0
  23. data/lib/{z_k → zk}/locker.rb +0 -0
  24. data/lib/{z_k → zk}/logging.rb +0 -0
  25. data/lib/{z_k → zk}/message_queue.rb +8 -4
  26. data/lib/{z_k → zk}/mongoid.rb +0 -0
  27. data/lib/{z_k → zk}/pool.rb +0 -0
  28. data/lib/zk/stat.rb +115 -0
  29. data/lib/{z_k → zk}/threadpool.rb +52 -4
  30. data/lib/zk/version.rb +3 -0
  31. data/lib/zk.rb +238 -1
  32. data/spec/message_queue_spec.rb +2 -2
  33. data/spec/shared/client_contexts.rb +8 -20
  34. data/spec/shared/client_examples.rb +136 -2
  35. data/spec/spec_helper.rb +4 -2
  36. data/spec/support/event_catcher.rb +11 -0
  37. data/spec/support/exist_matcher.rb +6 -0
  38. data/spec/support/logging.rb +2 -1
  39. data/spec/watch_spec.rb +194 -10
  40. data/spec/{z_k → zk}/client/locking_and_session_death_spec.rb +0 -32
  41. data/spec/zk/client_spec.rb +23 -0
  42. data/spec/{z_k → zk}/election_spec.rb +0 -0
  43. data/spec/{z_k → zk}/extensions_spec.rb +0 -0
  44. data/spec/{z_k → zk}/locker_spec.rb +0 -40
  45. data/spec/zk/module_spec.rb +185 -0
  46. data/spec/{z_k → zk}/mongoid_spec.rb +0 -2
  47. data/spec/{z_k → zk}/pool_spec.rb +0 -2
  48. data/spec/{z_k → zk}/threadpool_spec.rb +32 -4
  49. data/spec/zookeeper_spec.rb +1 -6
  50. data/zk.gemspec +2 -2
  51. metadata +64 -56
  52. data/lib/z_k/client/continuation_proxy.rb +0 -109
  53. data/lib/z_k/client/drop_box.rb +0 -98
  54. data/lib/z_k/client/multiplexed.rb +0 -28
  55. data/lib/z_k/client/threaded.rb +0 -76
  56. data/lib/z_k/client.rb +0 -35
  57. data/lib/z_k/event_handler_subscription.rb +0 -36
  58. data/lib/z_k/extensions.rb +0 -155
  59. data/lib/z_k/version.rb +0 -3
  60. data/lib/z_k.rb +0 -97
  61. data/spec/z_k/client/drop_box_spec.rb +0 -90
  62. data/spec/z_k/client/multiplexed_spec.rb +0 -20
  63. data/spec/z_k/client_spec.rb +0 -7
metadata CHANGED
@@ -1,13 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zk
3
3
  version: !ruby/object:Gem::Version
4
- hash: 57
5
- prerelease:
4
+ hash: 1457112361
5
+ prerelease: 6
6
6
  segments:
7
+ - 1
8
+ - 0
7
9
  - 0
8
- - 9
10
+ - rc
9
11
  - 1
10
- version: 0.9.1
12
+ version: 1.0.0.rc.1
11
13
  platform: ruby
12
14
  authors:
13
15
  - Jonathan D. Simms
@@ -16,7 +18,7 @@ autorequire:
16
18
  bindir: bin
17
19
  cert_chain: []
18
20
 
19
- date: 2012-04-26 00:00:00 Z
21
+ date: 2012-04-30 00:00:00 Z
20
22
  dependencies:
21
23
  - !ruby/object:Gem::Dependency
22
24
  name: slyphon-zookeeper
@@ -26,12 +28,12 @@ dependencies:
26
28
  requirements:
27
29
  - - ~>
28
30
  - !ruby/object:Gem::Version
29
- hash: 61
31
+ hash: 63
30
32
  segments:
31
33
  - 0
32
- - 8
33
- - 1
34
- version: 0.8.1
34
+ - 9
35
+ - 2
36
+ version: 0.9.2
35
37
  type: :runtime
36
38
  version_requirements: *id001
37
39
  description: |
@@ -57,30 +59,32 @@ files:
57
59
  - README.markdown
58
60
  - RELEASES.markdown
59
61
  - Rakefile
60
- - lib/z_k.rb
61
- - lib/z_k/client.rb
62
- - lib/z_k/client/base.rb
63
- - lib/z_k/client/continuation_proxy.rb
64
- - lib/z_k/client/conveniences.rb
65
- - lib/z_k/client/drop_box.rb
66
- - lib/z_k/client/multiplexed.rb
67
- - lib/z_k/client/state_mixin.rb
68
- - lib/z_k/client/threaded.rb
69
- - lib/z_k/client/unixisms.rb
70
- - lib/z_k/election.rb
71
- - lib/z_k/event_handler.rb
72
- - lib/z_k/event_handler_subscription.rb
73
- - lib/z_k/exceptions.rb
74
- - lib/z_k/extensions.rb
75
- - lib/z_k/find.rb
76
- - lib/z_k/locker.rb
77
- - lib/z_k/logging.rb
78
- - lib/z_k/message_queue.rb
79
- - lib/z_k/mongoid.rb
80
- - lib/z_k/pool.rb
81
- - lib/z_k/threadpool.rb
82
- - lib/z_k/version.rb
62
+ - docs/examples/block_until_node_deleted_ex.rb
63
+ - docs/examples/events_01.rb
64
+ - docs/examples/events_02.rb
83
65
  - lib/zk.rb
66
+ - lib/zk/client.rb
67
+ - lib/zk/client/base.rb
68
+ - lib/zk/client/conveniences.rb
69
+ - lib/zk/client/state_mixin.rb
70
+ - lib/zk/client/threaded.rb
71
+ - lib/zk/client/unixisms.rb
72
+ - lib/zk/core_ext.rb
73
+ - lib/zk/election.rb
74
+ - lib/zk/event.rb
75
+ - lib/zk/event_handler.rb
76
+ - lib/zk/event_handler_subscription.rb
77
+ - lib/zk/exceptions.rb
78
+ - lib/zk/extensions.rb
79
+ - lib/zk/find.rb
80
+ - lib/zk/locker.rb
81
+ - lib/zk/logging.rb
82
+ - lib/zk/message_queue.rb
83
+ - lib/zk/mongoid.rb
84
+ - lib/zk/pool.rb
85
+ - lib/zk/stat.rb
86
+ - lib/zk/threadpool.rb
87
+ - lib/zk/version.rb
84
88
  - spec/informal/close-in-event-thread.rb
85
89
  - spec/informal/lock_with_dead_session.rb
86
90
  - spec/informal/what-the-fork.rb
@@ -90,6 +94,8 @@ files:
90
94
  - spec/shared/client_examples.rb
91
95
  - spec/spec_helper.rb
92
96
  - spec/support/bogus_mongoid.rb
97
+ - spec/support/event_catcher.rb
98
+ - spec/support/exist_matcher.rb
93
99
  - spec/support/logging.rb
94
100
  - spec/support/logging_progress_bar_formatter.rb
95
101
  - spec/support/queuey_thread.rb
@@ -97,16 +103,15 @@ files:
97
103
  - spec/support/wait_watchers.rb
98
104
  - spec/test_file.txt
99
105
  - spec/watch_spec.rb
100
- - spec/z_k/client/drop_box_spec.rb
101
- - spec/z_k/client/locking_and_session_death_spec.rb
102
- - spec/z_k/client/multiplexed_spec.rb
103
- - spec/z_k/client_spec.rb
104
- - spec/z_k/election_spec.rb
105
- - spec/z_k/extensions_spec.rb
106
- - spec/z_k/locker_spec.rb
107
- - spec/z_k/mongoid_spec.rb
108
- - spec/z_k/pool_spec.rb
109
- - spec/z_k/threadpool_spec.rb
106
+ - spec/zk/client/locking_and_session_death_spec.rb
107
+ - spec/zk/client_spec.rb
108
+ - spec/zk/election_spec.rb
109
+ - spec/zk/extensions_spec.rb
110
+ - spec/zk/locker_spec.rb
111
+ - spec/zk/module_spec.rb
112
+ - spec/zk/mongoid_spec.rb
113
+ - spec/zk/pool_spec.rb
114
+ - spec/zk/threadpool_spec.rb
110
115
  - spec/zookeeper_spec.rb
111
116
  - zk.gemspec
112
117
  homepage: https://github.com/slyphon/zk
@@ -129,12 +134,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
129
134
  required_rubygems_version: !ruby/object:Gem::Requirement
130
135
  none: false
131
136
  requirements:
132
- - - ">="
137
+ - - ">"
133
138
  - !ruby/object:Gem::Version
134
- hash: 3
139
+ hash: 25
135
140
  segments:
136
- - 0
137
- version: "0"
141
+ - 1
142
+ - 3
143
+ - 1
144
+ version: 1.3.1
138
145
  requirements: []
139
146
 
140
147
  rubyforge_project:
@@ -152,6 +159,8 @@ test_files:
152
159
  - spec/shared/client_examples.rb
153
160
  - spec/spec_helper.rb
154
161
  - spec/support/bogus_mongoid.rb
162
+ - spec/support/event_catcher.rb
163
+ - spec/support/exist_matcher.rb
155
164
  - spec/support/logging.rb
156
165
  - spec/support/logging_progress_bar_formatter.rb
157
166
  - spec/support/queuey_thread.rb
@@ -159,14 +168,13 @@ test_files:
159
168
  - spec/support/wait_watchers.rb
160
169
  - spec/test_file.txt
161
170
  - spec/watch_spec.rb
162
- - spec/z_k/client/drop_box_spec.rb
163
- - spec/z_k/client/locking_and_session_death_spec.rb
164
- - spec/z_k/client/multiplexed_spec.rb
165
- - spec/z_k/client_spec.rb
166
- - spec/z_k/election_spec.rb
167
- - spec/z_k/extensions_spec.rb
168
- - spec/z_k/locker_spec.rb
169
- - spec/z_k/mongoid_spec.rb
170
- - spec/z_k/pool_spec.rb
171
- - spec/z_k/threadpool_spec.rb
171
+ - spec/zk/client/locking_and_session_death_spec.rb
172
+ - spec/zk/client_spec.rb
173
+ - spec/zk/election_spec.rb
174
+ - spec/zk/extensions_spec.rb
175
+ - spec/zk/locker_spec.rb
176
+ - spec/zk/module_spec.rb
177
+ - spec/zk/mongoid_spec.rb
178
+ - spec/zk/pool_spec.rb
179
+ - spec/zk/threadpool_spec.rb
172
180
  - spec/zookeeper_spec.rb
@@ -1,109 +0,0 @@
1
- module ZK
2
- module Client
3
- # Wraps calls to zookeeper so that the requests are made asynchronously,
4
- # but still provides a blocking API
5
- #
6
- # @private
7
- class ContinuationProxy
8
- include ZK::Logging
9
-
10
- attr_accessor :zookeeper_cnx
11
-
12
- # @private
13
- def self.call_with_continuation(*syms)
14
- syms.each do |sym|
15
- class_eval(<<-EOS, __FILE__, __LINE__+1)
16
- def #{sym}(opts)
17
- logger.debug { "_call_continue(#{sym.inspect}, \#{opts.inspect})" }
18
- _call_continue(#{sym.inspect}, opts)
19
- end
20
- EOS
21
- end
22
- end
23
-
24
- call_with_continuation :get, :set, :stat, :children, :delete, :get_acl, :set_acl
25
-
26
- def initialize(zookeeper_cnx=nil)
27
- @zookeeper_cnx = zookeeper_cnx
28
- @mutex = Mutex.new
29
- @dropboxen = []
30
- end
31
-
32
- # create is "special" because the return hash doesn't have a :path, it has a :string
33
- def create(opts)
34
- logger.debug { "_call_continue(create, #{opts.inspect})" }
35
- _call_continue(:create, opts).tap do |rval|
36
- rval[:path] = rval.delete(:string)
37
- end
38
- end
39
-
40
- # called by the multiplxed client to wake up threads that are waiting for
41
- # results (with an exception)
42
- # @private
43
- def connection_closed!
44
- _oh_noes(ZookeeperExceptions::ZookeeperException::NotConnected, 'connection closed')
45
- end
46
-
47
- # called by the multiplxed client to wake up threads that are waiting for
48
- # results (with an exception)
49
- # @private
50
- def expired_session!
51
- _oh_noes(ZookeeperExceptions::ZookeeperException::SessionExpired, 'session expired')
52
- end
53
-
54
- private
55
- def method_missing(m, *a, &b)
56
- @zookeeper_cnx.respond_to?(m) ? @zookeeper_cnx.__send__(m, *a, &b) : super
57
- end
58
-
59
- def _oh_noes(exception, message)
60
- @mutex.synchronize do
61
- @dropboxen.each do |db|
62
- db.oh_noes!(exception, message)
63
- end
64
- end
65
- end
66
-
67
- # not really callcc, but close enough
68
- # opts should be an options hash as passed through to the Zookeeper
69
- # layer
70
- def _call_continue(meth, opts)
71
- _assert_not_async!(meth, opts)
72
-
73
- opts = opts.dup
74
-
75
- _with_drop_box do |db|
76
- cb = lambda do |hash|
77
- # logger.debug { "#{self.class}##{__method__} block pushing: #{hash.inspect}" }
78
- db.push(hash)
79
- end
80
-
81
- opts[:callback] = cb
82
-
83
- @zookeeper_cnx.__send__(meth, opts)
84
-
85
- # db.pop.tap do |obj|
86
- # logger.debug { "#{self.class}##{__method__} popped and returning: #{obj.inspect}" }
87
- # end
88
-
89
- db.pop
90
- end
91
- end
92
-
93
- def _with_drop_box
94
- db = DropBox.current
95
- @mutex.synchronize { @dropboxen << db }
96
- yield db
97
- ensure
98
- @mutex.synchronize { @dropboxen.delete(db) }
99
- db.clear
100
- end
101
-
102
- def _assert_not_async!(meth, opts)
103
- return unless opts.has_key?(:callback)
104
- raise ArgumentError, "you cannot use async callbacks with a Multiplexed client! meth: #{meth.inspect}, opts: #{opts.inspect}"
105
- end
106
- end # ContinuationProxy
107
- end
108
- end
109
-
@@ -1,98 +0,0 @@
1
- module ZK
2
- module Client
3
- # A simple threadsafe way of having a thread deliver a single value
4
- # to another thread.
5
- #
6
- # Each thread making requests will have a thread-local continuation
7
- # that can be accessed via DropBox.current and one can use
8
- # DropBox.with_current that will clear the result once the given block
9
- # exits (allowing for reuse)
10
- #
11
- # (this class is in no way related to dropbox.com or Dropbox Inc.)
12
- # @private
13
- class DropBox
14
- UNDEFINED = Object.new unless defined?(UNDEFINED)
15
- KILL_TOKEN = Object.new unless defined?(KILL_TOKEN)
16
- IMPOSSIBLE_TO_CONTINUE = Object.new unless defined?(IMPOSSIBLE_TO_CONTINUE)
17
-
18
- # represents an exception to raise. if the pop method sees the value as an instance
19
- # of this class, it will call the raise! method
20
- class ExceptionValue
21
- def initialize(exception_class, message)
22
- @exception_class, @message = exception_class, message
23
- end
24
-
25
- def raise!
26
- raise @exception_class, @message
27
- end
28
- end
29
-
30
- THREAD_LOCAL_KEY = :__zk_client_continuation_current__ unless defined?(THREAD_LOCAL_KEY)
31
-
32
- # @private
33
- attr_reader :value
34
-
35
- # sets the thread-local instance to nil, used by tests
36
- # @private
37
- def self.remove_current
38
- Thread.current[THREAD_LOCAL_KEY] = nil
39
- end
40
-
41
- # access the thread-local DropBox instance for the current thread
42
- def self.current
43
- Thread.current[THREAD_LOCAL_KEY] ||= self.new()
44
- end
45
-
46
- # yields the current thread's DropBox instance and clears its value
47
- # after the block returns
48
- def self.with_current
49
- yield current
50
- ensure
51
- current.clear
52
- end
53
-
54
- def initialize
55
- @mutex = Mutex.new
56
- @cond = ConditionVariable.new
57
- @value = UNDEFINED # allows us to return nil
58
- end
59
-
60
- def push(obj)
61
- @mutex.synchronize do
62
- @value = obj
63
- @cond.signal
64
- end
65
- end
66
-
67
- def pop
68
- @mutex.synchronize do
69
- @cond.wait(@mutex)
70
- @value.kind_of?(ExceptionValue) ? @value.raise! : @value
71
- end
72
- end
73
-
74
- def clear
75
- @mutex.synchronize do
76
- @value = UNDEFINED
77
- end
78
- end
79
-
80
- # we are done if value is defined, use clear to reset
81
- def done?
82
- @value != UNDEFINED
83
- end
84
-
85
- # called when you need the waiting thread to receive an exception
86
- # returns nil if a value has already been set
87
- def oh_noes!(exception_class, message)
88
- @mutex.synchronize do
89
- return if done?
90
- @value = ExceptionValue.new(exception_class, message)
91
- @cond.signal
92
- end
93
- true
94
- end
95
- end
96
- end
97
- end
98
-
@@ -1,28 +0,0 @@
1
- module ZK
2
- module Client
3
- # This client is an experimental implementation of a threaded and
4
- # multiplexed client. The idea is that each synchronous request represents
5
- # a continuation. This way, you can have multiple requests pending with the
6
- # server simultaneously, and the responses will be delivered on the event
7
- # thread (but run in the calling thread). This allows for higher throughput
8
- # for multi-threaded applications.
9
- #
10
- # Asynchronous requests are not supported through this client.
11
- #
12
- class Multiplexed < Threaded
13
- def close!
14
- @cnx.connection_closed!
15
- super
16
- end
17
-
18
- protected
19
- def create_connection(*args)
20
- ContinuationProxy.new.tap do |cp|
21
- on_expired_session { cp.expired_session! } # hook up client's session expired event listener
22
- cp.zookeeper_cnx = super(*args)
23
- end
24
- end
25
- end
26
- end
27
- end
28
-
@@ -1,76 +0,0 @@
1
- module ZK
2
- module Client
3
- # This is the default client that ZK will use. In the zk-eventmachine gem,
4
- # there is an Evented client.
5
- #
6
- class Threaded < Base
7
- include StateMixin
8
- include Unixisms
9
- include Conveniences
10
-
11
- DEFAULT_THREADPOOL_SIZE = 1
12
-
13
- # @note The `:timeout` argument here is *not* the session_timeout for the
14
- # connection. rather it is the amount of time we wait for the connection
15
- # to be established. The session timeout exchanged with the server is
16
- # set to 10s by default in the C implemenation, and as of version 0.8.0
17
- # of slyphon-zookeeper has yet to be exposed as an option. That feature
18
- # is planned.
19
- #
20
- # @param [String] host (see ZK::Client::Base#initialize)
21
- #
22
- # @option opts [Fixnum] :threadpool_size the size of the threadpool that
23
- # should be used to deliver events. In ZK 0.8.x this was set to 5, which
24
- # means that events could be delivered concurrently. As of 0.9, this will
25
- # be set to 1, so it's very important to _not block the event thread_.
26
- #
27
- # @option opts [Fixnum] :timeout how long we will wait for the connection
28
- # to be established.
29
- #
30
- # @yield [self] calls the block with the new instance after the event
31
- # handler has been set up, but before any connections have been made.
32
- # This allows the client to register watchers for session events like
33
- # `connected`. You *cannot* perform any other operations with the client
34
- # as you will get a NoMethodError (the underlying connection is nil).
35
- #
36
- def initialize(host, opts={}, &b)
37
- super(host, opts)
38
-
39
- @session_timeout = opts.fetch(:timeout, DEFAULT_TIMEOUT) # maybe move this into superclass?
40
- @event_handler = EventHandler.new(self)
41
-
42
- yield self if block_given?
43
-
44
- @cnx = create_connection(host, @session_timeout, @event_handler.get_default_watcher_block)
45
-
46
- tp_size = opts.fetch(:threadpool_size, DEFAULT_THREADPOOL_SIZE)
47
-
48
- @threadpool = Threadpool.new(tp_size)
49
- end
50
-
51
- # @see ZK::Client::Base#close!
52
- def close!
53
- if event_dispatch_thread?
54
- msg = ["ZK ERROR: You called #{self.class}#close! on the event dispatch thread!!",
55
- "This will cause the client to deadlock and possibly your main thread as well!"]
56
-
57
- warn_msg = [nil, msg, nil, "See ZK error log output (stderr by default) for a backtrace", nil].join("\n")
58
-
59
- Kernel.warn(warn_msg)
60
- assert_we_are_not_on_the_event_dispatch_thread!(msg.join(' '))
61
- end
62
-
63
- @threadpool.shutdown
64
- super
65
- nil
66
- end
67
-
68
- protected
69
- # allows for the Mutliplexed client to wrap the connection in its ContinuationProxy
70
- # @private
71
- def create_connection(*args)
72
- ::Zookeeper.new(*args)
73
- end
74
- end
75
- end
76
- end
data/lib/z_k/client.rb DELETED
@@ -1,35 +0,0 @@
1
- module ZK
2
- # A ruby-friendly wrapper around the low-level zookeeper drivers. This is the
3
- # class that you will likely interact with the most.
4
- #
5
- # @todo ACL support is pretty much unused currently.
6
- # If anyone has suggestions, hints, use-cases, examples, etc. by all means please file a bug.
7
- #
8
- module Client
9
- DEFAULT_TIMEOUT = 10
10
-
11
- # @private
12
- STATE_SYM_MAP = {
13
- Zookeeper::ZOO_CLOSED_STATE => :closed,
14
- Zookeeper::ZOO_EXPIRED_SESSION_STATE => :expired_session,
15
- Zookeeper::ZOO_AUTH_FAILED_STATE => :auth_failed,
16
- Zookeeper::ZOO_CONNECTING_STATE => :connecting,
17
- Zookeeper::ZOO_CONNECTED_STATE => :connected,
18
- Zookeeper::ZOO_ASSOCIATING_STATE => :associating,
19
- }.freeze
20
-
21
- def self.new(*a, &b)
22
- Threaded.new(*a, &b)
23
- end
24
- end
25
- end
26
-
27
- require 'z_k/client/drop_box'
28
- require 'z_k/client/state_mixin'
29
- require 'z_k/client/unixisms'
30
- require 'z_k/client/conveniences'
31
- require 'z_k/client/base'
32
- require 'z_k/client/threaded'
33
- require 'z_k/client/continuation_proxy'
34
- require 'z_k/client/multiplexed'
35
-
@@ -1,36 +0,0 @@
1
- module ZK
2
- # the subscription object that is passed back from subscribing
3
- # to events.
4
- # @see ZK::Client::Base#register
5
- class EventHandlerSubscription
6
- # the event handler associated with this subscription
7
- # @return [EventHandler]
8
- attr_accessor :event_handler
9
-
10
- # the path this subscription is for
11
- # @return [String]
12
- attr_accessor :path
13
-
14
- # the block associated with the path
15
- # @return [Proc]
16
- attr_accessor :callback
17
-
18
- # @private
19
- def initialize(event_handler, path, callback)
20
- @event_handler, @path, @callback = event_handler, path, callback
21
- end
22
-
23
- # unsubscribe from the path or state you were watching
24
- # @see ZK::Client::Base#register
25
- def unsubscribe
26
- @event_handler.unregister(self)
27
- end
28
- alias :unregister :unsubscribe
29
-
30
- # @private
31
- def call(event)
32
- callback.call(event)
33
- end
34
- end
35
- end
36
-