fraggle 1.0.1 → 2.0.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/README.md +18 -16
- data/Rakefile +1 -1
- data/example/getdir.rb +45 -6
- data/example/{redirect.rb → readonly.rb} +0 -0
- data/example/resend.rb +2 -1
- data/example/set.rb +5 -2
- data/lib/fraggle/client.rb +14 -76
- data/lib/fraggle/connection.rb +4 -29
- data/lib/fraggle/msg.pb.rb +8 -11
- data/lib/fraggle/request.rb +0 -8
- data/lib/fraggle/response.rb +2 -14
- data/lib/fraggle/version.rb +1 -1
- data/test/fraggle_client_test.rb +10 -114
- data/test/fraggle_protocol_test.rb +7 -7
- data/test/fraggle_transaction_test.rb +5 -95
- data/test/helper.rb +0 -7
- metadata +5 -7
- data/example/addrs.rb +0 -13
- data/example/watch.rb +0 -20
data/README.md
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
# Fraggle (
|
1
|
+
# Fraggle (v2.0.0 is compatible with Doozer 0.6)
|
2
|
+
|
3
|
+
Fraggle currently is only a raw interface to Doozer 0.6.
|
4
|
+
Sugar for `WALK`, `GETDIR`, etc are to come in v3.0.0.
|
5
|
+
|
2
6
|
**An EventMachine based Doozer client**
|
3
7
|
|
4
8
|
## Install
|
@@ -90,16 +94,14 @@ This also means you can go back in time or into the future!
|
|
90
94
|
# This will not yield until the data store is at revision 100,000
|
91
95
|
c.get("/a", 100_000) { ... }
|
92
96
|
|
97
|
+
NOTE: Doozer's data store is a persistent data structure. You can reference the
|
98
|
+
stores history as far back as it is configured to hold it. The default is
|
99
|
+
360,000 revisions. See [data model][] for more information.
|
100
|
+
|
93
101
|
## High Availability
|
94
102
|
|
95
103
|
Fraggle has mechanisms to gracefully deal with connection loss. They are:
|
96
104
|
|
97
|
-
*Monitoring cluster activity*
|
98
|
-
|
99
|
-
Fraggle monitors new Doozer nodes that come and go. This enables Fraggle to
|
100
|
-
keep an up-to-date list of available nodes it can connect to in the case of
|
101
|
-
a connection loss.
|
102
|
-
|
103
105
|
*Resend / Connection loss*
|
104
106
|
|
105
107
|
When a connection is lost and Fraggle successfully reconnects to another
|
@@ -107,21 +109,14 @@ This also means you can go back in time or into the future!
|
|
107
109
|
This means you will not miss events; Even events that happened while you were
|
108
110
|
disconnected! All read commands will pick up where they left off. This is
|
109
111
|
valuable to understand because it means you don't need to code for failure on
|
110
|
-
reads; Fraggle gracefully handles it for you.
|
111
|
-
the `WATCH` command.
|
112
|
+
reads; Fraggle gracefully handles it for you.
|
112
113
|
|
113
114
|
Write commands will be resent if their `rev` is greater than 0. These are
|
114
|
-
idempotent requests. A rev of 0
|
115
|
+
idempotent requests. A rev of 0 will cause that request's error
|
115
116
|
callback to be invoked with a Fraggle::Connection::Disconnected response.
|
116
117
|
You will have to handle these yourself because Fraggle cannot know whether or
|
117
118
|
not it's safe to retry on your behalf.
|
118
119
|
|
119
|
-
For commands with multiple responses (i.e. `walk`, `watch`, `getdir`), Fraggle
|
120
|
-
will update their offset and limit as each response comes in. This means
|
121
|
-
if you disconnect in the middle of the responses, Fraggle will gracefully
|
122
|
-
resend the requests making it appear nothing happened and continue giving you
|
123
|
-
the remaining responses.
|
124
|
-
|
125
120
|
## Dev
|
126
121
|
|
127
122
|
**Clone**
|
@@ -133,3 +128,10 @@ This also means you can go back in time or into the future!
|
|
133
128
|
$ gem install turn
|
134
129
|
|
135
130
|
$ turn
|
131
|
+
|
132
|
+
**Mailing List**
|
133
|
+
|
134
|
+
Please join the Doozer mailing list for help:
|
135
|
+
http://groups.google.com/forum/#!forum/doozer
|
136
|
+
|
137
|
+
[data model]: https://github.com/ha/doozerd/blob/master/doc/data-model.md
|
data/Rakefile
CHANGED
data/example/getdir.rb
CHANGED
@@ -4,16 +4,55 @@ require 'fraggle'
|
|
4
4
|
|
5
5
|
EM.run do
|
6
6
|
|
7
|
+
## NOTE: This will be easier the very near future.
|
8
|
+
|
9
|
+
## Collects names in a directory
|
10
|
+
|
7
11
|
c = Fraggle.connect
|
8
12
|
c.log.level = Logger::DEBUG
|
9
13
|
|
10
|
-
|
11
|
-
|
14
|
+
def c.getdirx(path, rev, offset, &blk)
|
15
|
+
w = Request.new
|
16
|
+
w.valid(&blk)
|
17
|
+
|
18
|
+
err = Proc.new do |e|
|
19
|
+
if e.err_code == Fraggle::Response::Err::AGAIN
|
20
|
+
w.emit(:done)
|
21
|
+
else
|
22
|
+
w.emit(:error, e)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
req = getdir(path, rev, offset) do |e|
|
27
|
+
blk.call(e)
|
28
|
+
req = getdirx(path, rev, offset+1, &blk)
|
29
|
+
req.error(&err)
|
30
|
+
end
|
31
|
+
req.error(&err)
|
32
|
+
|
33
|
+
w
|
34
|
+
end
|
35
|
+
|
36
|
+
ents, n = [], 0
|
37
|
+
|
38
|
+
f = Proc.new do |e|
|
12
39
|
ents << e.path
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
40
|
+
n += 1
|
41
|
+
c.getdir("/ctl", nil, n, &f).error do |e|
|
42
|
+
if e.err_code == Fraggle::Response::Err::RANGE
|
43
|
+
p [:ents, ents]
|
44
|
+
else
|
45
|
+
p [:err, e]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
c.getdir("/ctl", nil, n, &f).error do |e|
|
51
|
+
if e.err_code == Fraggle::Response::Err::RANGE
|
52
|
+
p [:ents, ents]
|
53
|
+
else
|
54
|
+
p [:err, e]
|
55
|
+
end
|
17
56
|
end
|
18
57
|
|
19
58
|
end
|
File without changes
|
data/example/resend.rb
CHANGED
@@ -9,13 +9,14 @@ require 'fraggle'
|
|
9
9
|
#
|
10
10
|
EM.run do
|
11
11
|
c = Fraggle.connect
|
12
|
+
c.log.level = Logger::DEBUG
|
12
13
|
|
13
14
|
puts "# To see this work, kill the doozer this is connected to"
|
14
15
|
puts "# to see it resend the request to the next connection."
|
15
16
|
puts
|
16
17
|
|
17
18
|
# Wait for rev 100,000
|
18
|
-
c.get(
|
19
|
+
c.get("/foo", 100_000) do |e|
|
19
20
|
p ["This should not be!", e]
|
20
21
|
end.error do |e|
|
21
22
|
p [:err, e]
|
data/example/set.rb
CHANGED
@@ -2,8 +2,11 @@ require 'rubygems'
|
|
2
2
|
require 'eventmachine'
|
3
3
|
require 'fraggle'
|
4
4
|
|
5
|
+
MaxInt64 = (1<<62)-1
|
6
|
+
|
5
7
|
EM.run do
|
6
8
|
c = Fraggle.connect
|
9
|
+
c.log.level = Logger::DEBUG
|
7
10
|
|
8
11
|
EM.add_periodic_timer(1) do
|
9
12
|
c.get("/hello") do |e|
|
@@ -11,7 +14,7 @@ EM.run do
|
|
11
14
|
end
|
12
15
|
end
|
13
16
|
|
14
|
-
c.set('/hello', 'world',
|
15
|
-
p e
|
17
|
+
c.set('/hello', 'world', MaxInt64) do |e|
|
18
|
+
p [:set, e]
|
16
19
|
end
|
17
20
|
end
|
data/lib/fraggle/client.rb
CHANGED
@@ -16,7 +16,6 @@ module Fraggle
|
|
16
16
|
|
17
17
|
def initialize(cn, addrs, log=DefaultLog)
|
18
18
|
@cn, @addrs, @log = cn, addrs, log
|
19
|
-
monitor_addrs
|
20
19
|
end
|
21
20
|
|
22
21
|
def addr
|
@@ -54,41 +53,31 @@ module Fraggle
|
|
54
53
|
idemp(req)
|
55
54
|
end
|
56
55
|
|
57
|
-
def getdir(path, rev=nil, offset=nil,
|
56
|
+
def getdir(path, rev=nil, offset=nil, &blk)
|
58
57
|
req = Request.new
|
59
|
-
req.verb
|
60
|
-
req.rev
|
61
|
-
req.path
|
62
|
-
|
63
|
-
# To reliably pick-up where we left off in the event of a disconnect, we
|
64
|
-
# must default the offset to zero. This is best done here and not in the
|
65
|
-
# param declaration because the user could override it to nil there.
|
66
|
-
req.offset = offset || 0
|
67
|
-
req.limit = limit
|
58
|
+
req.verb = GETDIR
|
59
|
+
req.rev = rev
|
60
|
+
req.path = path
|
61
|
+
req.offset = offset
|
68
62
|
req.valid(&blk)
|
69
63
|
|
70
64
|
resend(req)
|
71
65
|
end
|
72
66
|
|
73
|
-
def walk(path, rev=nil, offset=nil,
|
67
|
+
def walk(path, rev=nil, offset=nil, &blk)
|
74
68
|
req = Request.new
|
75
|
-
req.verb
|
76
|
-
req.rev
|
77
|
-
req.path
|
78
|
-
|
79
|
-
# To reliably pick-up where we left off in the event of a disconnect, we
|
80
|
-
# must default the offset to zero. This is best done here and not in the
|
81
|
-
# param declaration because the user could override it to nil there.
|
82
|
-
req.offset = offset || 0
|
83
|
-
req.limit = limit
|
69
|
+
req.verb = WALK
|
70
|
+
req.rev = rev
|
71
|
+
req.path = path
|
72
|
+
req.offset = offset
|
84
73
|
req.valid(&blk)
|
85
74
|
|
86
75
|
resend(req)
|
87
76
|
end
|
88
77
|
|
89
|
-
def
|
78
|
+
def wait(path, rev=nil, &blk)
|
90
79
|
req = Request.new
|
91
|
-
req.verb =
|
80
|
+
req.verb = WAIT
|
92
81
|
req.rev = rev
|
93
82
|
req.path = path
|
94
83
|
req.valid(&blk)
|
@@ -114,43 +103,6 @@ module Fraggle
|
|
114
103
|
resend(req)
|
115
104
|
end
|
116
105
|
|
117
|
-
def monitor_addrs
|
118
|
-
log.debug("monitor addrs")
|
119
|
-
rev do |v|
|
120
|
-
walk("/ctl/cal/*", v.rev) do |e|
|
121
|
-
get("/ctl/node/#{e.value}/addr", v.rev) do |a|
|
122
|
-
if a.value != ""
|
123
|
-
add_addr(a.value)
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end.done do
|
127
|
-
watch("/ctl/cal/*", v.rev+1) do |e|
|
128
|
-
if e.value == ""
|
129
|
-
## Look to see what it was before
|
130
|
-
get(e.path, e.rev-1) do |b|
|
131
|
-
if b.rev > 0
|
132
|
-
# The node was cleared. Delete it from the list of addrs.
|
133
|
-
log.debug("del addr: #{addr}")
|
134
|
-
@addrs.delete(b.value)
|
135
|
-
end
|
136
|
-
end
|
137
|
-
else
|
138
|
-
get("/ctl/node/#{e.value}/addr", e.rev) do |b|
|
139
|
-
add_addr(b.value)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
def add_addr(s)
|
148
|
-
return if s == self.addr
|
149
|
-
return if @addrs.include?(s)
|
150
|
-
log.debug("add addr: #{s}")
|
151
|
-
@addrs << s
|
152
|
-
end
|
153
|
-
|
154
106
|
# Sends a request to the server. Returns the request with a new tag
|
155
107
|
# assigned. If `onre` is supplied, it will be invoked when a new connection
|
156
108
|
# is established
|
@@ -159,20 +111,6 @@ module Fraggle
|
|
159
111
|
|
160
112
|
wr.valid do |e|
|
161
113
|
log.debug("response: #{e.inspect} for #{req.inspect}")
|
162
|
-
|
163
|
-
if req.offset
|
164
|
-
req.offset += 1
|
165
|
-
end
|
166
|
-
|
167
|
-
if req.limit
|
168
|
-
req.limit -= 1
|
169
|
-
end
|
170
|
-
|
171
|
-
if (req.rev || 0) < (e.rev || 0)
|
172
|
-
log.debug("updating rev: to #{e.rev} - #{req.inspect}")
|
173
|
-
req.rev = e.rev
|
174
|
-
end
|
175
|
-
|
176
114
|
req.emit(:valid, e)
|
177
115
|
end
|
178
116
|
|
@@ -195,9 +133,9 @@ module Fraggle
|
|
195
133
|
else
|
196
134
|
req.emit(:error, e)
|
197
135
|
end
|
198
|
-
when e.
|
136
|
+
when e.readonly?
|
199
137
|
|
200
|
-
log.error("
|
138
|
+
log.error("readonly: #{req.inspect}")
|
201
139
|
|
202
140
|
# Closing the connection triggers a reconnect above.
|
203
141
|
cn.close_connection
|
data/lib/fraggle/connection.rb
CHANGED
@@ -55,25 +55,16 @@ module Fraggle
|
|
55
55
|
return
|
56
56
|
end
|
57
57
|
|
58
|
-
req = @cb
|
58
|
+
req = @cb.delete(res.tag)
|
59
59
|
|
60
60
|
if ! req
|
61
61
|
return
|
62
62
|
end
|
63
63
|
|
64
|
-
if
|
65
|
-
@cb.delete(req.tag)
|
66
|
-
req.emit(:error, res)
|
67
|
-
return
|
68
|
-
end
|
69
|
-
|
70
|
-
if res.valid?
|
64
|
+
if res.ok?
|
71
65
|
req.emit(:valid, res)
|
72
|
-
|
73
|
-
|
74
|
-
if res.done?
|
75
|
-
@cb.delete(req.tag)
|
76
|
-
req.emit(:done)
|
66
|
+
else
|
67
|
+
req.emit(:error, res)
|
77
68
|
end
|
78
69
|
end
|
79
70
|
|
@@ -106,22 +97,6 @@ module Fraggle
|
|
106
97
|
req
|
107
98
|
end
|
108
99
|
|
109
|
-
def post_init
|
110
|
-
last = 0
|
111
|
-
rev = Request.new :verb => Request::Verb::REV
|
112
|
-
|
113
|
-
rev.valid do |e|
|
114
|
-
if e.rev <= last
|
115
|
-
close_connection
|
116
|
-
else
|
117
|
-
timer(5) { send_request(rev.dup) }
|
118
|
-
last = e.rev
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
send_request(rev.dup)
|
123
|
-
end
|
124
|
-
|
125
100
|
def unbind
|
126
101
|
@err = true
|
127
102
|
@cb.values.each do |req|
|
data/lib/fraggle/msg.pb.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
## Generated from msg.proto for
|
1
|
+
## Generated from msg.proto for server
|
2
2
|
require "beefcake"
|
3
3
|
|
4
4
|
module Fraggle
|
@@ -7,27 +7,23 @@ module Fraggle
|
|
7
7
|
include Beefcake::Message
|
8
8
|
|
9
9
|
module Verb
|
10
|
-
CHECKIN = 0
|
11
10
|
GET = 1
|
12
11
|
SET = 2
|
13
12
|
DEL = 3
|
14
|
-
ESET = 4
|
15
13
|
REV = 5
|
14
|
+
WAIT = 6
|
16
15
|
NOP = 7
|
17
|
-
WATCH = 8
|
18
16
|
WALK = 9
|
19
|
-
CANCEL = 10
|
20
17
|
GETDIR = 14
|
21
18
|
STAT = 16
|
22
19
|
end
|
23
20
|
|
24
|
-
|
25
|
-
|
21
|
+
optional :tag, :int32, 1
|
22
|
+
optional :verb, Request::Verb, 2
|
26
23
|
optional :path, :string, 4
|
27
24
|
optional :value, :bytes, 5
|
28
25
|
optional :other_tag, :int32, 6
|
29
26
|
optional :offset, :int32, 7
|
30
|
-
optional :limit, :int32, 8
|
31
27
|
optional :rev, :int64, 9
|
32
28
|
|
33
29
|
end
|
@@ -39,18 +35,19 @@ module Fraggle
|
|
39
35
|
OTHER = 127
|
40
36
|
TAG_IN_USE = 1
|
41
37
|
UNKNOWN_VERB = 2
|
42
|
-
|
38
|
+
READONLY = 3
|
43
39
|
TOO_LATE = 4
|
44
40
|
REV_MISMATCH = 5
|
45
41
|
BAD_PATH = 6
|
46
42
|
MISSING_ARG = 7
|
43
|
+
RANGE = 8
|
47
44
|
NOTDIR = 20
|
48
45
|
ISDIR = 21
|
49
46
|
NOENT = 22
|
50
47
|
end
|
51
48
|
|
52
|
-
|
53
|
-
|
49
|
+
optional :tag, :int32, 1
|
50
|
+
optional :flags, :int32, 2
|
54
51
|
optional :rev, :int64, 3
|
55
52
|
optional :path, :string, 5
|
56
53
|
optional :value, :bytes, 6
|
data/lib/fraggle/request.rb
CHANGED
data/lib/fraggle/response.rb
CHANGED
@@ -3,23 +3,11 @@ require 'fraggle/msg.pb'
|
|
3
3
|
module Fraggle
|
4
4
|
class Response
|
5
5
|
|
6
|
-
VALID = 1
|
7
|
-
DONE = 2
|
8
6
|
SET = 4
|
9
7
|
DEL = 8
|
10
8
|
|
11
9
|
attr_accessor :disconnected
|
12
10
|
|
13
|
-
def valid?
|
14
|
-
return false if !flags
|
15
|
-
(flags & VALID) > 0
|
16
|
-
end
|
17
|
-
|
18
|
-
def done?
|
19
|
-
return false if !flags
|
20
|
-
(flags & DONE) > 0
|
21
|
-
end
|
22
|
-
|
23
11
|
def set?
|
24
12
|
return false if !flags
|
25
13
|
(flags & SET) > 0
|
@@ -38,8 +26,8 @@ module Fraggle
|
|
38
26
|
err_code.nil?
|
39
27
|
end
|
40
28
|
|
41
|
-
def
|
42
|
-
err_code == Err::
|
29
|
+
def readonly?
|
30
|
+
err_code == Err::READONLY
|
43
31
|
end
|
44
32
|
|
45
33
|
def disconnected?
|
data/lib/fraggle/version.rb
CHANGED
data/test/fraggle_client_test.rb
CHANGED
@@ -23,44 +23,13 @@ class FraggleClientTest < Test::Unit::TestCase
|
|
23
23
|
@c.__send__(:initialize, cn, @addrs)
|
24
24
|
end
|
25
25
|
|
26
|
-
def test_send_valid_done
|
27
|
-
req, log = request(V::NOP)
|
28
|
-
req = c.send(req)
|
29
|
-
|
30
|
-
res = Fraggle::Response.new :tag => req.tag, :value => "ing", :flags => F::VALID|F::DONE
|
31
|
-
c.cn.receive_response(res)
|
32
|
-
|
33
|
-
assert_equal [res], log.valid
|
34
|
-
assert_equal [req], log.done
|
35
|
-
assert_equal [], log.error
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_send_valid_called_before_done
|
39
|
-
req, _ = request(V::NOP)
|
40
|
-
req = c.send(req)
|
41
|
-
|
42
|
-
log = []
|
43
|
-
req.valid do
|
44
|
-
log << :valid
|
45
|
-
end
|
46
|
-
req.done do
|
47
|
-
log << :done
|
48
|
-
end
|
49
|
-
|
50
|
-
res = Fraggle::Response.new :tag => req.tag, :value => "ing", :flags => F::VALID|F::DONE
|
51
|
-
c.cn.receive_response(res)
|
52
|
-
|
53
|
-
assert_equal [:valid, :done], log
|
54
|
-
end
|
55
|
-
|
56
26
|
def test_send_error
|
57
27
|
req, log = request(V::NOP)
|
58
28
|
req = c.send(req)
|
59
29
|
|
60
|
-
res = Fraggle::Response.new :tag => req.tag, :err_code => E::OTHER
|
30
|
+
res = Fraggle::Response.new :tag => req.tag, :err_code => E::OTHER
|
61
31
|
c.cn.receive_response(res)
|
62
32
|
|
63
|
-
assert_equal [], log.valid
|
64
33
|
assert_equal [], log.done
|
65
34
|
assert_equal [res], log.error
|
66
35
|
end
|
@@ -155,66 +124,7 @@ class FraggleClientTest < Test::Unit::TestCase
|
|
155
124
|
assert_equal [Fraggle::Connection::Disconnected], nlog.error
|
156
125
|
end
|
157
126
|
|
158
|
-
def
|
159
|
-
req, log = request(V::WALK, :path => "/foo/*", :offset => 3)
|
160
|
-
req = c.resend(req)
|
161
|
-
|
162
|
-
res = Fraggle::Response.new :tag => req.tag, :flags => F::VALID
|
163
|
-
c.cn.receive_response(res)
|
164
|
-
|
165
|
-
c.cn.close_connection
|
166
|
-
|
167
|
-
exp, _ = request(V::WALK, :tag => req.tag, :path => "/foo/*", :offset => 4)
|
168
|
-
assert_equal [exp], c.cn.sent
|
169
|
-
end
|
170
|
-
|
171
|
-
def test_manage_limit
|
172
|
-
req, log = request(V::WALK, :path => "/foo/*", :limit => 4)
|
173
|
-
req = c.resend(req)
|
174
|
-
|
175
|
-
res = Fraggle::Response.new :tag => req.tag, :flags => F::VALID
|
176
|
-
c.cn.receive_response(res)
|
177
|
-
|
178
|
-
c.cn.close_connection
|
179
|
-
|
180
|
-
exp, _ = request(V::WALK, :tag => req.tag, :path => "/foo/*", :limit => 3)
|
181
|
-
assert_equal [exp], c.cn.sent
|
182
|
-
end
|
183
|
-
|
184
|
-
def test_manage_rev
|
185
|
-
req, log = request(V::WALK, :path => "/foo/*", :rev => 4)
|
186
|
-
req = c.resend(req)
|
187
|
-
|
188
|
-
# nil rev
|
189
|
-
res = Fraggle::Response.new :tag => req.tag, :flags => F::VALID
|
190
|
-
c.cn.receive_response(res)
|
191
|
-
assert_equal 4, req.rev
|
192
|
-
|
193
|
-
# equal to rev
|
194
|
-
res = Fraggle::Response.new :tag => req.tag, :rev => 4, :flags => F::VALID
|
195
|
-
c.cn.receive_response(res)
|
196
|
-
assert_equal 4, req.rev
|
197
|
-
|
198
|
-
# less than rev
|
199
|
-
res = Fraggle::Response.new :tag => req.tag, :rev => 3, :flags => F::VALID
|
200
|
-
c.cn.receive_response(res)
|
201
|
-
assert_equal 4, req.rev
|
202
|
-
|
203
|
-
# greater than rev
|
204
|
-
# NOTE: This will never happen in life on a WALK, this is purely a
|
205
|
-
# test.
|
206
|
-
res = Fraggle::Response.new :tag => req.tag, :rev => 5, :flags => F::VALID
|
207
|
-
c.cn.receive_response(res)
|
208
|
-
assert_equal 5, req.rev
|
209
|
-
|
210
|
-
# force retry
|
211
|
-
c.cn.close_connection
|
212
|
-
|
213
|
-
exp, _ = request(V::WALK, :tag => req.tag, :rev => 5, :path => "/foo/*")
|
214
|
-
assert_equal [exp], c.cn.sent
|
215
|
-
end
|
216
|
-
|
217
|
-
def test_redirect_simple
|
127
|
+
def test_readonly_simple
|
218
128
|
a, al = request(V::SET, :rev => 0, :path => "/foo")
|
219
129
|
a = c.send(a)
|
220
130
|
|
@@ -223,9 +133,8 @@ class FraggleClientTest < Test::Unit::TestCase
|
|
223
133
|
|
224
134
|
res = Fraggle::Response.new(
|
225
135
|
:tag => a.tag,
|
226
|
-
:err_code => E::
|
227
|
-
:err_detail => "9.9.9.9:9"
|
228
|
-
:flags => F::VALID|F::DONE
|
136
|
+
:err_code => E::READONLY,
|
137
|
+
:err_detail => "9.9.9.9:9"
|
229
138
|
)
|
230
139
|
|
231
140
|
c.cn.receive_response(res)
|
@@ -291,11 +200,10 @@ class FraggleClientTest < Test::Unit::TestCase
|
|
291
200
|
:verb => V::GETDIR,
|
292
201
|
:rev => 0,
|
293
202
|
:path => "/foo",
|
294
|
-
:offset => 0
|
295
|
-
:limit => 5
|
203
|
+
:offset => 0
|
296
204
|
}
|
297
205
|
|
298
|
-
assert_verb exp, :getdir, "/foo", 0, 0
|
206
|
+
assert_verb exp, :getdir, "/foo", 0, 0
|
299
207
|
end
|
300
208
|
|
301
209
|
def test_rev
|
@@ -317,18 +225,6 @@ class FraggleClientTest < Test::Unit::TestCase
|
|
317
225
|
end
|
318
226
|
|
319
227
|
def test_walk
|
320
|
-
exp = {
|
321
|
-
:verb => V::WALK,
|
322
|
-
:rev => 0,
|
323
|
-
:path => "/foo/*",
|
324
|
-
:offset => 0,
|
325
|
-
:limit => 5
|
326
|
-
}
|
327
|
-
|
328
|
-
assert_verb exp, :walk, "/foo/*", 0, 0, 5
|
329
|
-
end
|
330
|
-
|
331
|
-
def test_walk_no_offset_limit_given
|
332
228
|
exp = {
|
333
229
|
:verb => V::WALK,
|
334
230
|
:rev => 0,
|
@@ -336,17 +232,17 @@ class FraggleClientTest < Test::Unit::TestCase
|
|
336
232
|
:offset => 0
|
337
233
|
}
|
338
234
|
|
339
|
-
assert_verb exp, :walk, "/foo/*", 0
|
235
|
+
assert_verb exp, :walk, "/foo/*", 0, 0
|
340
236
|
end
|
341
237
|
|
342
|
-
def
|
238
|
+
def test_wait
|
343
239
|
exp = {
|
344
|
-
:verb => V::
|
240
|
+
:verb => V::WAIT,
|
345
241
|
:rev => 0,
|
346
242
|
:path => "/foo/*"
|
347
243
|
}
|
348
244
|
|
349
|
-
assert_verb exp, :
|
245
|
+
assert_verb exp, :wait, "/foo/*", 0
|
350
246
|
end
|
351
247
|
|
352
248
|
end
|
@@ -15,23 +15,23 @@ class FraggleProtocolTest < Test::Unit::TestCase
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def test_simple
|
18
|
-
req = Fraggle::Response.new :tag => 0, :verb => V::NOP
|
18
|
+
req = Fraggle::Response.new :tag => 0, :verb => V::NOP
|
19
19
|
cn.receive_data(encode(req))
|
20
20
|
|
21
21
|
assert_equal [req], cn.received
|
22
22
|
end
|
23
23
|
|
24
24
|
def test_multiple_single
|
25
|
-
a = Fraggle::Response.new :tag => 0, :verb => V::NOP
|
26
|
-
b = Fraggle::Response.new :tag => 1, :verb => V::NOP
|
25
|
+
a = Fraggle::Response.new :tag => 0, :verb => V::NOP
|
26
|
+
b = Fraggle::Response.new :tag => 1, :verb => V::NOP
|
27
27
|
cn.receive_data(encode(a) + encode(b))
|
28
28
|
|
29
29
|
assert_equal [a, b], cn.received
|
30
30
|
end
|
31
31
|
|
32
32
|
def test_multiple_double
|
33
|
-
a = Fraggle::Response.new :tag => 0, :verb => V::NOP
|
34
|
-
b = Fraggle::Response.new :tag => 1, :verb => V::NOP
|
33
|
+
a = Fraggle::Response.new :tag => 0, :verb => V::NOP
|
34
|
+
b = Fraggle::Response.new :tag => 1, :verb => V::NOP
|
35
35
|
cn.receive_data(encode(a))
|
36
36
|
cn.receive_data(encode(b))
|
37
37
|
|
@@ -39,7 +39,7 @@ class FraggleProtocolTest < Test::Unit::TestCase
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def test_small_chunks
|
42
|
-
req = Fraggle::Response.new :tag => 0, :verb => V::NOP
|
42
|
+
req = Fraggle::Response.new :tag => 0, :verb => V::NOP
|
43
43
|
|
44
44
|
bytes = encode(req) * 3
|
45
45
|
len = bytes.length
|
@@ -53,7 +53,7 @@ class FraggleProtocolTest < Test::Unit::TestCase
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def test_big_chunks
|
56
|
-
req = Fraggle::Response.new :tag => 0, :verb => V::NOP
|
56
|
+
req = Fraggle::Response.new :tag => 0, :verb => V::NOP
|
57
57
|
|
58
58
|
bytes = encode(req) * 3
|
59
59
|
len = bytes.length
|
@@ -26,42 +26,19 @@ class FraggleTransactionTest < Test::Unit::TestCase
|
|
26
26
|
req, log = nop
|
27
27
|
req = cn.send_request(req)
|
28
28
|
|
29
|
-
res = Fraggle::Response.new :tag => req.tag
|
29
|
+
res = Fraggle::Response.new :tag => req.tag
|
30
30
|
cn.receive_response(res)
|
31
31
|
|
32
32
|
assert_equal [res], log.valid
|
33
33
|
assert_equal [], log.done
|
34
34
|
end
|
35
35
|
|
36
|
-
def test_done
|
37
|
-
req, log = nop
|
38
|
-
req = cn.send_request(req)
|
39
|
-
|
40
|
-
res = Fraggle::Response.new :tag => req.tag, :flags => F::DONE
|
41
|
-
cn.receive_response(res)
|
42
|
-
|
43
|
-
assert_equal [], log.valid
|
44
|
-
assert_equal [req], log.done
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_valid_and_done
|
48
|
-
req, log = nop
|
49
|
-
req = cn.send_request(req)
|
50
|
-
|
51
|
-
res = Fraggle::Response.new :tag => req.tag, :flags => F::VALID|F::DONE
|
52
|
-
cn.receive_response(res)
|
53
|
-
|
54
|
-
assert_equal [res], log.valid
|
55
|
-
assert_equal [req], log.done
|
56
|
-
end
|
57
|
-
|
58
36
|
def test_error
|
59
37
|
req, log = nop
|
60
38
|
req = cn.send_request(req)
|
61
39
|
|
62
40
|
res = Fraggle::Response.new(
|
63
41
|
:tag => req.tag,
|
64
|
-
:flags => F::VALID|F::DONE,
|
65
42
|
:err_code => E::OTHER
|
66
43
|
)
|
67
44
|
|
@@ -75,7 +52,6 @@ class FraggleTransactionTest < Test::Unit::TestCase
|
|
75
52
|
def test_invalid_tag
|
76
53
|
res = Fraggle::Response.new(
|
77
54
|
:tag => 0,
|
78
|
-
:flags => F::VALID|F::DONE,
|
79
55
|
:err_code => E::OTHER
|
80
56
|
)
|
81
57
|
|
@@ -84,11 +60,11 @@ class FraggleTransactionTest < Test::Unit::TestCase
|
|
84
60
|
end
|
85
61
|
end
|
86
62
|
|
87
|
-
def
|
63
|
+
def test_deletes_callback
|
88
64
|
req, log = nop
|
89
65
|
req = cn.send_request(req)
|
90
66
|
|
91
|
-
res = Fraggle::Response.new(:tag => req.tag
|
67
|
+
res = Fraggle::Response.new(:tag => req.tag)
|
92
68
|
cn.receive_response(res)
|
93
69
|
|
94
70
|
# This should be ignored
|
@@ -97,13 +73,12 @@ class FraggleTransactionTest < Test::Unit::TestCase
|
|
97
73
|
assert_equal [res], log.valid
|
98
74
|
end
|
99
75
|
|
100
|
-
def
|
76
|
+
def test_error_deletes_callback
|
101
77
|
req, log = nop
|
102
78
|
req = cn.send_request(req)
|
103
79
|
|
104
80
|
res = Fraggle::Response.new(
|
105
81
|
:tag => req.tag,
|
106
|
-
:flags => F::VALID|F::DONE,
|
107
82
|
:err_code => E::OTHER
|
108
83
|
)
|
109
84
|
|
@@ -124,36 +99,6 @@ class FraggleTransactionTest < Test::Unit::TestCase
|
|
124
99
|
end
|
125
100
|
end
|
126
101
|
|
127
|
-
def test_cancel
|
128
|
-
req, _ = nop
|
129
|
-
req = cn.send_request(req)
|
130
|
-
can = req.cancel
|
131
|
-
|
132
|
-
canx = Fraggle::Response.new(:tag => can.tag, :flags => F::VALID|F::DONE)
|
133
|
-
cn.receive_response(canx)
|
134
|
-
end
|
135
|
-
|
136
|
-
def test_cannot_cancel_more_than_once
|
137
|
-
req, _ = nop
|
138
|
-
req = cn.send_request(req)
|
139
|
-
req.cancel
|
140
|
-
|
141
|
-
assert_raises Fraggle::Connection::SendError do
|
142
|
-
req.cancel
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def test_cancel_emits_done
|
147
|
-
req, log = nop
|
148
|
-
req = cn.send_request(req)
|
149
|
-
can = req.cancel
|
150
|
-
|
151
|
-
canx = Fraggle::Response.new(:tag => can.tag, :flags => F::VALID|F::DONE)
|
152
|
-
cn.receive_response(canx)
|
153
|
-
|
154
|
-
assert_equal [req], log.done
|
155
|
-
end
|
156
|
-
|
157
102
|
def test_disconnected
|
158
103
|
a, al = nop
|
159
104
|
a = cn.send_request(a)
|
@@ -180,7 +125,7 @@ class FraggleTransactionTest < Test::Unit::TestCase
|
|
180
125
|
|
181
126
|
cn.unbind
|
182
127
|
|
183
|
-
res = Fraggle::Response.new(:tag => a.tag
|
128
|
+
res = Fraggle::Response.new(:tag => a.tag)
|
184
129
|
cn.receive_response(res)
|
185
130
|
|
186
131
|
assert_equal [], al.valid
|
@@ -195,39 +140,4 @@ class FraggleTransactionTest < Test::Unit::TestCase
|
|
195
140
|
|
196
141
|
assert_equal nil, log.error.first
|
197
142
|
end
|
198
|
-
|
199
|
-
def test_liveness
|
200
|
-
live = cn.post_init
|
201
|
-
|
202
|
-
def cn.timer(_, &blk)
|
203
|
-
blk.call
|
204
|
-
end
|
205
|
-
|
206
|
-
res = Fraggle::Response.new(:tag => live.tag, :rev => 1, :flags => F::VALID|F::DONE)
|
207
|
-
cn.receive_response(res)
|
208
|
-
assert ! cn.err?
|
209
|
-
|
210
|
-
# Connections reuse tags and we're only responding to one request in this
|
211
|
-
# test, so we know the next rev will use the previous tag
|
212
|
-
res = Fraggle::Response.new(:tag => live.tag, :rev => 2, :flags => F::VALID|F::DONE)
|
213
|
-
cn.receive_response(res)
|
214
|
-
assert ! cn.err?
|
215
|
-
end
|
216
|
-
|
217
|
-
def test_not_alive
|
218
|
-
live = cn.post_init
|
219
|
-
|
220
|
-
def cn.timer(_, &blk)
|
221
|
-
blk.call
|
222
|
-
end
|
223
|
-
|
224
|
-
res = Fraggle::Response.new(:tag => live.tag, :rev => 1, :flags => F::VALID|F::DONE)
|
225
|
-
cn.receive_response(res)
|
226
|
-
assert ! cn.err?
|
227
|
-
|
228
|
-
res.tag += 1
|
229
|
-
cn.receive_response(res)
|
230
|
-
assert cn.err?
|
231
|
-
end
|
232
|
-
|
233
143
|
end
|
data/test/helper.rb
CHANGED
@@ -71,14 +71,7 @@ class Test::Unit::TestCase
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def reply(tag, attrs={})
|
74
|
-
attrs[:flags] ||= 0
|
75
|
-
attrs[:flags] |= F::VALID
|
76
74
|
Fraggle::Response.new(attrs.merge(:tag => tag))
|
77
75
|
end
|
78
76
|
|
79
|
-
def reply!(tag, attrs={})
|
80
|
-
attrs[:flags] = F::DONE
|
81
|
-
reply(tag, attrs)
|
82
|
-
end
|
83
|
-
|
84
77
|
end
|
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
|
+
- 2
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version:
|
9
|
+
- 0
|
10
|
+
version: 2.0.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Blake Mizerany
|
@@ -76,15 +76,13 @@ files:
|
|
76
76
|
- LICENSE
|
77
77
|
- README.md
|
78
78
|
- Rakefile
|
79
|
-
- example/addrs.rb
|
80
79
|
- example/getdir.rb
|
81
|
-
- example/
|
80
|
+
- example/readonly.rb
|
82
81
|
- example/resend.rb
|
83
82
|
- example/rev.rb
|
84
83
|
- example/set.rb
|
85
84
|
- example/stat.rb
|
86
85
|
- example/walk.rb
|
87
|
-
- example/watch.rb
|
88
86
|
- fraggle.gemspec
|
89
87
|
- lib/fraggle.rb
|
90
88
|
- lib/fraggle/client.rb
|
data/example/addrs.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'eventmachine'
|
3
|
-
require 'fraggle'
|
4
|
-
# This is for testing Fraggle's monitoring of addresses in a cluster.
|
5
|
-
|
6
|
-
EM.run do
|
7
|
-
c = Fraggle.connect "doozer:?ca=127.0.0.1:8041"
|
8
|
-
c.log.level = Logger::DEBUG
|
9
|
-
|
10
|
-
EM.add_periodic_timer(1) do
|
11
|
-
p [:addrs, c.addr, c.addrs]
|
12
|
-
end
|
13
|
-
end
|
data/example/watch.rb
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'eventmachine'
|
3
|
-
require 'fraggle'
|
4
|
-
|
5
|
-
EM.run do
|
6
|
-
|
7
|
-
c = Fraggle.connect
|
8
|
-
c.log.level = Logger::DEBUG
|
9
|
-
|
10
|
-
c.watch("/example/*") do |e|
|
11
|
-
p e
|
12
|
-
end.error do |e|
|
13
|
-
p [:err, e]
|
14
|
-
end
|
15
|
-
|
16
|
-
EM.add_periodic_timer(0.5) do
|
17
|
-
c.set("/example/#{rand(10)}", "test", -1)
|
18
|
-
end
|
19
|
-
|
20
|
-
end
|