fraggle 0.3.5 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/fraggle/client.rb +151 -132
- data/lib/fraggle/msg.rb +14 -20
- data/lib/fraggle/response.rb +15 -7
- data/lib/fraggle.rb +6 -4
- data/test/fraggle_client_test.rb +32 -48
- metadata +5 -8
- data/lib/fraggle/snap.rb +0 -52
- data/test/fraggle_snap_test.rb +0 -67
data/lib/fraggle/client.rb
CHANGED
@@ -21,15 +21,18 @@ module Fraggle
|
|
21
21
|
|
22
22
|
Nibbles = "0123456789abcdef"
|
23
23
|
|
24
|
-
def initialize(addrs)
|
25
|
-
@addr = addrs.shift
|
26
|
-
@init = addrs
|
27
|
-
@addrs = {}
|
28
|
-
@shun = {}
|
24
|
+
def initialize(addr, addrs=[], opts={})
|
29
25
|
@cbx = {}
|
30
26
|
|
27
|
+
@addr = addr
|
28
|
+
@addrs = {}
|
29
|
+
|
30
|
+
addrs.each_with_index do |addr, i|
|
31
|
+
@addrs[i] = addr
|
32
|
+
end
|
33
|
+
|
31
34
|
# Logging
|
32
|
-
@level = ERROR
|
35
|
+
@level = opts[:level] || ERROR
|
33
36
|
@writer = $stderr
|
34
37
|
end
|
35
38
|
|
@@ -56,13 +59,20 @@ module Fraggle
|
|
56
59
|
end
|
57
60
|
end
|
58
61
|
|
59
|
-
def
|
62
|
+
def rev
|
60
63
|
req = Request.new
|
61
|
-
req.verb
|
62
|
-
|
63
|
-
req
|
64
|
+
req.verb = Request::Verb::REV
|
65
|
+
|
66
|
+
resend(req)
|
67
|
+
end
|
64
68
|
|
65
|
-
|
69
|
+
def checkin(path, rev)
|
70
|
+
req = Request.new
|
71
|
+
req.verb = Request::Verb::CHECKIN
|
72
|
+
req.path = path
|
73
|
+
req.rev = casify(rev)
|
74
|
+
|
75
|
+
resend(req)
|
66
76
|
end
|
67
77
|
|
68
78
|
def session(prefix=nil, &blk)
|
@@ -79,103 +89,121 @@ module Fraggle
|
|
79
89
|
estab = true
|
80
90
|
|
81
91
|
# Get back to the server ASAP
|
82
|
-
checkin(name, e.
|
92
|
+
checkin(name, e.rev).valid(&f)
|
83
93
|
end
|
84
94
|
|
85
|
-
checkin(name, 0
|
95
|
+
checkin(name, 0).valid(&f)
|
86
96
|
end
|
87
97
|
|
88
|
-
def get(
|
98
|
+
def get(rev, path)
|
89
99
|
req = Request.new
|
100
|
+
req.rev = rev
|
90
101
|
req.verb = Request::Verb::GET
|
91
|
-
req.id = sid if sid != 0 # wire optimization
|
92
102
|
req.path = path
|
93
103
|
|
94
|
-
|
104
|
+
resend(req)
|
95
105
|
end
|
96
106
|
|
97
|
-
def stat(
|
107
|
+
def stat(rev, path)
|
98
108
|
req = Request.new
|
109
|
+
req.rev = rev
|
99
110
|
req.verb = Request::Verb::STAT
|
100
|
-
req.id = sid if sid != 0 # wire optimization
|
101
111
|
req.path = path
|
102
112
|
|
103
|
-
|
113
|
+
resend(req)
|
104
114
|
end
|
105
115
|
|
106
|
-
def getdir(
|
116
|
+
def getdir(rev, path, offset, limit)
|
107
117
|
req = Request.new
|
118
|
+
req.rev = rev
|
108
119
|
req.verb = Request::Verb::GETDIR
|
109
|
-
req.id = sid if sid != 0
|
110
120
|
req.offset = offset if offset != 0
|
111
121
|
req.limit = limit if limit != 0
|
112
122
|
req.path = path
|
113
123
|
|
114
|
-
|
124
|
+
resend(req)
|
115
125
|
end
|
116
126
|
|
117
|
-
def set(path, value,
|
127
|
+
def set(path, value, rev)
|
118
128
|
req = Request.new
|
119
129
|
req.verb = Request::Verb::SET
|
120
130
|
req.path = path
|
121
131
|
req.value = value
|
122
|
-
req.
|
132
|
+
req.rev = casify(rev)
|
123
133
|
|
124
|
-
send(req
|
134
|
+
send(req)
|
125
135
|
end
|
126
136
|
|
127
|
-
def del(path,
|
137
|
+
def del(path, rev)
|
128
138
|
req = Request.new
|
129
139
|
req.verb = Request::Verb::DEL
|
130
140
|
req.path = path
|
131
|
-
req.
|
141
|
+
req.rev = casify(rev)
|
132
142
|
|
133
|
-
send(req
|
143
|
+
send(req)
|
134
144
|
end
|
135
145
|
|
136
|
-
def walk(
|
146
|
+
def walk(rev, glob, offset=nil, limit=nil)
|
137
147
|
req = Request.new
|
138
|
-
req.verb
|
139
|
-
req.
|
140
|
-
req.path
|
148
|
+
req.verb = Request::Verb::WALK
|
149
|
+
req.rev = rev
|
150
|
+
req.path = glob
|
151
|
+
req.offset = offset
|
152
|
+
req.limit = limit
|
141
153
|
|
142
|
-
cancelable(
|
154
|
+
cancelable(resend(req))
|
143
155
|
end
|
144
156
|
|
145
|
-
def watch(
|
157
|
+
def watch(rev, glob)
|
146
158
|
req = Request.new
|
159
|
+
req.rev = rev
|
147
160
|
req.verb = Request::Verb::WATCH
|
148
161
|
req.path = glob
|
149
162
|
|
150
|
-
cancelable(
|
163
|
+
cancelable(resend(req))
|
151
164
|
end
|
152
165
|
|
153
|
-
def
|
166
|
+
def monitor(rev, glob)
|
154
167
|
req = Request.new
|
155
|
-
req.
|
168
|
+
req.rev = rev
|
169
|
+
req.path = glob
|
156
170
|
|
157
|
-
|
158
|
-
|
171
|
+
wt = nil
|
172
|
+
wk = nil
|
159
173
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
174
|
+
req.metadef :cancel do
|
175
|
+
wt.cancel if wt
|
176
|
+
wk.cancel if wk
|
177
|
+
end
|
178
|
+
|
179
|
+
wk = walk(rev, glob).valid do |e|
|
180
|
+
req.emit(:valid, e)
|
181
|
+
end.error do |e|
|
182
|
+
req.emit(:error, e)
|
183
|
+
end.done do
|
184
|
+
req.emit(:done)
|
185
|
+
|
186
|
+
wt = watch(rev+1, glob).valid do |e|
|
187
|
+
req.emit(:valid, e)
|
188
|
+
end.error do |e|
|
189
|
+
req.emit(:error, e)
|
190
|
+
end
|
191
|
+
end
|
164
192
|
|
165
|
-
|
193
|
+
req
|
166
194
|
end
|
167
195
|
|
168
196
|
def noop(&blk)
|
169
197
|
req = Request.new
|
170
198
|
req.verb = Request::Verb::NOOP
|
171
199
|
|
172
|
-
send(req
|
200
|
+
send(req)
|
173
201
|
end
|
174
202
|
|
175
203
|
# Be careful with this. It is recommended you use #cancel on the Request
|
176
204
|
# returned to ensure you don't run into a race-condition where you cancel an
|
177
205
|
# operation you may have thought was something else.
|
178
|
-
def __cancel__(what
|
206
|
+
def __cancel__(what)
|
179
207
|
req = Request.new
|
180
208
|
req.verb = Request::Verb::CANCEL
|
181
209
|
req.id = what.tag
|
@@ -183,39 +211,28 @@ module Fraggle
|
|
183
211
|
# Hold on to the tag as unavaiable for reuse until the cancel succeeds.
|
184
212
|
@cbx[what.tag] = nil
|
185
213
|
|
186
|
-
send(req) do |res|
|
214
|
+
send(req).valid do |res|
|
187
215
|
# Do not send any more responses from the server to this request.
|
188
216
|
@cbx.delete(what.tag)
|
189
|
-
|
217
|
+
what.emit(:valid, res)
|
190
218
|
end
|
191
219
|
end
|
192
220
|
|
193
|
-
def
|
194
|
-
|
195
|
-
tag = MinTag
|
221
|
+
def next_tag
|
222
|
+
tag = MinTag
|
196
223
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
end
|
224
|
+
while @cbx.has_key?(tag)
|
225
|
+
tag += 1
|
226
|
+
if tag > MaxTag
|
227
|
+
tag = MinTag
|
202
228
|
end
|
203
|
-
|
204
|
-
req.tag = tag
|
205
229
|
end
|
206
230
|
|
207
|
-
|
208
|
-
|
209
|
-
end
|
231
|
+
tag
|
232
|
+
end
|
210
233
|
|
211
|
-
|
212
|
-
req.
|
213
|
-
warn("'error (%d) (%s)' for: %s" % [
|
214
|
-
e.err_code,
|
215
|
-
e.err_detail.inspect,
|
216
|
-
req.inspect
|
217
|
-
])
|
218
|
-
end
|
234
|
+
def send(req)
|
235
|
+
req.tag ||= next_tag
|
219
236
|
|
220
237
|
@cbx[req.tag] = req
|
221
238
|
|
@@ -225,6 +242,44 @@ module Fraggle
|
|
225
242
|
req
|
226
243
|
end
|
227
244
|
|
245
|
+
def resend(req)
|
246
|
+
req.tag ||= next_tag
|
247
|
+
|
248
|
+
wrap = Request.new(req.to_hash)
|
249
|
+
|
250
|
+
req.valid do |e|
|
251
|
+
if req.offset
|
252
|
+
req.offset += 1
|
253
|
+
end
|
254
|
+
|
255
|
+
if req.limit
|
256
|
+
req.limit -= 1
|
257
|
+
end
|
258
|
+
|
259
|
+
if (req.rev || 0) < (e.rev || 0)
|
260
|
+
req.rev = e.rev
|
261
|
+
end
|
262
|
+
|
263
|
+
wrap.emit(:valid, e)
|
264
|
+
end
|
265
|
+
|
266
|
+
req.error do |err|
|
267
|
+
if err.disconnected?
|
268
|
+
send(req)
|
269
|
+
else
|
270
|
+
wrap.emit(:error, err)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
req.done do
|
275
|
+
wrap.emit(:done)
|
276
|
+
end
|
277
|
+
|
278
|
+
send(req)
|
279
|
+
|
280
|
+
wrap
|
281
|
+
end
|
282
|
+
|
228
283
|
def cancelable(req)
|
229
284
|
c = self
|
230
285
|
can = true
|
@@ -246,88 +301,52 @@ module Fraggle
|
|
246
301
|
def post_init
|
247
302
|
info "successfully connected to #{@addr}"
|
248
303
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
req.emit(:again, req)
|
304
|
+
res = Response.new(:err_code => Errno::ECONNREFUSED::Errno)
|
305
|
+
@cbx.values.compact.each do |req|
|
306
|
+
debug "sending disconnected error to #{req.inspect}"
|
307
|
+
req.emit(:error, res)
|
254
308
|
end
|
255
309
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
close_connection
|
260
|
-
else
|
261
|
-
get(0, "/ping")
|
262
|
-
end
|
310
|
+
if ! @tracking
|
311
|
+
trackaddrs
|
312
|
+
@tracking = true
|
263
313
|
end
|
314
|
+
end
|
264
315
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
info "pardoning #{addr} after #{n} secs"
|
277
|
-
@shun.delete(addr)
|
278
|
-
else
|
279
|
-
info "ignoring shunned addr #{addr}"
|
280
|
-
next
|
281
|
-
end
|
316
|
+
# Track addresses of doozers in a cluster. This will retry
|
317
|
+
# in the event of a new connection.
|
318
|
+
def trackaddrs
|
319
|
+
rev.valid do |v|
|
320
|
+
monitor(v.rev, "/doozer/slot/*").valid do |e|
|
321
|
+
if e.value == ""
|
322
|
+
@addrs.delete(e.path)
|
323
|
+
else
|
324
|
+
get(v.rev, "/doozer/info/#{e.value}/addr").valid do |g|
|
325
|
+
next if g.value == @addr
|
326
|
+
@addrs[e.path] = g.value
|
282
327
|
end
|
283
|
-
# TODO: Be defensive and check the addr value is valid
|
284
|
-
@addrs[e.path] = addr
|
285
|
-
info("added #{e.path} addr #{addr}")
|
286
328
|
end
|
329
|
+
end.error do |err|
|
330
|
+
error "address tracking: #{err.inspect} for #{req.inspect}"
|
287
331
|
end
|
288
332
|
end
|
289
|
-
|
290
|
-
watch("/doozer/slot/*", &waw)
|
291
|
-
|
292
|
-
w = walk(0, "/doozer/slot/*", &waw)
|
293
|
-
w.done do
|
294
|
-
# We have the best known addrs; We can clear the initial
|
295
|
-
# ones given at inception.
|
296
|
-
debug "addrs list complete; clearing init addrs"
|
297
|
-
@init.clear
|
298
|
-
end
|
299
333
|
end
|
300
334
|
|
301
335
|
# What happens when a connection is closed for any reason.
|
302
336
|
def unbind
|
303
|
-
|
304
|
-
|
305
|
-
# Shun the address we were currently attempting/connected to.
|
306
|
-
@shun[@addr] = Time.now
|
307
|
-
@addrs.delete_if {|_, v| v == @addr }
|
308
|
-
|
309
|
-
# We don't want the timer to race us while
|
310
|
-
# we're trying to reconnect. Once the reconnect
|
311
|
-
# has been complete, we'll start the timer again.
|
312
|
-
EM.cancel_timer(@timer)
|
337
|
+
info "disconnected from #{@addr}"
|
313
338
|
|
314
|
-
# Attempt to use an addr given to us by a Doozer
|
315
339
|
_, @addr = @addrs.shift
|
316
|
-
|
317
|
-
if ! @addr
|
318
|
-
# As a last resort, try one of the addresses given
|
319
|
-
# at inception.
|
320
|
-
@addr = @init.shift
|
321
|
-
end
|
322
|
-
|
323
340
|
if ! @addr
|
324
|
-
|
325
|
-
raise NoAddrs
|
341
|
+
raise "No more addrs"
|
326
342
|
end
|
327
343
|
|
328
344
|
host, port = @addr.split(":")
|
329
|
-
|
345
|
+
|
346
|
+
info "attempting connection to #{@addr}"
|
347
|
+
|
330
348
|
reconnect(host, port.to_i)
|
349
|
+
|
331
350
|
post_init
|
332
351
|
end
|
333
352
|
|
data/lib/fraggle/msg.rb
CHANGED
@@ -8,23 +8,22 @@ module Fraggle
|
|
8
8
|
required :tag, :int32, 1
|
9
9
|
|
10
10
|
module Verb
|
11
|
-
CHECKIN = 0; #
|
12
|
-
GET = 1; # path, id =>
|
13
|
-
SET = 2; #
|
14
|
-
DEL = 3; #
|
15
|
-
ESET = 4; #
|
16
|
-
|
17
|
-
DELSNAP = 6; # id => {}
|
11
|
+
CHECKIN = 0; # rev, id => rev
|
12
|
+
GET = 1; # path, id => rev, value
|
13
|
+
SET = 2; # rev, path, value => rev
|
14
|
+
DEL = 3; # rev, path => {}
|
15
|
+
ESET = 4; # rev, path => {}
|
16
|
+
REV = 5; # {} => seqn, id
|
18
17
|
NOOP = 7; # {} => {}
|
19
|
-
WATCH = 8; # path => {
|
18
|
+
WATCH = 8; # path => {rev, path, value}+
|
20
19
|
CANCEL = 10; # id => {}
|
21
|
-
STAT = 16; # path, id =>
|
20
|
+
STAT = 16; # path, id => rev, len
|
22
21
|
|
23
22
|
# future
|
24
|
-
GETDIR = 14; # path => {
|
25
|
-
MONITOR = 11; # path => {
|
26
|
-
SYNCPATH = 12; # path =>
|
27
|
-
WALK = 9; # path, id => {
|
23
|
+
GETDIR = 14; # path => {rev, value}+
|
24
|
+
MONITOR = 11; # path => {rev, path, value}+
|
25
|
+
SYNCPATH = 12; # path => rev, value
|
26
|
+
WALK = 9; # path, id => {rev, path, value}+
|
28
27
|
|
29
28
|
# deprecated
|
30
29
|
JOIN = 13;
|
@@ -32,7 +31,6 @@ module Fraggle
|
|
32
31
|
|
33
32
|
required :verb, Verb, 2
|
34
33
|
|
35
|
-
optional :cas, :int64, 3
|
36
34
|
optional :path, :string, 4
|
37
35
|
optional :value, :bytes, 5
|
38
36
|
optional :id, :int32, 6
|
@@ -40,6 +38,7 @@ module Fraggle
|
|
40
38
|
optional :offset, :int32, 7
|
41
39
|
optional :limit, :int32, 8
|
42
40
|
|
41
|
+
optional :rev, :int64, 9
|
43
42
|
end
|
44
43
|
|
45
44
|
|
@@ -56,18 +55,13 @@ module Fraggle
|
|
56
55
|
optional :id, :int32, 7
|
57
56
|
optional :len, :int32, 8
|
58
57
|
|
59
|
-
module Flag
|
60
|
-
VALID = 1
|
61
|
-
DONE = 2
|
62
|
-
end
|
63
|
-
|
64
58
|
module Err
|
65
59
|
# don't use value 0
|
66
60
|
OTHER = 127
|
67
61
|
TAG_IN_USE = 1
|
68
62
|
UNKNOWN_VERB = 2
|
69
63
|
REDIRECT = 3
|
70
|
-
|
64
|
+
TOO_LATE = 4
|
71
65
|
CAS_MISMATCH = 5
|
72
66
|
|
73
67
|
# match unix errno
|
data/lib/fraggle/response.rb
CHANGED
@@ -9,27 +9,35 @@ module Fraggle
|
|
9
9
|
|
10
10
|
class Response
|
11
11
|
|
12
|
+
module Flag
|
13
|
+
VALID = 1
|
14
|
+
DONE = 2
|
15
|
+
SET = 4
|
16
|
+
DEL = 8
|
17
|
+
end
|
18
|
+
|
19
|
+
|
12
20
|
Missing = 0
|
13
21
|
Clobber = -1
|
14
22
|
Dir = -2
|
15
|
-
|
23
|
+
Nop = -3
|
16
24
|
|
17
25
|
Refused = -1
|
18
26
|
|
19
27
|
# CAS
|
20
|
-
def missing? ;
|
21
|
-
def dir? ;
|
22
|
-
def dummy? ;
|
28
|
+
def missing? ; rev == Missing ; end
|
29
|
+
def dir? ; rev == Dir ; end
|
30
|
+
def dummy? ; rev == Nop ; end
|
23
31
|
|
24
|
-
def del? ;
|
25
|
-
def set? ;
|
32
|
+
def del? ; (flags & Flag::Del) > 0 ; end
|
33
|
+
def set? ; (flags & Flag::Set) > 0 ; end
|
26
34
|
|
27
35
|
# ERR
|
28
36
|
def ok? ; err_code != 0 ; end
|
29
37
|
def other? ; err_code == Err::OTHER ; end
|
30
38
|
def unknown_verb? ; err_code == Err::UNKNOWN_VERB ; end
|
31
39
|
def redirect? ; err_code == Err::REDIRECT ; end
|
32
|
-
def
|
40
|
+
def too_late? ; err_code == Err::TOO_LATE ; end
|
33
41
|
def mismatch? ; err_code == Err::CAS_MISMATCH ; end
|
34
42
|
def not_dir? ; err_code == Err::NOT_DIR ; end
|
35
43
|
def is_dir? ; err_code == Err::ISDIR ; end
|
data/lib/fraggle.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
+
require 'fraggle/client'
|
1
2
|
require 'fraggle/errors'
|
2
3
|
require 'fraggle/logger'
|
3
|
-
require 'fraggle/snap'
|
4
4
|
require 'uri'
|
5
5
|
|
6
6
|
module Fraggle
|
@@ -15,11 +15,13 @@ module Fraggle
|
|
15
15
|
"ca=127.0.0.1:8042&"+
|
16
16
|
"ca=127.0.0.1:8043"
|
17
17
|
|
18
|
-
def self.connect(
|
18
|
+
def self.connect(*args)
|
19
|
+
opts = args.last.is_a?(Hash) ? args.pop : {}
|
20
|
+
uri = args.shift || ENV["DOOZER_URI"] || DefaultUri
|
19
21
|
addrs = addrs_for(uri)
|
22
|
+
|
20
23
|
host, port = addrs.first.split(":")
|
21
|
-
|
22
|
-
Snap.new(0, c)
|
24
|
+
EM.connect(host, port, Client, addrs.shift, addrs, opts)
|
23
25
|
end
|
24
26
|
|
25
27
|
def self.addrs_for(uri)
|
data/test/fraggle_client_test.rb
CHANGED
@@ -13,14 +13,14 @@ class FraggleClientTest < Test::Unit::TestCase
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_send_recv
|
16
|
-
req = c.send(Fraggle::Request.new
|
16
|
+
req = c.send(Fraggle::Request.new).valid(&blk)
|
17
17
|
|
18
18
|
assert_sent req.tag
|
19
19
|
assert_recv reply(req.tag)
|
20
20
|
end
|
21
21
|
|
22
22
|
def test_valid
|
23
|
-
req = c.send(Fraggle::Request.new
|
23
|
+
req = c.send(Fraggle::Request.new).valid(&blk)
|
24
24
|
|
25
25
|
reply(req.tag)
|
26
26
|
reply(req.tag)
|
@@ -74,100 +74,84 @@ class FraggleClientTest < Test::Unit::TestCase
|
|
74
74
|
|
75
75
|
# CHECKIN cas, path => cas
|
76
76
|
def test_checkin
|
77
|
-
req = c.checkin("abc123", 123
|
77
|
+
req = c.checkin("abc123", 123).valid(&blk)
|
78
78
|
|
79
|
-
assert_sent(req.tag, :verb => V::CHECKIN, :path => "abc123", :
|
80
|
-
assert_recv(reply(req.tag, :
|
79
|
+
assert_sent(req.tag, :verb => V::CHECKIN, :path => "abc123", :rev => 123)
|
80
|
+
assert_recv(reply(req.tag, :rev => 123))
|
81
81
|
end
|
82
82
|
|
83
83
|
# GET path, id => cas, value
|
84
84
|
def test_get
|
85
|
-
req = c.get(0, "/ping"
|
85
|
+
req = c.get(0, "/ping").valid(&blk)
|
86
86
|
|
87
|
-
assert_sent req.tag, :verb => V::GET, :path => "/ping"
|
87
|
+
assert_sent req.tag, :rev => 0, :verb => V::GET, :path => "/ping"
|
88
88
|
assert_recv reply(req.tag, :cas => 123, :value => "pong")
|
89
89
|
end
|
90
90
|
|
91
91
|
# STAT path, id => cas, len
|
92
92
|
def test_stat
|
93
|
-
req = c.stat(0, "/ping"
|
93
|
+
req = c.stat(0, "/ping").valid(&blk)
|
94
94
|
|
95
|
-
assert_sent req.tag, :verb => V::STAT, :path => "/ping"
|
95
|
+
assert_sent req.tag, :rev => 0, :verb => V::STAT, :path => "/ping"
|
96
96
|
assert_recv reply(req.tag, :cas => 123, :len => 4)
|
97
97
|
end
|
98
98
|
|
99
99
|
# GETDIR id, path, offset, limit => {cas, value}+
|
100
100
|
def test_getdir
|
101
|
-
req = c.getdir(0, "/test",
|
101
|
+
req = c.getdir(0, "/test", nil, nil).valid(&blk)
|
102
102
|
|
103
|
-
assert_sent req.tag, :verb => V::GETDIR, :path => "/test"
|
104
|
-
assert_recv reply(req.tag, :
|
103
|
+
assert_sent req.tag, :rev => 0, :verb => V::GETDIR, :path => "/test"
|
104
|
+
assert_recv reply(req.tag, :rev => 123, :value => "a")
|
105
105
|
|
106
|
-
req = c.getdir(0, "/test", 1, 2
|
106
|
+
req = c.getdir(0, "/test", 1, 2).valid(&blk)
|
107
107
|
|
108
|
-
assert_sent req.tag, :verb => V::GETDIR, :path => "/test", :offset => 1, :limit => 2
|
108
|
+
assert_sent req.tag, :rev => 0, :verb => V::GETDIR, :path => "/test", :offset => 1, :limit => 2
|
109
109
|
assert_recv reply(req.tag, :cas => 123, :value => "b")
|
110
110
|
end
|
111
111
|
|
112
112
|
# SET cas, path, value => cas
|
113
113
|
def test_set
|
114
|
-
req = c.set("/foo", "bar", 123
|
114
|
+
req = c.set("/foo", "bar", 123).valid(&blk)
|
115
115
|
|
116
|
-
assert_sent(req.tag, :verb => V::SET, :
|
117
|
-
assert_recv(reply(req.tag, :
|
116
|
+
assert_sent(req.tag, :verb => V::SET, :rev => 123, :path => "/foo", :value => "bar")
|
117
|
+
assert_recv(reply(req.tag, :rev => 123))
|
118
118
|
end
|
119
119
|
|
120
120
|
# DEL cas, path => {}
|
121
121
|
def test_del
|
122
|
-
req = c.del("/foo", 123
|
122
|
+
req = c.del("/foo", 123).valid(&blk)
|
123
123
|
|
124
|
-
assert_sent(req.tag, :verb => V::DEL, :
|
124
|
+
assert_sent(req.tag, :verb => V::DEL, :rev => 123, :path => "/foo")
|
125
125
|
assert_recv(reply(req.tag))
|
126
126
|
end
|
127
127
|
|
128
128
|
# WALK path, id => {cas, path, value}+
|
129
129
|
def test_walk
|
130
|
-
req = c.walk(
|
130
|
+
req = c.walk(nil, "/foo/*").valid(&blk)
|
131
131
|
|
132
132
|
assert_respond_to req, :cancel
|
133
133
|
|
134
134
|
assert_sent(req.tag, :verb => V::WALK, :path => "/foo/*")
|
135
|
-
assert_recv(reply(req.tag, :
|
136
|
-
assert_recv(reply(req.tag, :
|
137
|
-
assert_recv(reply(req.tag, :
|
135
|
+
assert_recv(reply(req.tag, :rev => 123, :path => "/foo/a", :value => "1"))
|
136
|
+
assert_recv(reply(req.tag, :rev => 456, :path => "/foo/b", :value => "2"))
|
137
|
+
assert_recv(reply(req.tag, :rev => 789, :path => "/foo/c", :value => "3"))
|
138
138
|
end
|
139
139
|
|
140
140
|
# WATCH path => {cas, path, value}+
|
141
141
|
def test_watch
|
142
|
-
req = c.watch("/foo/*"
|
142
|
+
req = c.watch(123, "/foo/*").valid(&blk)
|
143
143
|
|
144
144
|
assert_respond_to req, :cancel
|
145
145
|
|
146
|
-
assert_sent(req.tag, :verb => V::WATCH, :path => "/foo/*")
|
146
|
+
assert_sent(req.tag, :rev => 123, :verb => V::WATCH, :path => "/foo/*")
|
147
147
|
assert_recv(reply(req.tag, :cas => 123, :path => "/foo/a", :value => "1"))
|
148
148
|
assert_recv(reply(req.tag, :cas => 456, :path => "/foo/b", :value => "2"))
|
149
149
|
assert_recv(reply(req.tag, :cas => 789, :path => "/foo/c", :value => "3"))
|
150
150
|
end
|
151
151
|
|
152
|
-
# SNAP {} => id
|
153
|
-
def test_snap
|
154
|
-
req = c.snap(&blk)
|
155
|
-
|
156
|
-
assert_sent(req.tag, :verb => V::SNAP)
|
157
|
-
assert_recv(reply(req.tag, :id => 1))
|
158
|
-
end
|
159
|
-
|
160
|
-
# DELSNAP id => {}
|
161
|
-
def test_delsnap
|
162
|
-
req = c.delsnap(1, &blk)
|
163
|
-
|
164
|
-
assert_sent(req.tag, :verb => V::DELSNAP, :id => 1)
|
165
|
-
assert_recv(reply(req.tag))
|
166
|
-
end
|
167
|
-
|
168
152
|
# NOOP {} => {}
|
169
153
|
def test_noop
|
170
|
-
req = c.noop(&blk)
|
154
|
+
req = c.noop.valid(&blk)
|
171
155
|
|
172
156
|
assert_sent(req.tag, :verb => V::NOOP)
|
173
157
|
assert_recv(reply(req.tag))
|
@@ -175,8 +159,8 @@ class FraggleClientTest < Test::Unit::TestCase
|
|
175
159
|
|
176
160
|
# CANCEL id => {}
|
177
161
|
def test_cancel
|
178
|
-
nop = c.noop(&blk)
|
179
|
-
req = c.__cancel__(nop
|
162
|
+
nop = c.noop.valid(&blk)
|
163
|
+
req = c.__cancel__(nop).valid(&blk)
|
180
164
|
|
181
165
|
assert_sent(req.tag, :verb => V::CANCEL, :id => nop.tag)
|
182
166
|
assert_recv(reply(req.tag))
|
@@ -202,7 +186,7 @@ class FraggleClientTest < Test::Unit::TestCase
|
|
202
186
|
end
|
203
187
|
|
204
188
|
def test_cancel_does_not_prematurely_remove_callback
|
205
|
-
x = c.watch("/foo/*"
|
189
|
+
x = c.watch(123, "/foo/*").valid(&blk)
|
206
190
|
y = x.cancel
|
207
191
|
|
208
192
|
assert_not_equal x.object_id, y.object_id
|
@@ -210,7 +194,7 @@ class FraggleClientTest < Test::Unit::TestCase
|
|
210
194
|
end
|
211
195
|
|
212
196
|
def test_cancel_discards_further_replies
|
213
|
-
x = c.watch("/foo/*"
|
197
|
+
x = c.watch(123, "/foo/*").valid(&blk)
|
214
198
|
x.cancel
|
215
199
|
|
216
200
|
reply!(x.tag)
|
@@ -221,7 +205,7 @@ class FraggleClientTest < Test::Unit::TestCase
|
|
221
205
|
end
|
222
206
|
|
223
207
|
def test_tag_pending_cancel_is_not_useable
|
224
|
-
x = c.watch("/foo/*"
|
208
|
+
x = c.watch(123, "/foo/*").valid(&blk)
|
225
209
|
y = x.cancel
|
226
210
|
|
227
211
|
# Force a reset of tag so that `send` will attempt
|
@@ -235,7 +219,7 @@ class FraggleClientTest < Test::Unit::TestCase
|
|
235
219
|
end
|
236
220
|
|
237
221
|
def test_reuse_canceled_tag
|
238
|
-
x = c.watch("/foo/*"
|
222
|
+
x = c.watch(123, "/foo/*").valid(&blk)
|
239
223
|
y = x.cancel
|
240
224
|
|
241
225
|
reply!(y.tag)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fraggle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 0.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Blake Mizerany
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-03-21 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -55,12 +55,10 @@ files:
|
|
55
55
|
- lib/fraggle/protocol.rb
|
56
56
|
- lib/fraggle/request.rb
|
57
57
|
- lib/fraggle/response.rb
|
58
|
-
- lib/fraggle/snap.rb
|
59
58
|
- lib/fraggle/test.rb
|
60
59
|
- lib/fraggle.rb
|
61
60
|
- test/fraggle_client_test.rb
|
62
61
|
- test/fraggle_protocol_test.rb
|
63
|
-
- test/fraggle_snap_test.rb
|
64
62
|
- test/fraggle_test.rb
|
65
63
|
has_rdoc: true
|
66
64
|
homepage: http://github.com/bmizerany/fraggle
|
@@ -104,5 +102,4 @@ summary: A Ruby/EventMachine Client for Doozer
|
|
104
102
|
test_files:
|
105
103
|
- test/fraggle_client_test.rb
|
106
104
|
- test/fraggle_protocol_test.rb
|
107
|
-
- test/fraggle_snap_test.rb
|
108
105
|
- test/fraggle_test.rb
|
data/lib/fraggle/snap.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'fraggle/client'
|
2
|
-
|
3
|
-
module Fraggle
|
4
|
-
|
5
|
-
class Snap
|
6
|
-
|
7
|
-
attr_reader :id, :rev, :c
|
8
|
-
|
9
|
-
def initialize(id, c, rev=nil)
|
10
|
-
@id = id
|
11
|
-
@c = c
|
12
|
-
@rev = rev
|
13
|
-
end
|
14
|
-
|
15
|
-
def get(path, &blk)
|
16
|
-
@c.get(@id, path, &blk)
|
17
|
-
end
|
18
|
-
|
19
|
-
def walk(glob, &blk)
|
20
|
-
@c.walk(@id, glob, &blk)
|
21
|
-
end
|
22
|
-
|
23
|
-
def stat(path, &blk)
|
24
|
-
@c.stat(@id, path, &blk)
|
25
|
-
end
|
26
|
-
|
27
|
-
def getdir(path, offset=0, limit=0, &blk)
|
28
|
-
@c.getdir(@id, path, offset, limit, &blk)
|
29
|
-
end
|
30
|
-
|
31
|
-
def snap(&blk)
|
32
|
-
@c.snap do |res|
|
33
|
-
sn = Snap.new(res.id, @c, res.rev)
|
34
|
-
blk.call(sn)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
def delete(&blk)
|
39
|
-
@c.delsnap(@id, &blk)
|
40
|
-
end
|
41
|
-
|
42
|
-
def send(req, &blk)
|
43
|
-
@c.send(req, &blk)
|
44
|
-
end
|
45
|
-
|
46
|
-
def method_missing(*args, &blk)
|
47
|
-
@c.__send__(*args, &blk)
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
data/test/fraggle_snap_test.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
require 'fraggle/test'
|
2
|
-
require 'fraggle/snap'
|
3
|
-
|
4
|
-
class FraggleSnapTest < Test::Unit::TestCase
|
5
|
-
include Fraggle::Test
|
6
|
-
|
7
|
-
attr_reader :c, :blk
|
8
|
-
|
9
|
-
def setup
|
10
|
-
cl = TestClient.new(["127.0.0.1:8046"])
|
11
|
-
@c = Fraggle::Snap.new(1, cl)
|
12
|
-
@blk = Blk.new
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_get
|
16
|
-
req = c.get("/ping", &blk)
|
17
|
-
|
18
|
-
assert_sent req.tag, :verb => V::GET, :id => 1, :path => "/ping"
|
19
|
-
assert_recv reply(req.tag)
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_stat
|
23
|
-
req = c.stat("/ping", &blk)
|
24
|
-
|
25
|
-
assert_sent req.tag, :verb => V::STAT, :id => 1, :path => "/ping"
|
26
|
-
assert_recv reply(req.tag)
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_getdir
|
30
|
-
req = c.getdir("/test", &blk)
|
31
|
-
|
32
|
-
assert_sent req.tag, :verb => V::GETDIR, :path => "/test", :id => 1
|
33
|
-
assert_recv reply(req.tag)
|
34
|
-
|
35
|
-
req = c.getdir("/test", 1, 2, &blk)
|
36
|
-
|
37
|
-
assert_sent req.tag, :verb => V::GETDIR, :path => "/test", :offset => 1, :limit => 2, :id => 1
|
38
|
-
assert_recv reply(req.tag)
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_walk
|
42
|
-
req = c.walk("/letters/*", &blk)
|
43
|
-
|
44
|
-
assert_sent req.tag, :verb => V::WALK, :id => 1, :path => "/letters/*"
|
45
|
-
assert_recv reply(req.tag)
|
46
|
-
end
|
47
|
-
|
48
|
-
def test_other
|
49
|
-
req = c.noop(&blk)
|
50
|
-
|
51
|
-
assert_sent req.tag, :verb => V::NOOP
|
52
|
-
assert_recv reply(req.tag)
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_snap
|
56
|
-
b = nil
|
57
|
-
a = c.snap do |sn|
|
58
|
-
b = sn.get("/ping")
|
59
|
-
end
|
60
|
-
|
61
|
-
reply(a.tag, :id => 99)
|
62
|
-
|
63
|
-
assert_sent a.tag, :verb => V::SNAP
|
64
|
-
assert_sent b.tag, :verb => V::GET, :id => 99, :path => "/ping"
|
65
|
-
end
|
66
|
-
|
67
|
-
end
|