fraggle 0.3.5 → 0.4.0
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/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
|