zookeeper-ng 1.5

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.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/.ctags_paths +1 -0
  3. data/.dotfiles/ruby-gemset +1 -0
  4. data/.dotfiles/ruby-version +1 -0
  5. data/.dotfiles/rvmrc +2 -0
  6. data/.gitignore +19 -0
  7. data/.gitmodules +3 -0
  8. data/.travis.yml +25 -0
  9. data/CHANGELOG +395 -0
  10. data/Gemfile +30 -0
  11. data/Guardfile +8 -0
  12. data/LICENSE +23 -0
  13. data/Manifest +29 -0
  14. data/README.markdown +85 -0
  15. data/Rakefile +121 -0
  16. data/cause-abort.rb +117 -0
  17. data/ext/.gitignore +6 -0
  18. data/ext/Rakefile +41 -0
  19. data/ext/c_zookeeper.rb +398 -0
  20. data/ext/common.h +17 -0
  21. data/ext/dbg.h +53 -0
  22. data/ext/depend +5 -0
  23. data/ext/event_lib.c +740 -0
  24. data/ext/event_lib.h +175 -0
  25. data/ext/extconf.rb +103 -0
  26. data/ext/generate_gvl_code.rb +321 -0
  27. data/ext/patches/zkc-3.3.5-network.patch +24 -0
  28. data/ext/patches/zkc-3.4.5-fetch-and-add.patch +16 -0
  29. data/ext/patches/zkc-3.4.5-logging.patch +41 -0
  30. data/ext/patches/zkc-3.4.5-out-of-order-ping.patch +163 -0
  31. data/ext/patches/zkc-3.4.5-overflow.patch +11 -0
  32. data/ext/patches/zkc-3.4.5-yosemite-htonl-fix.patch +102 -0
  33. data/ext/zkc-3.4.5.tar.gz +0 -0
  34. data/ext/zkrb.c +1075 -0
  35. data/ext/zkrb_wrapper.c +775 -0
  36. data/ext/zkrb_wrapper.h +350 -0
  37. data/ext/zkrb_wrapper_compat.c +15 -0
  38. data/ext/zkrb_wrapper_compat.h +11 -0
  39. data/ext/zookeeper_base.rb +256 -0
  40. data/java/java_base.rb +503 -0
  41. data/lib/zookeeper.rb +115 -0
  42. data/lib/zookeeper/acls.rb +44 -0
  43. data/lib/zookeeper/callbacks.rb +108 -0
  44. data/lib/zookeeper/client.rb +30 -0
  45. data/lib/zookeeper/client_methods.rb +282 -0
  46. data/lib/zookeeper/common.rb +122 -0
  47. data/lib/zookeeper/common/queue_with_pipe.rb +110 -0
  48. data/lib/zookeeper/compatibility.rb +138 -0
  49. data/lib/zookeeper/constants.rb +97 -0
  50. data/lib/zookeeper/continuation.rb +223 -0
  51. data/lib/zookeeper/core_ext.rb +58 -0
  52. data/lib/zookeeper/em_client.rb +55 -0
  53. data/lib/zookeeper/exceptions.rb +135 -0
  54. data/lib/zookeeper/forked.rb +19 -0
  55. data/lib/zookeeper/latch.rb +34 -0
  56. data/lib/zookeeper/logger.rb +39 -0
  57. data/lib/zookeeper/logger/forwarding_logger.rb +84 -0
  58. data/lib/zookeeper/monitor.rb +19 -0
  59. data/lib/zookeeper/rake_tasks.rb +165 -0
  60. data/lib/zookeeper/request_registry.rb +153 -0
  61. data/lib/zookeeper/stat.rb +21 -0
  62. data/lib/zookeeper/version.rb +4 -0
  63. data/notes.txt +14 -0
  64. data/scripts/upgrade-1.0-sed-alike.rb +46 -0
  65. data/spec/c_zookeeper_spec.rb +51 -0
  66. data/spec/chrooted_connection_spec.rb +83 -0
  67. data/spec/compatibilty_spec.rb +8 -0
  68. data/spec/default_watcher_spec.rb +41 -0
  69. data/spec/em_spec.rb +51 -0
  70. data/spec/ext/zookeeper_base_spec.rb +19 -0
  71. data/spec/forked_connection_spec.rb +124 -0
  72. data/spec/latch_spec.rb +24 -0
  73. data/spec/log4j.properties +17 -0
  74. data/spec/shared/all_success_return_values.rb +10 -0
  75. data/spec/shared/connection_examples.rb +1077 -0
  76. data/spec/spec_helper.rb +61 -0
  77. data/spec/support/00_logging.rb +38 -0
  78. data/spec/support/10_spawn_zookeeper.rb +24 -0
  79. data/spec/support/progress_formatter.rb +15 -0
  80. data/spec/support/zookeeper_spec_helpers.rb +96 -0
  81. data/spec/zookeeper_spec.rb +24 -0
  82. data/zookeeper.gemspec +38 -0
  83. data/zoomonkey/duplicates +3 -0
  84. data/zoomonkey/zoomonkey.rb +194 -0
  85. metadata +157 -0
