zkruby 3.4.3
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.tar.gz.sig +0 -0
- data/.gemtest +0 -0
- data/History.txt +18 -0
- data/Manifest.txt +39 -0
- data/README.rdoc +119 -0
- data/Rakefile +39 -0
- data/jute/jute.citrus +105 -0
- data/jute/lib/hoe/jute.rb +56 -0
- data/jute/lib/jute.rb +120 -0
- data/lib/em_zkruby.rb +4 -0
- data/lib/jute/zookeeper.rb +203 -0
- data/lib/zkruby.rb +4 -0
- data/lib/zkruby/bindata.rb +45 -0
- data/lib/zkruby/client.rb +608 -0
- data/lib/zkruby/enum.rb +108 -0
- data/lib/zkruby/eventmachine.rb +186 -0
- data/lib/zkruby/multi.rb +47 -0
- data/lib/zkruby/protocol.rb +182 -0
- data/lib/zkruby/rubyio.rb +310 -0
- data/lib/zkruby/session.rb +445 -0
- data/lib/zkruby/util.rb +141 -0
- data/lib/zkruby/zkruby.rb +27 -0
- data/spec/bindata_spec.rb +51 -0
- data/spec/enum_spec.rb +84 -0
- data/spec/eventmachine_spec.rb +50 -0
- data/spec/multi_spec.rb +93 -0
- data/spec/protocol_spec.rb +72 -0
- data/spec/recipe_helper.rb +68 -0
- data/spec/rubyio_spec.rb +8 -0
- data/spec/sequences_spec.rb +19 -0
- data/spec/server_helper.rb +45 -0
- data/spec/shared/auth.rb +40 -0
- data/spec/shared/basic.rb +180 -0
- data/spec/shared/binding.rb +33 -0
- data/spec/shared/chroot.rb +61 -0
- data/spec/shared/multi.rb +38 -0
- data/spec/shared/util.rb +56 -0
- data/spec/shared/watch.rb +49 -0
- data/spec/spec_helper.rb +12 -0
- data/src/jute/zookeeper.jute +288 -0
- data/yard_ext/enum_handler.rb +16 -0
- metadata +243 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
shared_examples_for "chrooted connection" do
|
2
|
+
describe "chrooted connection" do
|
3
|
+
|
4
|
+
around(:each) do |example|
|
5
|
+
@zk = connect(:binding => binding)
|
6
|
+
@ch_zk = connect(:binding => binding, :chroot => "/zkruby")
|
7
|
+
|
8
|
+
example.run
|
9
|
+
|
10
|
+
safe_close(@zk)
|
11
|
+
safe_close(@ch_zk)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should perform all the ZooKeeper CRUD chrooted" do
|
15
|
+
path = @ch_zk.create("/spec-chroot","someData",ZK::ACL_OPEN_UNSAFE,:ephemeral)
|
16
|
+
path.should == "/spec-chroot"
|
17
|
+
real_path = "/zkruby#{path}"
|
18
|
+
stat,data = @ch_zk.get(path)
|
19
|
+
stat.should be_a ZooKeeper::Data::Stat
|
20
|
+
data.should == "someData"
|
21
|
+
|
22
|
+
stat,data = @zk.get(real_path)
|
23
|
+
data.should == "someData"
|
24
|
+
|
25
|
+
new_stat = @ch_zk.set(path,"different data",stat.version)
|
26
|
+
new_stat.should be_a ZooKeeper::Data::Stat
|
27
|
+
|
28
|
+
stat,data = @ch_zk.get(path)
|
29
|
+
data.should == "different data"
|
30
|
+
|
31
|
+
stat,data = @zk.get(real_path)
|
32
|
+
data.should == "different data"
|
33
|
+
|
34
|
+
@ch_zk.delete(path,stat.version)
|
35
|
+
@ch_zk.exists?(path).should be_false
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should return a client path for sync" do
|
39
|
+
path = @ch_zk.sync("/aPath")
|
40
|
+
path.should == "/aPath"
|
41
|
+
end
|
42
|
+
|
43
|
+
context "util recipes" do
|
44
|
+
|
45
|
+
it "Client#mkpath should work with chroot" do
|
46
|
+
@zk.rmpath("/zkruby/spec-util")
|
47
|
+
@ch_zk.mkpath("/spec-util/test/mkpath")
|
48
|
+
stat,data = @zk.get("/zkruby/spec-util/test")
|
49
|
+
data.should == ""
|
50
|
+
end
|
51
|
+
|
52
|
+
it "Client#rmpath should work with chroot" do
|
53
|
+
@zk.mkpath("/zkruby/spec-util/test")
|
54
|
+
@zk.mkpath("/zkruby/spec-util/test/two/three/four")
|
55
|
+
@ch_zk.rmpath("/spec-util")
|
56
|
+
@zk.exists?("/zkruby/spec-util").should be_false
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
shared_examples_for "multi" do
|
2
|
+
|
3
|
+
context "only in 3.4 and up", :multi => true do
|
4
|
+
it "should do a create in a multi-op" do
|
5
|
+
delete_path = @zk.create("/zkruby/multi","hello multi",ZK::ACL_OPEN_UNSAFE,:ephemeral,:sequential)
|
6
|
+
|
7
|
+
new_path = nil
|
8
|
+
stat,data = @zk.get("/zkruby")
|
9
|
+
@zk.transaction() do |txn|
|
10
|
+
txn.create("/zkruby/multi","hello world", ZK::ACL_OPEN_UNSAFE,:ephemeral,:sequential) { |path| logger.debug{ "New path #{path}"} ; new_path = path }
|
11
|
+
txn.check("/zkruby",stat.version)
|
12
|
+
txn.set("/zkruby","new multi data",-1)
|
13
|
+
txn.delete(delete_path,-1)
|
14
|
+
end
|
15
|
+
|
16
|
+
new_path.should_not be_nil
|
17
|
+
|
18
|
+
stat, data = @zk.get(new_path)
|
19
|
+
data.should == "hello world"
|
20
|
+
|
21
|
+
stat, data = @zk.get("/zkruby")
|
22
|
+
data.should == "new multi data"
|
23
|
+
|
24
|
+
@zk.exists?(delete_path).should be_nil
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should raise exceptions if the multi op fails" do
|
29
|
+
lambda { @zk.transaction() do |txn|
|
30
|
+
txn.create("/multi","hello world", ZK::ACL_OPEN_UNSAFE,:ephemeral,:sequential) { |path| puts path }
|
31
|
+
txn.create("/multi/something/","hello world", ZK::ACL_OPEN_UNSAFE,:ephemeral,:sequential) { |path| puts path }
|
32
|
+
txn.create("/multi","hello world 2", ZK::ACL_OPEN_UNSAFE,:ephemeral,:sequential) { |path| puts path }
|
33
|
+
end }.should raise_error(ZooKeeper::Error)
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
data/spec/shared/util.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
shared_examples_for "util recipes" do
|
2
|
+
context "util recipes" do
|
3
|
+
context "Client#mkpath" do
|
4
|
+
#you'll note that these tests rely on each other!
|
5
|
+
before(:each) do
|
6
|
+
@zk.rmpath("/zkruby/spec-util")
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should create empty nodes at all the intermediate paths" do
|
10
|
+
@zk.mkpath("/zkruby/spec-util/test/mkpath")
|
11
|
+
stat,data = @zk.get("/zkruby/spec-util/test")
|
12
|
+
data.should == ""
|
13
|
+
stat,data = @zk.get("/zkruby/spec-util/test/mkpath")
|
14
|
+
data.should == ""
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should not raise errors when path already exists" do
|
18
|
+
@zk.mkpath("/zkruby")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should only create the final path if all parents exist" do
|
22
|
+
@zk.create("/zkruby/spec-util","node that exists",ZK::ACL_OPEN_UNSAFE)
|
23
|
+
@zk.mkpath("/zkruby/spec-util/mkpath")
|
24
|
+
stat, data = @zk.get("/zkruby/spec-util")
|
25
|
+
data.should == "node that exists"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not raise error if something else creates an intermediate path"
|
29
|
+
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
context "Client#rmpath" do
|
34
|
+
before(:each) do
|
35
|
+
@zk.mkpath("/zkruby/spec_util/one")
|
36
|
+
@zk.mkpath("/zkruby/spec_util/two/twopointtwo")
|
37
|
+
@zk.mkpath("/zkruby/spec_util/two/three/four/five")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should delete a tree of paths" do
|
41
|
+
@zk.rmpath("/zkruby/spec_util")
|
42
|
+
@zk.exists?("/zkruby/spec_util").should be_false
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should not raise errors if the path is already deleted"
|
46
|
+
it "should delete leaf nodes just like delete does" do
|
47
|
+
@zk.rmpath("/zkruby/spec_util/one")
|
48
|
+
@zk.exists?("/zkruby/spec_util/one").should be_false
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
it "should not raise errors if some nodes are deleted by something else during processing"
|
53
|
+
it "should fight to the death if something else is creating subnodes"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
shared_examples_for "watches" do
|
2
|
+
describe "watches" do
|
3
|
+
around(:each) do |example|
|
4
|
+
@zk = connect(:binding => binding)
|
5
|
+
@zk2 = connect(:binding => binding)
|
6
|
+
|
7
|
+
example.run
|
8
|
+
|
9
|
+
safe_close(@zk)
|
10
|
+
safe_close(@zk2)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should handle data watches" do
|
14
|
+
path = @zk.create("/zkruby/rspec_watch","somedata",ZK::ACL_OPEN_UNSAFE,:ephemeral,:sequential)
|
15
|
+
watch_results = []
|
16
|
+
watch = lambda { |state,path,event| watch_results << [ state,path,event ] }
|
17
|
+
|
18
|
+
stat,data = @zk.get(path,watch)
|
19
|
+
# set the data on the 2nd session
|
20
|
+
@zk2.set(path,"newdata",stat.version)
|
21
|
+
sleep(5)
|
22
|
+
watch_results.size().should == 1
|
23
|
+
watch_results[0][1].should == path
|
24
|
+
watch_results[0][2].should === :node_data_changed
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should handle exists watches"
|
28
|
+
it "should handle child watches" do
|
29
|
+
watch_results = []
|
30
|
+
watch = lambda { |state,path,event| watch_results << [ state,path,event ] }
|
31
|
+
|
32
|
+
stat,children = @zk.children("/zkruby",watch)
|
33
|
+
path = @zk2.create("/zkruby/rspec_watch","somedata",ZK::ACL_OPEN_UNSAFE,:ephemeral,:sequential)
|
34
|
+
sleep(5)
|
35
|
+
watch_results.size().should == 1
|
36
|
+
watch_results[0][1].should == "/zkruby"
|
37
|
+
watch_results[0][2].should === :node_children_changed
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should reset watches over socket disconnects"
|
42
|
+
it "should not send :connection_lost to watches on disconnect if so configured"
|
43
|
+
|
44
|
+
describe :close do
|
45
|
+
it "should send :session_expired to the default watcher on close"
|
46
|
+
it "should send :Session_expired to all watchers on close"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'slf4r/logging_logger'
|
2
|
+
require 'zkruby/zkruby'
|
3
|
+
|
4
|
+
Logging.logger.root.level = :error
|
5
|
+
Logging.logger.root.appenders = Logging.appenders.stdout(:layout => Logging.layouts.pattern(:pattern => '%c [%T] %-5l: %m\n'))
|
6
|
+
#Logging.logger[ZooKeeper::RubyIO::Connection].level = :error
|
7
|
+
#Logging.logger[ZooKeeper::RubyIO::Binding].level = :error
|
8
|
+
#Logging.logger[ZooKeeper::Session].level = :debug
|
9
|
+
#Logging.logger["ZooKeeper::EventMachine::ClientConn"].level = :debug
|
10
|
+
#Logging.logger["ZooKeeper::Session::Ping"].level = :error
|
11
|
+
|
12
|
+
Thread.current[:name] = "Rspec::Main"
|
@@ -0,0 +1,288 @@
|
|
1
|
+
/**
|
2
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
3
|
+
* or more contributor license agreements. See the NOTICE file
|
4
|
+
* distributed with this work for additional information
|
5
|
+
* regarding copyright ownership. The ASF licenses this file
|
6
|
+
* to you under the Apache License, Version 2.0 (the
|
7
|
+
* "License"); you may not use this file except in compliance
|
8
|
+
* with the License. You may obtain a copy of the License at
|
9
|
+
*
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
*
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
* See the License for the specific language governing permissions and
|
16
|
+
* limitations under the License.
|
17
|
+
*/
|
18
|
+
|
19
|
+
module org.apache.zookeeper.data {
|
20
|
+
class Id {
|
21
|
+
ustring scheme;
|
22
|
+
ustring id;
|
23
|
+
}
|
24
|
+
class ACL {
|
25
|
+
int perms;
|
26
|
+
Id id;
|
27
|
+
}
|
28
|
+
// information shared with the client
|
29
|
+
class Stat {
|
30
|
+
long czxid; // created zxid
|
31
|
+
long mzxid; // last modified zxid
|
32
|
+
long ctime; // created
|
33
|
+
long mtime; // last modified
|
34
|
+
int version; // version
|
35
|
+
int cversion; // child version
|
36
|
+
int aversion; // acl version
|
37
|
+
long ephemeralOwner; // owner id if ephemeral, 0 otw
|
38
|
+
int dataLength; //length of the data in the node
|
39
|
+
int numChildren; //number of children of this node
|
40
|
+
long pzxid; // last modified children
|
41
|
+
}
|
42
|
+
// information explicitly stored by the server persistently
|
43
|
+
class StatPersisted {
|
44
|
+
long czxid; // created zxid
|
45
|
+
long mzxid; // last modified zxid
|
46
|
+
long ctime; // created
|
47
|
+
long mtime; // last modified
|
48
|
+
int version; // version
|
49
|
+
int cversion; // child version
|
50
|
+
int aversion; // acl version
|
51
|
+
long ephemeralOwner; // owner id if ephemeral, 0 otw
|
52
|
+
long pzxid; // last modified children
|
53
|
+
}
|
54
|
+
|
55
|
+
// information explicitly stored by the version 1 database of servers
|
56
|
+
class StatPersistedV1 {
|
57
|
+
long czxid; //created zxid
|
58
|
+
long mzxid; //last modified zxid
|
59
|
+
long ctime; //created
|
60
|
+
long mtime; //last modified
|
61
|
+
int version; //version
|
62
|
+
int cversion; //child version
|
63
|
+
int aversion; //acl version
|
64
|
+
long ephemeralOwner; //owner id if ephemeral. 0 otw
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
module org.apache.zookeeper.proto {
|
69
|
+
class ConnectRequest {
|
70
|
+
int protocolVersion;
|
71
|
+
long lastZxidSeen;
|
72
|
+
int timeOut;
|
73
|
+
long sessionId;
|
74
|
+
buffer passwd;
|
75
|
+
}
|
76
|
+
class ConnectResponse {
|
77
|
+
int protocolVersion;
|
78
|
+
int timeOut;
|
79
|
+
long sessionId;
|
80
|
+
buffer passwd;
|
81
|
+
}
|
82
|
+
class SetWatches {
|
83
|
+
long relativeZxid;
|
84
|
+
vector<ustring>dataWatches;
|
85
|
+
vector<ustring>existWatches;
|
86
|
+
vector<ustring>childWatches;
|
87
|
+
}
|
88
|
+
class RequestHeader {
|
89
|
+
int xid;
|
90
|
+
int type;
|
91
|
+
}
|
92
|
+
class MultiHeader {
|
93
|
+
int type;
|
94
|
+
boolean done;
|
95
|
+
int err;
|
96
|
+
}
|
97
|
+
class AuthPacket {
|
98
|
+
int type;
|
99
|
+
ustring scheme;
|
100
|
+
buffer auth;
|
101
|
+
}
|
102
|
+
class ReplyHeader {
|
103
|
+
int xid;
|
104
|
+
long zxid;
|
105
|
+
int err;
|
106
|
+
}
|
107
|
+
class GetDataRequest {
|
108
|
+
ustring path;
|
109
|
+
boolean watch;
|
110
|
+
}
|
111
|
+
class SetDataRequest {
|
112
|
+
ustring path;
|
113
|
+
buffer data;
|
114
|
+
int version;
|
115
|
+
}
|
116
|
+
class SetDataResponse {
|
117
|
+
org.apache.zookeeper.data.Stat stat;
|
118
|
+
}
|
119
|
+
class GetSASLRequest {
|
120
|
+
buffer token;
|
121
|
+
}
|
122
|
+
class SetSASLRequest {
|
123
|
+
buffer token;
|
124
|
+
}
|
125
|
+
class SetSASLResponse {
|
126
|
+
buffer token;
|
127
|
+
}
|
128
|
+
class CreateRequest {
|
129
|
+
ustring path;
|
130
|
+
buffer data;
|
131
|
+
vector<org.apache.zookeeper.data.ACL> acl;
|
132
|
+
int flags;
|
133
|
+
}
|
134
|
+
class DeleteRequest {
|
135
|
+
ustring path;
|
136
|
+
int version;
|
137
|
+
}
|
138
|
+
class GetChildrenRequest {
|
139
|
+
ustring path;
|
140
|
+
boolean watch;
|
141
|
+
}
|
142
|
+
class GetChildren2Request {
|
143
|
+
ustring path;
|
144
|
+
boolean watch;
|
145
|
+
}
|
146
|
+
class CheckVersionRequest {
|
147
|
+
ustring path;
|
148
|
+
int version;
|
149
|
+
}
|
150
|
+
class GetMaxChildrenRequest {
|
151
|
+
ustring path;
|
152
|
+
}
|
153
|
+
class GetMaxChildrenResponse {
|
154
|
+
int max;
|
155
|
+
}
|
156
|
+
class SetMaxChildrenRequest {
|
157
|
+
ustring path;
|
158
|
+
int max;
|
159
|
+
}
|
160
|
+
class SyncRequest {
|
161
|
+
ustring path;
|
162
|
+
}
|
163
|
+
class SyncResponse {
|
164
|
+
ustring path;
|
165
|
+
}
|
166
|
+
class GetACLRequest {
|
167
|
+
ustring path;
|
168
|
+
}
|
169
|
+
class SetACLRequest {
|
170
|
+
ustring path;
|
171
|
+
vector<org.apache.zookeeper.data.ACL> acl;
|
172
|
+
int version;
|
173
|
+
}
|
174
|
+
class SetACLResponse {
|
175
|
+
org.apache.zookeeper.data.Stat stat;
|
176
|
+
}
|
177
|
+
class WatcherEvent {
|
178
|
+
int type; // event type
|
179
|
+
int state; // state of the Keeper client runtime
|
180
|
+
ustring path;
|
181
|
+
}
|
182
|
+
class ErrorResponse {
|
183
|
+
int err;
|
184
|
+
}
|
185
|
+
class CreateResponse {
|
186
|
+
ustring path;
|
187
|
+
}
|
188
|
+
class ExistsRequest {
|
189
|
+
ustring path;
|
190
|
+
boolean watch;
|
191
|
+
}
|
192
|
+
class ExistsResponse {
|
193
|
+
org.apache.zookeeper.data.Stat stat;
|
194
|
+
}
|
195
|
+
class GetDataResponse {
|
196
|
+
buffer data;
|
197
|
+
org.apache.zookeeper.data.Stat stat;
|
198
|
+
}
|
199
|
+
class GetChildrenResponse {
|
200
|
+
vector<ustring> children;
|
201
|
+
}
|
202
|
+
class GetChildren2Response {
|
203
|
+
vector<ustring> children;
|
204
|
+
org.apache.zookeeper.data.Stat stat;
|
205
|
+
}
|
206
|
+
class GetACLResponse {
|
207
|
+
vector<org.apache.zookeeper.data.ACL> acl;
|
208
|
+
org.apache.zookeeper.data.Stat stat;
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
module org.apache.zookeeper.server.quorum {
|
213
|
+
class LearnerInfo {
|
214
|
+
long serverid;
|
215
|
+
int protocolVersion;
|
216
|
+
}
|
217
|
+
class QuorumPacket {
|
218
|
+
int type; // Request, Ack, Commit, Ping
|
219
|
+
long zxid;
|
220
|
+
buffer data; // Only significant when type is request
|
221
|
+
vector<org.apache.zookeeper.data.Id> authinfo;
|
222
|
+
}
|
223
|
+
}
|
224
|
+
|
225
|
+
module org.apache.zookeeper.server.persistence {
|
226
|
+
class FileHeader {
|
227
|
+
int magic;
|
228
|
+
int version;
|
229
|
+
long dbid;
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
module org.apache.zookeeper.txn {
|
234
|
+
class TxnHeader {
|
235
|
+
long clientId;
|
236
|
+
int cxid;
|
237
|
+
long zxid;
|
238
|
+
long time;
|
239
|
+
int type;
|
240
|
+
}
|
241
|
+
class CreateTxnV0 {
|
242
|
+
ustring path;
|
243
|
+
buffer data;
|
244
|
+
vector<org.apache.zookeeper.data.ACL> acl;
|
245
|
+
boolean ephemeral;
|
246
|
+
}
|
247
|
+
class CreateTxn {
|
248
|
+
ustring path;
|
249
|
+
buffer data;
|
250
|
+
vector<org.apache.zookeeper.data.ACL> acl;
|
251
|
+
boolean ephemeral;
|
252
|
+
int parentCVersion;
|
253
|
+
}
|
254
|
+
class DeleteTxn {
|
255
|
+
ustring path;
|
256
|
+
}
|
257
|
+
class SetDataTxn {
|
258
|
+
ustring path;
|
259
|
+
buffer data;
|
260
|
+
int version;
|
261
|
+
}
|
262
|
+
class CheckVersionTxn {
|
263
|
+
ustring path;
|
264
|
+
int version;
|
265
|
+
}
|
266
|
+
class SetACLTxn {
|
267
|
+
ustring path;
|
268
|
+
vector<org.apache.zookeeper.data.ACL> acl;
|
269
|
+
int version;
|
270
|
+
}
|
271
|
+
class SetMaxChildrenTxn {
|
272
|
+
ustring path;
|
273
|
+
int max;
|
274
|
+
}
|
275
|
+
class CreateSessionTxn {
|
276
|
+
int timeOut;
|
277
|
+
}
|
278
|
+
class ErrorTxn {
|
279
|
+
int err;
|
280
|
+
}
|
281
|
+
class Txn {
|
282
|
+
int type;
|
283
|
+
buffer data;
|
284
|
+
}
|
285
|
+
class MultiTxn {
|
286
|
+
vector<org.apache.zookeeper.txn.Txn> txns;
|
287
|
+
}
|
288
|
+
}
|