zookeeper-ng 1.5

Sign up to get free protection for your applications and to get access to all the features.
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