@@ -0,0 +1,122 @@
1
+ require 'zookeeper/exceptions'
2
+ require 'zookeeper/common/queue_with_pipe'
3
+
4
+ module Zookeeper
5
+ module Common
6
+ def event_dispatch_thread?
7
+ @dispatcher && (@dispatcher == Thread.current)
8
+ end
9
+
10
+ private
11
+ def setup_dispatch_thread!
12
+ @mutex.synchronize do
13
+ if @dispatcher
14
+ logger.debug { "dispatcher already running" }
15
+ return
16
+ end
17
+
18
+ logger.debug { "starting dispatch thread" }
19
+
20
+ @dispatcher = Thread.new(&method(:dispatch_thread_body))
21
+ end
22
+ end
23
+
24
+ # this method is part of the reopen/close code, and is responsible for
25
+ # shutting down the dispatch thread.
26
+ #
27
+ # @dispatcher will be nil when this method exits
28
+ #
29
+ def stop_dispatch_thread!(timeout=2)
30
+ logger.debug { "#{self.class}##{__method__}" }
31
+
32
+ if @dispatcher
33
+ if @dispatcher.join(0)
34
+ @dispatcher = nil
35
+ return
36
+ end
37
+
38
+ @mutex.synchronize do
39
+ event_queue.graceful_close!
40
+
41
+ # we now release the mutex so that dispatch_next_callback can grab it
42
+ # to do what it needs to do while delivering events
43
+ #
44
+ @dispatch_shutdown_cond.wait
45
+
46
+ # wait for another timeout sec for the thread to join
47
+ until @dispatcher.join(timeout)
48
+ logger.error { "Dispatch thread did not join cleanly, waiting" }
49
+ end
50
+ @dispatcher = nil
51
+ end
52
+ end
53
+ end
54
+
55
+ def get_next_event(blocking=true)
56
+ @event_queue.pop(!blocking).tap do |event|
57
+ logger.debug { "#{self.class}##{__method__} delivering event #{event.inspect}" }
58
+ end
59
+ rescue ThreadError
60
+ nil
61
+ end
62
+
63
+ def dispatch_next_callback(hash)
64
+ return nil unless hash
65
+
66
+ logger.debug { "get_next_event returned: #{prettify_event(hash).inspect}" }
67
+
68
+ is_completion = hash.has_key?(:rc)
69
+
70
+ hash[:stat] = Zookeeper::Stat.new(hash[:stat]) if hash.has_key?(:stat)
71
+ hash[:acl] = hash[:acl].map { |acl| Zookeeper::ACLs::ACL.new(acl) } if hash[:acl]
72
+
73
+ callback_context = @req_registry.get_context_for(hash)
74
+
75
+ if callback_context
76
+ callback = is_completion ? callback_context[:callback] : callback_context[:watcher]
77
+
78
+ hash[:context] = callback_context[:context]
79
+
80
+ if callback.respond_to?(:call)
81
+ callback.call(hash)
82
+ else
83
+ # puts "dispatch_next_callback found non-callback => #{callback.inspect}"
84
+ end
85
+ else
86
+ logger.warn { "Duplicate event received (no handler for req_id #{hash[:req_id]}, event: #{hash.inspect}" }
87
+ end
88
+ true
89
+ end
90
+
91
+ def dispatch_thread_body
92
+ while true
93
+ begin
94
+ dispatch_next_callback(get_next_event(true))
95
+ rescue QueueWithPipe::ShutdownException
96
+ logger.info { "dispatch thread exiting, got shutdown exception" }
97
+ return
98
+ rescue Exception => e
99
+ $stderr.puts ["#{e.class}: #{e.message}", e.backtrace.map { |n| "\t#{n}" }.join("\n")].join("\n")
100
+ end
101
+ end
102
+ ensure
103
+ signal_dispatch_thread_exit!
104
+ end
105
+
106
+ def signal_dispatch_thread_exit!
107
+ @mutex.synchronize do
108
+ logger.debug { "dispatch thread exiting!" }
109
+ @dispatch_shutdown_cond.broadcast
110
+ end
111
+ end
112
+
113
+ def prettify_event(hash)
114
+ hash.dup.tap do |h|
115
+ # pretty up the event display
116
+ h[:type] = Zookeeper::Constants::EVENT_TYPE_NAMES.fetch(h[:type]) if h[:type]
117
+ h[:state] = Zookeeper::Constants::STATE_NAMES.fetch(h[:state]) if h[:state]
118
+ h[:req_id] = :global_session if h[:req_id] == -1
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,110 @@
1
+ module Zookeeper
2
+ module Common
3
+ # Ceci n'est pas une pipe
4
+ class QueueWithPipe
5
+ extend Forwardable
6
+ include Logger
7
+
8
+ # raised when close has been called, and pop() is performed
9
+ #
10
+ class ShutdownException < StandardError; end
11
+
12
+ # @private
13
+ KILL_TOKEN = Object.new unless defined?(KILL_TOKEN)
14
+
15
+ def initialize
16
+ @array = []
17
+
18
+ @mutex = Mutex.new
19
+ @cond = ConditionVariable.new
20
+ @closed = false
21
+ @graceful = false
22
+ end
23
+
24
+ def clear
25
+ @mutex.lock
26
+ begin
27
+ @array.clear
28
+ ensure
29
+ @mutex.unlock rescue nil
30
+ end
31
+ end
32
+
33
+ def push(obj)
34
+ @mutex.lock
35
+ begin
36
+ # raise ShutdownException if (@closed or @graceful)
37
+ @array << obj
38
+ @cond.signal
39
+ ensure
40
+ @mutex.unlock rescue nil
41
+ end
42
+ end
43
+
44
+ def pop(non_blocking=false)
45
+ rval = nil
46
+
47
+ @mutex.lock
48
+ begin
49
+
50
+ begin
51
+ raise ShutdownException if @closed # this may get us in trouble
52
+
53
+ rval = @array.shift
54
+
55
+ unless rval
56
+ raise ThreadError if non_blocking # sigh, ruby's stupid behavior
57
+ raise ShutdownException if @graceful # we've processed all the remaining mesages
58
+
59
+ @cond.wait(@mutex) until (@closed or @graceful or (@array.length > 0))
60
+ end
61
+ end until rval
62
+
63
+ return rval
64
+
65
+ ensure
66
+ @mutex.unlock rescue nil
67
+ end
68
+ end
69
+
70
+ # close the queue and causes ShutdownException to be raised on waiting threads
71
+ def graceful_close!
72
+ @mutex.lock
73
+ begin
74
+ return if @graceful or @closed
75
+ logger.debug { "#{self.class}##{__method__} gracefully closing" }
76
+ @graceful = true
77
+ @cond.broadcast
78
+ ensure
79
+ @mutex.unlock rescue nil
80
+ end
81
+ nil
82
+ end
83
+
84
+ def open
85
+ @mutex.lock
86
+ begin
87
+ @closed = @graceful = false
88
+ @cond.broadcast
89
+ ensure
90
+ @mutex.unlock rescue nil
91
+ end
92
+ end
93
+
94
+ def close
95
+ @mutex.lock
96
+ begin
97
+ return if @closed
98
+ @closed = true
99
+ @cond.broadcast
100
+ ensure
101
+ @mutex.unlock rescue nil
102
+ end
103
+ end
104
+
105
+ def closed?
106
+ @mutex.synchronize { !!@closed }
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,138 @@
1
+ module Zookeeper
2
+ # @private
3
+ def self.warn_about_compatability_once!
4
+ return if @warned_about_compatibility
5
+ @warned_about_compatibility = true
6
+
7
+ warn <<-EOS
8
+
9
+ -----------------------------------------------------------------------------
10
+
11
+ NOTICE: ZOOKEEPER BACKWARDS COMPATIBILTY EANBLED!!
12
+
13
+ THIS WILL NOT BE AUTOMATIC IN 1.1 !!
14
+
15
+ There was a major change to the organization of the Zookeeper gem between
16
+ 0.9 and 1.0, breaking backwards compatibility. To ease the transition,
17
+
18
+ #{__FILE__}
19
+
20
+ is automatically required. This will *not* be the case in 1.1.
21
+
22
+ -----------------------------------------------------------------------------
23
+ EOS
24
+ end
25
+
26
+ def self.warned_about_compatability?
27
+ !!@warned_about_compatability
28
+ end
29
+ end
30
+
31
+ # at request of @eric
32
+ #Zookeeper.warn_about_compatability_once!
33
+
34
+ module Zookeeper
35
+ module Compatibility
36
+ def clean_backtrace
37
+ caller[0..-2].reject {|n| n =~ %r%/rspec/|\(eval\)|const_missing% }.map { |n| "\t#{n}" }.join("\n")
38
+ end
39
+ end
40
+ end
41
+
42
+ module ZookeeperConstants
43
+ include Zookeeper::Constants
44
+ end
45
+
46
+ module ZookeeperCallbacks
47
+ include Zookeeper::Callbacks
48
+ Callback = Base
49
+ end
50
+
51
+ module ZookeeperExceptions
52
+ include Zookeeper::Exceptions
53
+ end
54
+
55
+ module ZookeeperStat
56
+ extend Zookeeper::Compatibility
57
+ def self.const_missing(sym)
58
+ if sym == :Stat
59
+ warn "\nZookeeperStat::Stat is now Zookeeper::Stat, please update your code!\n#{clean_backtrace}"
60
+ # self.const_set(sym, Zookeeper::Stat)
61
+ Zookeeper::Stat
62
+ else
63
+ super
64
+ end
65
+ end
66
+ end
67
+
68
+ module ZookeeperACLs
69
+ extend Zookeeper::Compatibility
70
+ def self.const_missing(sym)
71
+ candidates = [Zookeeper::ACLs, Zookeeper::Constants, Zookeeper::ACLs::Constants]
72
+
73
+ candidates.each do |candidate|
74
+ if candidate.const_defined?(sym)
75
+ warn "\n#{self.name}::#{sym} is now located in #{candidate}::#{sym}, please update your code!\n#{clean_backtrace}"
76
+
77
+ c = candidate.const_get(sym)
78
+ # self.const_set(sym, c)
79
+ return c
80
+ end
81
+ end
82
+
83
+ super
84
+ end
85
+ end
86
+
87
+ module ZookeeperCommon
88
+ include Zookeeper::Common
89
+ extend Zookeeper::Compatibility
90
+
91
+ def self.const_missing(sym)
92
+ candidate = Zookeeper::Common
93
+
94
+ if candidate.const_defined?(sym)
95
+ warn "\n#{self.name}::#{sym} is now located in #{candidate}::#{sym}, please update your code!\n#{clean_backtrace}"
96
+
97
+ candidate.const_get(sym).tap do |c|
98
+ # self.const_set(sym, c)
99
+ end
100
+ else
101
+ super
102
+ end
103
+ end
104
+
105
+ end
106
+
107
+ # module Zookeeper
108
+ # include ZookeeperConstants
109
+ # include ZookeeperCallbacks
110
+ # include ZookeeperExceptions
111
+ # include ZookeeperCommon
112
+ # include ZookeeperStat
113
+ # include ZookeeperACLs
114
+ # end
115
+
116
+ module Zookeeper
117
+ extend Zookeeper::Compatibility
118
+ def self.const_missing(sym)
119
+ candidate =
120
+ case sym.to_s
121
+ when /Callback/
122
+ Zookeeper::Callbacks
123
+ end
124
+
125
+ super unless candidate
126
+
127
+ if candidate.const_defined?(sym)
128
+ warn "\n#{self.name}::#{sym} is now located in #{candidate}::#{sym}, please update your code!\n#{clean_backtrace}"
129
+
130
+ candidate.const_get(sym).tap do |c|
131
+ # self.const_set(sym, c)
132
+ end
133
+ else
134
+ super
135
+ end
136
+ end
137
+ end
138
+
@@ -0,0 +1,97 @@
1
+ module Zookeeper
2
+ module Constants
3
+ include ACLs::Constants
4
+
5
+ # file type masks
6
+ ZOO_EPHEMERAL = 1
7
+ ZOO_SEQUENCE = 2
8
+
9
+ # session state
10
+ ZOO_EXPIRED_SESSION_STATE = -112
11
+ ZOO_AUTH_FAILED_STATE = -113
12
+ ZOO_CLOSED_STATE = 0
13
+ ZOO_CONNECTING_STATE = 1
14
+ ZOO_ASSOCIATING_STATE = 2
15
+ ZOO_CONNECTED_STATE = 3
16
+
17
+ # watch types
18
+ ZOO_CREATED_EVENT = 1
19
+ ZOO_DELETED_EVENT = 2
20
+ ZOO_CHANGED_EVENT = 3
21
+ ZOO_CHILD_EVENT = 4
22
+ ZOO_SESSION_EVENT = -1
23
+ ZOO_NOTWATCHING_EVENT = -2
24
+
25
+ # only used by the C extension
26
+ ZOO_LOG_LEVEL_ERROR = 1
27
+ ZOO_LOG_LEVEL_WARN = 2
28
+ ZOO_LOG_LEVEL_INFO = 3
29
+ ZOO_LOG_LEVEL_DEBUG = 4
30
+
31
+ # exceptions/errors
32
+ ZOK = 0
33
+ ZSYSTEMERROR = -1
34
+ ZRUNTIMEINCONSISTENCY = -2
35
+ ZDATAINCONSISTENCY = -3
36
+ ZCONNECTIONLOSS = -4
37
+ ZMARSHALLINGERROR = -5
38
+ ZUNIMPLEMENTED = -6
39
+ ZOPERATIONTIMEOUT = -7
40
+ ZBADARGUMENTS = -8
41
+ ZINVALIDSTATE = -9
42
+
43
+ # api errors
44
+ ZAPIERROR = -100
45
+ ZNONODE = -101
46
+ ZNOAUTH = -102
47
+ ZBADVERSION = -103
48
+ ZNOCHILDRENFOREPHEMERALS = -108
49
+ ZNODEEXISTS = -110
50
+ ZNOTEMPTY = -111
51
+ ZSESSIONEXPIRED = -112
52
+ ZINVALIDCALLBACK = -113
53
+ ZINVALIDACL = -114
54
+ ZAUTHFAILED = -115
55
+ ZCLOSING = -116
56
+ ZNOTHING = -117
57
+ ZSESSIONMOVED = -118
58
+
59
+ ZKRB_GLOBAL_CB_REQ = -1
60
+ ZKRB_ASYNC_CONTN_ID = -2
61
+
62
+ # @private
63
+ CONNECTED_EVENT_VALUES = [Constants::ZKRB_GLOBAL_CB_REQ,
64
+ Constants::ZOO_SESSION_EVENT,
65
+ Constants::ZOO_CONNECTED_STATE].freeze
66
+
67
+ # used to find the name for a numeric event
68
+ # @private
69
+ EVENT_TYPE_NAMES = {
70
+ 1 => 'created',
71
+ 2 => 'deleted',
72
+ 3 => 'changed',
73
+ 4 => 'child',
74
+ -1 => 'session',
75
+ -2 => 'notwatching',
76
+ }
77
+
78
+ # used to pretty print the state name
79
+ # @private
80
+ STATE_NAMES = {
81
+ -112 => 'expired_session',
82
+ -113 => 'auth_failed',
83
+ 0 => 'closed',
84
+ 1 => 'connecting',
85
+ 2 => 'associating',
86
+ 3 => 'connected',
87
+ }
88
+
89
+ def event_by_value(v)
90
+ (name = EVENT_TYPE_NAMES[v]) ? "ZOO_#{name.upcase}_EVENT" : ''
91
+ end
92
+
93
+ def state_by_value(v)
94
+ (name = STATE_NAMES[v]) ? "ZOO_#{name.upcase}_STATE" : ''
95
+ end
96
+ end
97
+ end