carlosnz-zookeeper 0.2

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/README ADDED
@@ -0,0 +1,70 @@
1
+ zookeeper
2
+ by Shane Mingins
3
+ http://github.com/smingins/zookeeper/tree/master
4
+
5
+ == DESCRIPTION:
6
+
7
+ Ruby Interface to Yahoo's ZooKeeper http://zookeeper.wiki.sourceforge.net/
8
+
9
+
10
+ == FEATURES/PROBLEMS:
11
+
12
+ Work in progress -- most of the needed ZooKeeper methods have been supported.
13
+ Queue was a hacked copy from the Java Tutorial on the site --- will refactor into a useable Recipe at some point.
14
+ ACL issues exist in ZooKeeper that have been patched, but patch only seems to work on trunk (Revision 176). See https://issues.apache.org/jira/browse/ZOOKEEPER-48
15
+
16
+ == TODO
17
+
18
+ Extend support for Ruby using ZooKeeper C API's
19
+
20
+ == SYNOPSIS:
21
+
22
+ Given a running ZooKeeper server listening for a client connection on port 2181:
23
+
24
+ zk = ZooKeeper.new(:host => "localhost:2181")
25
+ zk.create(:path => "/test", :data => "test_data")
26
+
27
+ See spec/zookeeper_spec for expected use and behaviour.
28
+
29
+ == REQUIREMENTS:
30
+
31
+ ZooKeeper installed and running.
32
+
33
+ I built zookeeper from source with the ACL patch https://issues.apache.org/jira/secure/attachment/12384350/acl_3.patch applied
34
+
35
+ For MRI version, ZooKeeper C client library (http://zookeeper.sourceforge.net/)
36
+
37
+ == INSTALL:
38
+
39
+ gem install smingins-zookeeper --source=http://gems.github.com/
40
+
41
+ jruby -S gem install smingins-zookeeper --source=http://gems.github.com/
42
+
43
+ == TESTS:
44
+
45
+ To run specs for MRI version execute extconf.rb to create makefile and then run make to create zookeeper_c.bundle, then run specs.
46
+
47
+ == LICENSE:
48
+
49
+ (The MIT License)
50
+
51
+ Copyright (c) 2008 Shane Mingins)
52
+
53
+ Permission is hereby granted, free of charge, to any person obtaining
54
+ a copy of this software and associated documentation files (the
55
+ 'Software'), to deal in the Software without restriction, including
56
+ without limitation the rights to use, copy, modify, merge, publish,
57
+ distribute, sublicense, and/or sell copies of the Software, and to
58
+ permit persons to whom the Software is furnished to do so, subject to
59
+ the following conditions:
60
+
61
+ The above copyright notice and this permission notice shall be
62
+ included in all copies or substantial portions of the Software.
63
+
64
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
65
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
66
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
67
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
68
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
69
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
70
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,9 @@
1
+ require 'mkmf'
2
+ extension_name = 'zookeeper_c'
3
+ dir_config(extension_name)
4
+
5
+ if have_library("zookeeper_mt", "zoo_set_debug_level") then
6
+ create_makefile(extension_name)
7
+ else
8
+ puts "No ZooKeeper C client library available"
9
+ end
@@ -0,0 +1,86 @@
1
+ require 'zookeeper_c'
2
+
3
+ class ZooKeeper < CZooKeeper
4
+
5
+ def initialize(args)
6
+ args = {:host => args} unless args.is_a?(Hash)
7
+ host = args[:host]
8
+ # timeout = args[:timeout] || DEFAULTS[:timeout]
9
+ # watcher = args[:watcher] || DefaultWatcher.new
10
+ # super(host, timeout, watcher)
11
+ super(host)
12
+ @watchers = {} # path => [ block, block, ... ]
13
+ end
14
+
15
+ def connected?
16
+ state == CONNECTED_STATE
17
+ end
18
+
19
+ def closed?
20
+ true # we hope TODO fix this
21
+ end
22
+
23
+ def close
24
+ # TODO
25
+ end
26
+
27
+ def create(args)
28
+ path = args[:path]
29
+ data = args[:data]
30
+ flags = 0
31
+ flags |= EPHEMERAL if args[:ephemeral]
32
+ flags |= SEQUENCE if args[:sequence]
33
+ super(path, data, flags)
34
+ end
35
+
36
+ def exists(path, &blk)
37
+ (@watchers[path] ||= []) << blk if blk
38
+ Stat.new(super(path, !!blk))
39
+ rescue NoNodeError
40
+ return nil
41
+ end
42
+
43
+ def get(args)
44
+ args = {:path => args} unless args.is_a?(Hash)
45
+ path = args[:path]
46
+ watch = args[:watch] || false
47
+ callback = args[:callback]
48
+ context = args[:context]
49
+
50
+ value, stat = super(path)
51
+ [value, Stat.new(stat)]
52
+ rescue NoNodeError
53
+ raise KeeperException::NoNode
54
+ end
55
+
56
+ def set(args)
57
+ path = args[:path]
58
+ data = args[:data]
59
+ version = args[:version] || -1
60
+ callback = args[:callback]
61
+ context = args[:context]
62
+
63
+ super(path, data, version)
64
+ end
65
+
66
+ def delete(args)
67
+ args = {:path => args} unless args.is_a?(Hash)
68
+ path = args[:path]
69
+ version = args[:version] || -1
70
+ callback = args[:callback]
71
+ context = args[:context]
72
+
73
+ super(path, version)
74
+ end
75
+
76
+ def children(args)
77
+ args = {:path => args} unless args.is_a?(Hash)
78
+ path = args[:path]
79
+ watch = args[:watch] || false
80
+ callback = args[:callback]
81
+ context = args[:context]
82
+
83
+ ls(path)
84
+ end
85
+
86
+ end
@@ -0,0 +1,206 @@
1
+ /* Ruby wrapper for the ZooKeeper C API
2
+ * Phillip Pearson <pp@myelin.co.nz>
3
+ */
4
+
5
+ #define THREADED
6
+
7
+ #include "ruby.h"
8
+
9
+ #include "c-client-src/zookeeper.h"
10
+ #include <errno.h>
11
+
12
+ #include <stdio.h>
13
+
14
+ static VALUE ZooKeeper = Qnil;
15
+ static VALUE eNoNode = Qnil;
16
+ static VALUE eBadVersion = Qnil;
17
+
18
+ struct zk_rb_data {
19
+ zhandle_t *zh;
20
+ clientid_t myid;
21
+ };
22
+
23
+ static void watcher(zhandle_t *zh, int type, int state, const char *path) {
24
+ VALUE self, watcher_id;
25
+
26
+ return; // watchers don't work in ruby yet
27
+
28
+ self = (VALUE)zoo_get_context(zh);;
29
+ watcher_id = rb_intern("watcher");
30
+
31
+ fprintf(stderr,"C watcher %d state = %d for %s.\n", type, state, (path ? path: "null"));
32
+ rb_funcall(self, watcher_id, 3, INT2FIX(type), INT2FIX(state), rb_str_new2(path));
33
+ }
34
+
35
+ static void check_errors(int rc) {
36
+ switch (rc) {
37
+ case ZOK: /* all good! */ break;
38
+ case ZBADARGUMENTS: rb_raise(rb_eRuntimeError, "invalid input parameters");
39
+ case ZMARSHALLINGERROR: rb_raise(rb_eRuntimeError, "failed to marshall a request; possibly out of memory");
40
+ case ZOPERATIONTIMEOUT: rb_raise(rb_eRuntimeError, "failed to flush the buffers within the specified timeout");
41
+ case ZCONNECTIONLOSS: rb_raise(rb_eRuntimeError, "a network error occured while attempting to send request to server");
42
+ case ZSYSTEMERROR: rb_raise(rb_eRuntimeError, "a system (OS) error occured; it's worth checking errno to get details");
43
+ case ZNONODE: rb_raise(eNoNode, "the node does not exist");
44
+ case ZNOAUTH: rb_raise(rb_eRuntimeError, "the client does not have permission");
45
+ case ZBADVERSION: rb_raise(eBadVersion, "expected version does not match actual version");
46
+ case ZINVALIDSTATE: rb_raise(rb_eRuntimeError, "zhandle state is either SESSION_EXPIRED_STATE or AUTH_FAILED_STATE");
47
+ case ZNODEEXISTS: rb_raise(rb_eRuntimeError, "the node already exists");
48
+ case ZNOCHILDRENFOREPHEMERALS: rb_raise(rb_eRuntimeError, "cannot create children of ephemeral nodes");
49
+ case ZINVALIDACL: rb_raise(rb_eRuntimeError, "invalid ACL specified");
50
+ default: rb_raise(rb_eRuntimeError, "unknown error returned from zookeeper: %d", rc);
51
+ }
52
+ }
53
+
54
+ static void free_zk_rb_data(struct zk_rb_data* ptr) {
55
+ /*fprintf(stderr, "free zk_rb_data at %p\n", ptr);*/
56
+ zookeeper_close(ptr->zh);
57
+ }
58
+
59
+ static VALUE array_from_stat(const struct Stat* stat) {
60
+ return rb_ary_new3(8,
61
+ LL2NUM(stat->czxid),
62
+ LL2NUM(stat->mzxid),
63
+ LL2NUM(stat->ctime),
64
+ LL2NUM(stat->mtime),
65
+ INT2NUM(stat->version),
66
+ INT2NUM(stat->cversion),
67
+ INT2NUM(stat->aversion),
68
+ LL2NUM(stat->ephemeralOwner));
69
+ }
70
+
71
+ static VALUE method_initialize(VALUE self, VALUE hostPort) {
72
+ VALUE data;
73
+ struct zk_rb_data* zk = NULL;
74
+
75
+ Check_Type(hostPort, T_STRING);
76
+
77
+ data = Data_Make_Struct(ZooKeeper, struct zk_rb_data, 0, free_zk_rb_data, zk);
78
+
79
+ zoo_set_debug_level(ZOO_LOG_LEVEL_INFO);
80
+ zoo_deterministic_conn_order(0);
81
+ zk->zh = zookeeper_init(RSTRING(hostPort)->ptr, watcher, 10000, &zk->myid, (void*)self, 0);
82
+ if (!zk->zh) {
83
+ rb_raise(rb_eRuntimeError, "error connecting to zookeeper: %d", errno);
84
+ }
85
+
86
+ rb_iv_set(self, "@data", data);
87
+
88
+ return Qnil;
89
+ }
90
+
91
+ static VALUE method_ls(VALUE self, VALUE path) {
92
+ struct zk_rb_data* zk;
93
+ struct String_vector strings;
94
+ int i;
95
+ VALUE output;
96
+
97
+ Check_Type(path, T_STRING);
98
+ Data_Get_Struct(rb_iv_get(self, "@data"), struct zk_rb_data, zk);
99
+
100
+ check_errors(zoo_get_children(zk->zh, RSTRING(path)->ptr, 0, &strings));
101
+
102
+ output = rb_ary_new();
103
+ for (i = 0; i < strings.count; ++i) {
104
+ rb_ary_push(output, rb_str_new2(strings.data[i]));
105
+ }
106
+ return output;
107
+ }
108
+
109
+ static VALUE method_exists(VALUE self, VALUE path, VALUE watch) {
110
+ struct zk_rb_data* zk;
111
+ struct Stat stat;
112
+
113
+ Check_Type(path, T_STRING);
114
+ Data_Get_Struct(rb_iv_get(self, "@data"), struct zk_rb_data, zk);
115
+
116
+ check_errors(zoo_exists(zk->zh, RSTRING(path)->ptr, (watch != Qfalse && watch != Qnil), &stat));
117
+
118
+ return array_from_stat(&stat);
119
+ }
120
+
121
+ static VALUE method_create(VALUE self, VALUE path, VALUE value, VALUE flags) {
122
+ struct zk_rb_data* zk;
123
+ char realpath[10240];
124
+
125
+ Check_Type(path, T_STRING);
126
+ Check_Type(value, T_STRING);
127
+ Check_Type(flags, T_FIXNUM);
128
+ Data_Get_Struct(rb_iv_get(self, "@data"), struct zk_rb_data, zk);
129
+
130
+ check_errors(zoo_create(zk->zh, RSTRING(path)->ptr, RSTRING(value)->ptr, RSTRING(value)->len,
131
+ &ZOO_OPEN_ACL_UNSAFE, FIX2INT(flags), realpath, 10240));
132
+
133
+ return rb_str_new2(realpath);
134
+ }
135
+
136
+ static VALUE method_delete(VALUE self, VALUE path, VALUE version) {
137
+ struct zk_rb_data* zk;
138
+
139
+ Check_Type(path, T_STRING);
140
+ Check_Type(version, T_FIXNUM);
141
+ Data_Get_Struct(rb_iv_get(self, "@data"), struct zk_rb_data, zk);
142
+
143
+ check_errors(zoo_delete(zk->zh, RSTRING(path)->ptr, FIX2INT(version)));
144
+
145
+ return Qnil;
146
+ }
147
+
148
+ static VALUE method_get(VALUE self, VALUE path) {
149
+ struct zk_rb_data* zk;
150
+ char data[1024];
151
+ int data_len = 1024;
152
+ struct Stat stat;
153
+
154
+ Check_Type(path, T_STRING);
155
+ Data_Get_Struct(rb_iv_get(self, "@data"), struct zk_rb_data, zk);
156
+
157
+ check_errors(zoo_get(zk->zh, RSTRING(path)->ptr, 0, data, &data_len, &stat));
158
+ /*printf("got some data; version=%d\n", stat.version);*/
159
+
160
+ return rb_ary_new3(2,
161
+ rb_str_new(data, data_len),
162
+ array_from_stat(&stat));
163
+ }
164
+
165
+
166
+ static VALUE method_set(VALUE self, VALUE path, VALUE data, VALUE version) {
167
+ struct zk_rb_data* zk;
168
+
169
+ Check_Type(path, T_STRING);
170
+ Check_Type(data, T_STRING);
171
+ Check_Type(version, T_FIXNUM);
172
+ Data_Get_Struct(rb_iv_get(self, "@data"), struct zk_rb_data, zk);
173
+
174
+ check_errors(zoo_set(zk->zh, RSTRING(path)->ptr, RSTRING(data)->ptr, RSTRING(data)->len, FIX2INT(version)));
175
+
176
+ return Qnil;
177
+ }
178
+
179
+ static VALUE method_state(VALUE self) {
180
+ struct zk_rb_data* zk;
181
+ Data_Get_Struct(rb_iv_get(self, "@data"), struct zk_rb_data, zk);
182
+ return INT2NUM(zoo_state(zk->zh));
183
+ }
184
+
185
+ void Init_zookeeper_c() {
186
+ ZooKeeper = rb_define_class("CZooKeeper", rb_cObject);
187
+ rb_define_method(ZooKeeper, "initialize", method_initialize, 1);
188
+ rb_define_method(ZooKeeper, "ls", method_ls, 1);
189
+ rb_define_method(ZooKeeper, "exists", method_exists, 2);
190
+ rb_define_method(ZooKeeper, "create", method_create, 3);
191
+ rb_define_method(ZooKeeper, "delete", method_delete, 2);
192
+ rb_define_method(ZooKeeper, "get", method_get, 1);
193
+ rb_define_method(ZooKeeper, "set", method_set, 3);
194
+ rb_define_method(ZooKeeper, "state", method_state, 0);
195
+
196
+ eNoNode = rb_define_class_under(ZooKeeper, "NoNodeError", rb_eRuntimeError);
197
+ eBadVersion = rb_define_class_under(ZooKeeper, "BadVersionError", rb_eRuntimeError);
198
+
199
+ rb_define_const(ZooKeeper, "EPHEMERAL", INT2FIX(ZOO_EPHEMERAL));
200
+ rb_define_const(ZooKeeper, "SEQUENCE", INT2FIX(ZOO_SEQUENCE));
201
+
202
+ rb_define_const(ZooKeeper, "SESSION_EVENT", INT2FIX(ZOO_SESSION_EVENT));
203
+ rb_define_const(ZooKeeper, "CONNECTED_STATE", INT2FIX(ZOO_CONNECTED_STATE));
204
+ rb_define_const(ZooKeeper, "AUTH_FAILED_STATE", INT2FIX(ZOO_AUTH_FAILED_STATE));
205
+ rb_define_const(ZooKeeper, "EXPIRED_SESSION_STATE", INT2FIX(ZOO_EXPIRED_SESSION_STATE));
206
+ }
data/lib/zookeeper.rb ADDED
@@ -0,0 +1,22 @@
1
+ if defined?(JRUBY_VERSION)
2
+ require 'zookeeper_j/zookeeper'
3
+ else
4
+ require 'zookeeper_c/zookeeper'
5
+ end
6
+
7
+ class ZooKeeper
8
+ DEFAULTS = {
9
+ :timeout => 10000
10
+ }
11
+
12
+ end
13
+
14
+ require 'zookeeper/id'
15
+ require 'zookeeper/permission'
16
+ require 'zookeeper/acl'
17
+ require 'zookeeper/stat'
18
+ require 'zookeeper/keeper_exception'
19
+ require 'zookeeper/watcher_event'
20
+ require 'zookeeper/sync_primitive'
21
+ require 'zookeeper/queue'
22
+ require 'zookeeper/logging'
@@ -0,0 +1,19 @@
1
+ class ZooKeeper
2
+ class ACL
3
+ attr_reader :permissions, :id
4
+
5
+ def initialize(permissions, id)
6
+ @permissions, @id = permissions, id
7
+ end
8
+
9
+ def ==(obj)
10
+ self.permissions == obj.permissions &&
11
+ self.id == obj.id
12
+ end
13
+
14
+ OPEN_ACL_UNSAFE = [ACL.new(Permission::ALL, Id::ANYONE_ID_UNSAFE)]
15
+ READ_ACL_UNSAFE = [ACL.new(Permission::READ, Id::ANYONE_ID_UNSAFE)]
16
+ CREATOR_ALL_ACL = [ACL.new(Permission::ALL | Permission::ADMIN, Id::AUTH_IDS)]
17
+
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ class ZooKeeper
2
+ class Id
3
+ attr_reader :scheme, :identification
4
+
5
+ def initialize(scheme, id)
6
+ @scheme, @identification = scheme, id
7
+ end
8
+
9
+ def ==(obj)
10
+ self.scheme == obj.scheme &&
11
+ self.identification == obj.identification
12
+ end
13
+
14
+
15
+ ANYONE_ID_UNSAFE = Id.new("world", "anyone")
16
+ AUTH_IDS = Id.new("auth", "")
17
+ end
18
+ end
@@ -0,0 +1,71 @@
1
+ class KeeperException < Exception
2
+
3
+ OK = 0
4
+ # System and server-side errors
5
+ SYSTEMERROR = -1
6
+ RUNTIMEINCONSISTENCY = SYSTEMERROR - 1
7
+ DATAINCONSISTENCY = SYSTEMERROR - 2
8
+ CONNECTIONLOSS = SYSTEMERROR - 3
9
+ MARSHALLINGERROR = SYSTEMERROR - 4
10
+ UNIMPLEMENTED = SYSTEMERROR - 5
11
+ OPERATIONTIMEOUT = SYSTEMERROR - 6
12
+ BADARGUMENTS = SYSTEMERROR - 7
13
+ # API errors
14
+ APIERROR = -100;
15
+ NONODE = APIERROR - 1 # Node does not exist
16
+ NOAUTH = APIERROR - 2 # Current operation not permitted
17
+ BADVERSION = APIERROR - 3 # Version conflict
18
+ NOCHILDRENFOREPHEMERALS = APIERROR - 8
19
+ NODEEXISTS = APIERROR - 10
20
+ NOTEMPTY = APIERROR - 11
21
+ SESSIONEXPIRED = APIERROR - 12
22
+ INVALIDCALLBACK = APIERROR - 13
23
+ INVALIDACL = APIERROR - 14
24
+ AUTHFAILED = APIERROR - 15 # client authentication failed
25
+
26
+ class SystemError < KeeperException; end
27
+ class RunTimeInconsistency < KeeperException; end
28
+ class DataInconsistency < KeeperException; end
29
+ class ConnectionLoss < KeeperException; end
30
+ class MarshallingError < KeeperException; end
31
+ class Unimplemented < KeeperException; end
32
+ class OperationTimeOut < KeeperException; end
33
+ class BadArguments < KeeperException; end
34
+ class ApiError < KeeperException; end
35
+ class NoNode < KeeperException; end
36
+ class NoAuth < KeeperException; end
37
+ class BadVersion < KeeperException; end
38
+ class NoChildrenForEphemerals < KeeperException; end
39
+ class NodeExists < KeeperException; end
40
+ class NotEmpty < KeeperException; end
41
+ class SessionExpired < KeeperException; end
42
+ class InvalidCallback < KeeperException; end
43
+ class InvalidACL < KeeperException; end
44
+ class AuthFailed < KeeperException; end
45
+
46
+ def self.by_code(code)
47
+ case code
48
+ when OK: Ok
49
+ when SYSTEMERROR: SystemError
50
+ when RUNTIMEINCONSISTENCY: RunTimeInconsistency
51
+ when DATAINCONSISTENCY: DataInconsistency
52
+ when CONNECTIONLOSS: ConnectionLoss
53
+ when MARSHALLINGERROR: MarshallingError
54
+ when UNIMPLEMENTED: Unimplemented
55
+ when OPERATIONTIMEOUT: OperationTimeOut
56
+ when BADARGUMENTS: BadArguments
57
+ when APIERROR: ApiError
58
+ when NONODE: NoNode
59
+ when NOAUTH: NoAuth
60
+ when BADVERSION: BadVersion
61
+ when NOCHILDRENFOREPHEMERALS: NoChildrenForEphemerals
62
+ when NODEEXISTS: NodeExists
63
+ when NOTEMPTY: NotEmpty
64
+ when SESSIONEXPIRED: SessionExpired
65
+ when INVALIDCALLBACK: InvalidCallback
66
+ when INVALIDACL: InvalidACL
67
+ when AUTHFAILED: AuthFailed
68
+ else Exception.new("no exception defined for code #{code}")
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,5 @@
1
+ require 'logger'
2
+
3
+ class ZooKeeper
4
+ $LOG = Logger.new($stderr)
5
+ end
@@ -0,0 +1,12 @@
1
+ class ZooKeeper
2
+
3
+ module Permission
4
+ READ = 1 << 0
5
+ WRITE = 1 << 1
6
+ CREATE = 1 << 2
7
+ DELETE = 1 << 3
8
+ ADMIN = 1 << 4
9
+ ALL = READ | WRITE | CREATE | DELETE
10
+ end
11
+
12
+ end
@@ -0,0 +1,57 @@
1
+ class ZooKeeper
2
+
3
+ class Queue < SyncPrimitive
4
+
5
+ def initialize(address, name)
6
+ super(address)
7
+ until @@zk.connected? do; end
8
+ @root = name
9
+ if @@zk && @@zk.exists(@root).nil?
10
+ @@zk.create(:path => @root, :data => "")
11
+ end
12
+ rescue Exception => e
13
+ $LOG.error "Exception instantiating queue #{e.message}"
14
+ end
15
+
16
+ def produce(data)
17
+ @@zk.create(:path => "#{@root}/element", :data => data, :sequence => true) and return true
18
+ end
19
+
20
+ def consume
21
+ @@monitor.synchronize do
22
+ loop do
23
+ list = @@zk.children(:path => @root, :watch => true)
24
+
25
+ if list.empty?
26
+ $LOG.info 'Queue empty, going to wait'
27
+ @@consume.wait
28
+ else
29
+ minimum_node = list.inject {|e1, e2| e2.delete("element").to_i < e1.delete("element").to_i ? e2 : e1 }
30
+ data, stat = @@zk.get("#{@root}/#{minimum_node}")
31
+ @@zk.delete(:path => "#{@root}/#{minimum_node}", :version => 0)
32
+ return data
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ def empty?
39
+ @@zk.children(:path => @root).empty?
40
+ end
41
+
42
+ def stop
43
+ @@zk.close
44
+ @@zk = nil
45
+ end
46
+
47
+ def stopped?
48
+ @@zk.nil?
49
+ end
50
+
51
+ def active?
52
+ @@zk.connected?
53
+ end
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,11 @@
1
+ class ZooKeeper
2
+ class Stat
3
+ attr_reader :created_zxid, :last_modified_zxid, :created_time, :last_modified_time, :version, :child_list_version,
4
+ :acl_list_version, :ephemeral_owner
5
+
6
+ def initialize(attributes)
7
+ @created_zxid, @last_modified_zxid, @created_time, @last_modified_time, @version,
8
+ @child_list_version, @acl_list_version, @ephemeral_owner = attributes
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ require 'monitor'
2
+
3
+ class ZooKeeper
4
+
5
+ class SyncPrimitive
6
+
7
+ @@zk =nil
8
+ @@monitor = nil
9
+ @@consume = nil
10
+
11
+ attr_accessor :root
12
+
13
+ def initialize(address)
14
+ unless @@zk
15
+ $LOG.info 'Connecting Zookeeper Client'
16
+ @@zk = ZooKeeper.new(:host => address, :timeout => 10000, :watcher => self)
17
+ @@monitor = Monitor.new
18
+ @@consume = @@monitor.new_cond
19
+ $LOG.info 'Zookeeper Client Started'
20
+ end
21
+ rescue Exception => e
22
+ $LOG.error "Exception connecting Zookeeper to #{address} #{e.message}"
23
+ @@zk = nil
24
+ end
25
+
26
+ def process(event)
27
+ @@monitor.synchronize { @@consume.signal }
28
+ end
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,24 @@
1
+ class ZooKeeper
2
+ class WatcherEvent
3
+ attr_reader :type, :state, :path
4
+
5
+ def initialize(type, state, path)
6
+ @type, @state, @path = type, state, path
7
+ end
8
+
9
+ # constants for connection states
10
+ KeeperStateChanged = 0
11
+ KeeperStateUnknown = -1
12
+ KeeperStateDisconnected = 0
13
+ KeeperStateNoSyncConnected = 1
14
+ KeeperStateSyncConnected = 3
15
+ KeeperStateExpired = -112
16
+
17
+ # constants for event types
18
+ EventNone = -1
19
+ EventNodeCreated = 1
20
+ EventNodeDeleted = 2
21
+ EventNodeDataChanged = 3
22
+ EventNodeChildrenChanged = 4
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: carlosnz-zookeeper
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.2"
5
+ platform: ruby
6
+ authors:
7
+ - Shane Mingins
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-06-13 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: A Ruby client interface to the Java ZooKeeper server.
17
+ email: smingins@elctech.com
18
+ executables: []
19
+
20
+ extensions:
21
+ - ext/zookeeper_c/extconf.rb
22
+ extra_rdoc_files:
23
+ - README
24
+ files:
25
+ - README
26
+ - lib/zookeeper.rb
27
+ - lib/zookeeper/acl.rb
28
+ - lib/zookeeper/id.rb
29
+ - lib/zookeeper/keeper_exception.rb
30
+ - lib/zookeeper/logging.rb
31
+ - lib/zookeeper/permission.rb
32
+ - lib/zookeeper/stat.rb
33
+ - lib/zookeeper/watcher_event.rb
34
+ - lib/zookeeper/sync_primitive.rb
35
+ - lib/zookeeper/queue.rb
36
+ - ext/zookeeper_c/zookeeper_ruby.c
37
+ - ext/zookeeper_c/zookeeper.rb
38
+ has_rdoc: true
39
+ homepage:
40
+ licenses:
41
+ post_install_message:
42
+ rdoc_options:
43
+ - --line-numbers
44
+ - --inline-source
45
+ - --title
46
+ - ZooKeeper
47
+ - --main
48
+ - README
49
+ require_paths:
50
+ - lib
51
+ - ext
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ requirements: []
65
+
66
+ rubyforge_project:
67
+ rubygems_version: 1.3.5
68
+ signing_key:
69
+ specification_version: 2
70
+ summary: A Ruby client interface to the Java ZooKeeper server.
71
+ test_files: []
72
+