fraggle 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Fraggle (v2.0.0 is compatible with Doozer 0.6)
1
+ # Fraggle (v3.0.0 is compatible with Doozer 0.6)
2
2
 
3
3
  Fraggle currently is only a raw interface to Doozer 0.6.
4
4
  Sugar for `WALK`, `GETDIR`, etc are to come in v3.0.0.
@@ -7,7 +7,7 @@ Sugar for `WALK`, `GETDIR`, etc are to come in v3.0.0.
7
7
 
8
8
  ## Install
9
9
 
10
- $ gem install fraggle --pre
10
+ $ gem install fraggle
11
11
 
12
12
  ## Use
13
13
 
@@ -16,65 +16,51 @@ Sugar for `WALK`, `GETDIR`, etc are to come in v3.0.0.
16
16
  require 'fraggle'
17
17
 
18
18
  EM.start do
19
- # Fraggle keeps track of this addr plus all others it finds once
20
- # connected. In the event of a lost connection, fraggle will attempt
19
+ # In the event of a lost connection, fraggle will attempt
21
20
  # other doozers until one accepts or it runs out of options; A NoAddrs
22
21
  # exception will be raised if that later happens.
23
22
  c = Fraggle.connect "doozerd://127.0.0.1:8046"
24
23
 
25
24
  req = c.get("/foo") do |e|
26
- e.value # => "bar"
27
- e.rev # => 123
28
- end
29
-
30
- req.error do |e|
31
- e.err_code # => nil
32
- e.err_detail # => nil
25
+ if e.ok?
26
+ e.value # => nil
27
+ e.rev # => 0
28
+ e.missing? # => true
29
+ else
30
+ e.err_code # => Fraggle::<CONST>
31
+ e.err_detail # => "bad path" or something
32
+ end
33
33
  end
34
34
 
35
- watch = c.watch("/foo") do |e|
36
- # The event has:
37
- # ------------------------
38
- e.err_code # => nil
39
- e.err_detail # => nil
40
- e.path # => "/foo"
41
- e.value # => "bar"
42
- e.rev # => 123
43
- e.set? # => true
44
- e.del? # => false
45
-
46
- do_something_with(e)
47
-
48
- # Phoney check for example
49
- if can_stop_watching?(path)
50
- watch.cancel
35
+ c.rev do |v|
36
+ ## Obtain the current revision the store is at and watch from then on for
37
+ ## any SET or DEL to /foo.
38
+ c.wait("/foo", v.rev) do |e|
39
+ # The event has:
40
+ # ------------------------
41
+ e.err_code # => nil
42
+ e.err_detail # => nil
43
+ e.path # => "/foo"
44
+ e.value # => "zomg!"
45
+ e.rev # => 123
46
+ e.set? # => true
47
+ e.del? # => false
51
48
  end
52
49
  end
53
50
 
54
51
  ## Setting a key (this will trigger the watch above)
55
52
  req = c.set("/foo", "zomg!", 0) do |e|
56
53
  # Success!
57
- end.error do |e|
58
- if e.mismatch?
59
- # There was a rev mismatch, handle this.
54
+ case e.err_code
55
+ when Fraggle::REV_MISMATCH
56
+ # We didn't win
57
+ when nil
58
+ # Success!
60
59
  else
61
- raise e.err_detail
60
+ fail "something bad happened"
62
61
  end
63
62
  end
64
63
 
65
- # Knowning when a command is done is useful in some cases.
66
- # Use the `done` callback for those situations.
67
- ents = []
68
- c.getdir("/test") do |e|
69
- ents << e
70
- end.done do
71
- p ents
72
- end
73
-
74
- c.get("/nothere") do |e|
75
- e.missing? # => true
76
- end
77
-
78
64
  end
79
65
 
80
66
  ## Consistency
data/bench/gets.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'eventmachine'
3
+ require 'fraggle'
4
+
5
+ reqs = 0
6
+
7
+ def rget(c, path, rev, &blk)
8
+ c.get(path, rev) do |e|
9
+ blk.call
10
+ rget(c, path, rev, &blk)
11
+ end
12
+ end
13
+
14
+ EM.run do
15
+ c = Fraggle.connect
16
+
17
+ EM.add_timer(1) do
18
+ # The primer is done. Reset `reqs` and do it for real.
19
+ reqs = 0
20
+ EM.add_timer(1) do
21
+ EM.stop_event_loop
22
+ end
23
+ end
24
+
25
+ c.rev do |v|
26
+ rget(c, "/ctl/cal/0", v.rev) do
27
+ reqs += 1
28
+ end
29
+ end
30
+ end
31
+
32
+ puts "Result (GET): #{reqs}/sec"
@@ -28,9 +28,8 @@ module Fraggle
28
28
  req.rev = rev
29
29
  req.path = path
30
30
  req.value = value
31
- req.valid(&blk)
32
31
 
33
- idemp(req)
32
+ idemp(req, &blk)
34
33
  end
35
34
 
36
35
  def get(path, rev=nil, &blk)
@@ -38,9 +37,8 @@ module Fraggle
38
37
  req.verb = GET
39
38
  req.rev = rev
40
39
  req.path = path
41
- req.valid(&blk)
42
40
 
43
- resend(req)
41
+ resend(req, &blk)
44
42
  end
45
43
 
46
44
  def del(path, rev, &blk)
@@ -48,9 +46,8 @@ module Fraggle
48
46
  req.verb = DEL
49
47
  req.rev = rev
50
48
  req.path = path
51
- req.valid(&blk)
52
49
 
53
- idemp(req)
50
+ idemp(req, &blk)
54
51
  end
55
52
 
56
53
  def getdir(path, rev=nil, offset=nil, &blk)
@@ -59,9 +56,8 @@ module Fraggle
59
56
  req.rev = rev
60
57
  req.path = path
61
58
  req.offset = offset
62
- req.valid(&blk)
63
59
 
64
- resend(req)
60
+ resend(req, &blk)
65
61
  end
66
62
 
67
63
  def walk(path, rev=nil, offset=nil, &blk)
@@ -70,9 +66,8 @@ module Fraggle
70
66
  req.rev = rev
71
67
  req.path = path
72
68
  req.offset = offset
73
- req.valid(&blk)
74
69
 
75
- resend(req)
70
+ resend(req, &blk)
76
71
  end
77
72
 
78
73
  def wait(path, rev=nil, &blk)
@@ -80,17 +75,15 @@ module Fraggle
80
75
  req.verb = WAIT
81
76
  req.rev = rev
82
77
  req.path = path
83
- req.valid(&blk)
84
78
 
85
- resend(req)
79
+ resend(req, &blk)
86
80
  end
87
81
 
88
82
  def rev(&blk)
89
83
  req = Request.new
90
84
  req.verb = REV
91
- req.valid(&blk)
92
85
 
93
- resend(req)
86
+ resend(req, &blk)
94
87
  end
95
88
 
96
89
  def stat(path, rev=nil, &blk)
@@ -98,27 +91,16 @@ module Fraggle
98
91
  req.rev = rev
99
92
  req.verb = STAT
100
93
  req.path = path
101
- req.valid(&blk)
102
94
 
103
- resend(req)
95
+ resend(req, &blk)
104
96
  end
105
97
 
106
98
  # Sends a request to the server. Returns the request with a new tag
107
- # assigned. If `onre` is supplied, it will be invoked when a new connection
108
- # is established
109
- def send(req, &onre)
110
- wr = Request.new(req.to_hash)
111
-
112
- wr.valid do |e|
99
+ # assigned.
100
+ def send(req, &blk)
101
+ cb = Proc.new do |e|
113
102
  log.debug("response: #{e.inspect} for #{req.inspect}")
114
- req.emit(:valid, e)
115
- end
116
103
 
117
- wr.done do
118
- req.emit(:done)
119
- end
120
-
121
- wr.error do |e|
122
104
  case true
123
105
  when e.disconnected?
124
106
  # If we haven't already reconnected, do so.
@@ -126,63 +108,46 @@ module Fraggle
126
108
  log.error("conn err: #{req.inspect}")
127
109
  reconnect!
128
110
  end
129
-
130
- if onre
131
- # Someone else will handle this
132
- onre.call
133
- else
134
- req.emit(:error, e)
135
- end
136
- when e.readonly?
137
-
138
- log.error("readonly: #{req.inspect}")
139
-
140
- # Closing the connection triggers a reconnect above.
141
- cn.close_connection
142
-
143
- if onre
144
- # Someone else will handle this
145
- onre.call
146
- else
147
- req.emit(:error, Connection::Disconnected)
148
- end
149
- else
150
- log.error("error: #{e.inspect} for #{req.inspect}")
151
- req.emit(:error, e)
152
111
  end
153
112
 
113
+ blk.call(e)
154
114
  end
155
115
 
156
- wr = cn.send_request(wr)
157
- req.tag = wr.tag
158
116
  log.debug("sending: #{req.inspect}")
159
-
160
- req
117
+ cn.send_request(req, cb)
161
118
  end
162
119
 
163
- def resend(req)
164
- send(req) do
165
- req.tag = nil
166
- log.debug("resending: #{req.inspect}")
167
- resend(req)
120
+ def resend(req, &blk)
121
+ cb = Proc.new do |e|
122
+ if e.disconnected?
123
+ req.tag = nil
124
+ log.debug("resending: #{req.inspect}")
125
+ resend(req, &blk)
126
+ else
127
+ blk.call(e)
128
+ end
168
129
  end
130
+
131
+ send(req, &cb)
169
132
  end
170
133
 
171
- def idemp(req)
172
- send(req) do
173
- if req.rev > 0
134
+ def idemp(req, &blk)
135
+ cb = Proc.new do |e|
136
+ if e.disconnected? && req.rev > 0
174
137
  # If we're trying to update a value that isn't missing or that we're
175
138
  # not trying to clobber, it's safe to retry. We can't idempotently
176
139
  # update missing values because there may be a race with another
177
140
  # client that sets and/or deletes the key during the time between your
178
141
  # read and write.
179
142
  req.tag = nil
180
- idemp(req)
181
- else
182
- # We can't safely retry the write. Inform the user.
183
- req.emit(:error, Connection::Disconnected)
143
+ idemp(req, &blk)
144
+ next
184
145
  end
146
+
147
+ blk.call(e)
185
148
  end
149
+
150
+ send(req, &cb)
186
151
  end
187
152
 
188
153
  def reconnect!
@@ -1,4 +1,3 @@
1
- require 'fraggle/request'
2
1
  require 'fraggle/response'
3
2
 
4
3
  module Fraggle
@@ -23,15 +22,13 @@ module Fraggle
23
22
  end
24
23
 
25
24
 
26
- attr_reader :last_received, :addr
25
+ attr_reader :addr
27
26
 
28
27
  def initialize(addr)
29
28
  @addr, @cb = addr, {}
30
29
  end
31
30
 
32
31
  def receive_data(data)
33
- @last_received = Time.now
34
-
35
32
  (@buf ||= "") << data
36
33
 
37
34
  while @buf.length > 0
@@ -51,30 +48,19 @@ module Fraggle
51
48
 
52
49
  # The default receive_response
53
50
  def receive_response(res)
54
- if err?
55
- return
56
- end
57
-
58
- req = @cb.delete(res.tag)
59
-
60
- if ! req
61
- return
62
- end
63
-
64
- if res.ok?
65
- req.emit(:valid, res)
66
- else
67
- req.emit(:error, res)
68
- end
51
+ return if err?
52
+ req, blk = @cb.delete(res.tag)
53
+ return if ! blk
54
+ blk.call(res)
69
55
  end
70
56
 
71
- def send_request(req)
57
+ def send_request(req, blk)
72
58
  if req.tag
73
59
  raise SendError, "Already sent #{req.inspect}"
74
60
  end
75
61
 
76
62
  if err?
77
- next_tick { req.emit(:error, Disconnected) }
63
+ next_tick { blk.call(Disconnected) }
78
64
  return req
79
65
  end
80
66
 
@@ -85,9 +71,8 @@ module Fraggle
85
71
  req.tag %= 2**31
86
72
  end
87
73
 
88
- req.cn = self
89
-
90
- @cb[req.tag] = req
74
+ # TODO: remove this!
75
+ @cb[req.tag] = [req, blk]
91
76
 
92
77
  data = req.encode
93
78
  head = [data.length].pack("N")
@@ -99,8 +84,8 @@ module Fraggle
99
84
 
100
85
  def unbind
101
86
  @err = true
102
- @cb.values.each do |req|
103
- req.emit(:error, Disconnected)
87
+ @cb.values.each do |_, blk|
88
+ blk.call(Disconnected)
104
89
  end
105
90
  end
106
91
 
@@ -26,10 +26,6 @@ module Fraggle
26
26
  err_code.nil?
27
27
  end
28
28
 
29
- def readonly?
30
- err_code == Err::READONLY
31
- end
32
-
33
29
  def disconnected?
34
30
  !!@disconnected
35
31
  end
@@ -1,3 +1,3 @@
1
1
  module Fraggle
2
- VERSION = "2.0.0"
2
+ VERSION = "3.0.0"
3
3
  end
@@ -1,9 +1,9 @@
1
- require File.dirname(__FILE__)+"/helper"
1
+ require File.expand_path(File.dirname(__FILE__)+"/helper")
2
2
  require 'fraggle/client'
3
3
 
4
4
  class FraggleClientTest < Test::Unit::TestCase
5
5
 
6
- attr_reader :c, :addrs, :blk, :called
6
+ attr_reader :c
7
7
 
8
8
  def setup
9
9
  addr = "127.0.0.1:0"
@@ -24,14 +24,14 @@ class FraggleClientTest < Test::Unit::TestCase
24
24
  end
25
25
 
26
26
  def test_send_error
27
- req, log = request(V::NOP)
28
- req = c.send(req)
27
+ req, log = request(V::REV)
29
28
 
30
- res = Fraggle::Response.new :tag => req.tag, :err_code => E::OTHER
29
+ c.send(req, &log)
30
+
31
+ res = reply(req.tag, :err_code => E::OTHER)
31
32
  c.cn.receive_response(res)
32
33
 
33
- assert_equal [], log.done
34
- assert_equal [res], log.error
34
+ assert_equal [res], log.valid
35
35
  end
36
36
 
37
37
  def test_reconnect_without_pending_requests
@@ -41,8 +41,8 @@ class FraggleClientTest < Test::Unit::TestCase
41
41
  c.cn.close_connection
42
42
 
43
43
  # Send a request to invoke reconnect
44
- req, log = request(V::NOP)
45
- req = c.send(req)
44
+ req, log = request(V::REV)
45
+ c.send(req, &log)
46
46
 
47
47
  # Fake reactor turn (only available in tests)
48
48
  c.cn.tick!
@@ -50,15 +50,15 @@ class FraggleClientTest < Test::Unit::TestCase
50
50
  assert exp.include?(c.cn.addr), "#{c.cn.addr.inspect} not in #{exp.inspect}"
51
51
 
52
52
  # If the client can handle an error, it should not mention it to the user.
53
- assert_equal [Fraggle::Connection::Disconnected], log.error
53
+ assert_equal [Fraggle::Connection::Disconnected], log.valid
54
54
  end
55
55
 
56
56
  def test_reconnect_with_pending_request
57
57
  exp = @addrs.dup
58
58
 
59
59
  # Send a request to invoke reconnect
60
- req, log = request(V::NOP)
61
- req = c.send(req)
60
+ req, log = request(V::REV)
61
+ c.send(req, &log)
62
62
 
63
63
  # Disconnect from 127.0.0.1:0
64
64
  c.cn.close_connection
@@ -68,18 +68,18 @@ class FraggleClientTest < Test::Unit::TestCase
68
68
 
69
69
  assert exp.include?(c.cn.addr), "#{c.cn.addr.inspect} not in #{exp.inspect}"
70
70
 
71
- assert_equal [Fraggle::Connection::Disconnected], log.error
71
+ assert_equal [Fraggle::Connection::Disconnected], log.valid
72
72
  end
73
73
 
74
74
  def test_reconnect_with_multiple_pending_requests
75
75
  exp = @addrs.dup
76
76
 
77
77
  # Send a request to invoke reconnect
78
- req, loga = request(V::NOP)
79
- req = c.send(req)
78
+ req, loga = request(V::REV)
79
+ c.send(req, &loga)
80
80
 
81
- req, logb = request(V::NOP)
82
- req = c.send(req)
81
+ req, logb = request(V::REV)
82
+ c.send(req, &logb)
83
83
 
84
84
  # Disconnect from 127.0.0.1:0
85
85
  c.cn.close_connection
@@ -93,13 +93,13 @@ class FraggleClientTest < Test::Unit::TestCase
93
93
  assert_equal exp.length - 1, c.addrs.length
94
94
 
95
95
  # If the client can handle an error, it should not mention it to the user.
96
- assert_equal [Fraggle::Connection::Disconnected], loga.error
97
- assert_equal [Fraggle::Connection::Disconnected], logb.error
96
+ assert_equal [Fraggle::Connection::Disconnected], loga.valid
97
+ assert_equal [Fraggle::Connection::Disconnected], logb.valid
98
98
  end
99
99
 
100
100
  def test_resend_pending_requests
101
101
  req, log = request(V::GET, :path => "/foo")
102
- req = c.resend(req)
102
+ c.resend(req, &log)
103
103
 
104
104
  c.cn.close_connection
105
105
 
@@ -108,42 +108,20 @@ class FraggleClientTest < Test::Unit::TestCase
108
108
 
109
109
  def test_idemp_pending_requests
110
110
  one, olog = request(V::SET, :rev => 1, :path => "/foo", :value => "bar")
111
- one = c.idemp(one)
111
+ c.idemp(one, &olog)
112
112
 
113
113
  zero, zlog = request(V::SET, :rev => 0, :path => "/foo", :value => "bar")
114
- zero = c.idemp(zero)
114
+ c.idemp(zero, &zlog)
115
115
 
116
116
  neg, nlog = request(V::SET, :rev => -1, :path => "/foo", :value => "bar")
117
- zero = c.idemp(neg)
117
+ c.idemp(neg, &nlog)
118
118
 
119
119
  c.cn.close_connection
120
120
 
121
121
  assert_equal [one], c.cn.sent
122
122
 
123
- assert_equal [Fraggle::Connection::Disconnected], zlog.error
124
- assert_equal [Fraggle::Connection::Disconnected], nlog.error
125
- end
126
-
127
- def test_readonly_simple
128
- a, al = request(V::SET, :rev => 0, :path => "/foo")
129
- a = c.send(a)
130
-
131
- b, bl = request(V::SET, :rev => 0, :path => "/foo")
132
- b = c.send(b)
133
-
134
- res = Fraggle::Response.new(
135
- :tag => a.tag,
136
- :err_code => E::READONLY,
137
- :err_detail => "9.9.9.9:9"
138
- )
139
-
140
- c.cn.receive_response(res)
141
-
142
- assert_equal "1.1.1.1:1", c.cn.addr
143
- assert_equal ["2.2.2.2:2", "3.3.3.3:3"], c.addrs
144
-
145
- assert_equal [Fraggle::Connection::Disconnected], al.error
146
- assert_equal [Fraggle::Connection::Disconnected], bl.error
123
+ assert_equal [Fraggle::Connection::Disconnected], zlog.valid
124
+ assert_equal [Fraggle::Connection::Disconnected], nlog.valid
147
125
  end
148
126
 
149
127
  ###
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__)+"/helper"
1
+ require File.expand_path(File.dirname(__FILE__)+"/helper")
2
2
  require 'fraggle/connection'
3
3
 
4
4
  class FraggleProtocolTest < Test::Unit::TestCase
@@ -80,7 +80,7 @@ class FraggleProtocolTest < Test::Unit::TestCase
80
80
  end
81
81
 
82
82
  nop = Fraggle::Request.new :verb => V::NOP
83
- cn.send_request(nop)
83
+ cn.send_request(nop, nil)
84
84
 
85
85
  assert_equal head+bytes, got
86
86
  end
@@ -1,9 +1,9 @@
1
- require File.dirname(__FILE__)+"/helper"
1
+ require File.expand_path(File.dirname(__FILE__)+"/helper")
2
2
  require 'fraggle/connection'
3
3
 
4
4
  class FraggleTransactionTest < Test::Unit::TestCase
5
5
 
6
- attr_reader :cn, :tmp, :valid, :done, :error
6
+ attr_reader :cn
7
7
 
8
8
  def nop(attrs={})
9
9
  request(V::NOP, attrs)
@@ -15,45 +15,37 @@ class FraggleTransactionTest < Test::Unit::TestCase
15
15
 
16
16
  def test_tagging
17
17
  req, _ = nop
18
- assert_equal 0, cn.send_request(req).tag
18
+ assert_equal 0, cn.send_request(req, _).tag
19
19
  req, _ = nop
20
- assert_equal 1, cn.send_request(req).tag
20
+ assert_equal 1, cn.send_request(req, _).tag
21
21
  req, _ = nop
22
- assert_equal 2, cn.send_request(req).tag
22
+ assert_equal 2, cn.send_request(req, _).tag
23
23
  end
24
24
 
25
25
  def test_valid
26
- req, log = nop
27
- req = cn.send_request(req)
26
+ req, log = request(V::REV)
28
27
 
29
- res = Fraggle::Response.new :tag => req.tag
28
+ cn.send_request(req, log)
29
+
30
+ res = reply(req.tag)
30
31
  cn.receive_response(res)
31
32
 
32
33
  assert_equal [res], log.valid
33
- assert_equal [], log.done
34
34
  end
35
35
 
36
36
  def test_error
37
- req, log = nop
38
- req = cn.send_request(req)
37
+ req, log = request(V::REV)
39
38
 
40
- res = Fraggle::Response.new(
41
- :tag => req.tag,
42
- :err_code => E::OTHER
43
- )
39
+ cn.send_request(req, log)
44
40
 
41
+ res = reply(req.tag, :err_code => E::OTHER)
45
42
  cn.receive_response(res)
46
43
 
47
- assert_equal [], log.valid
48
- assert_equal [], log.done
49
- assert_equal [res], log.error
44
+ assert_equal [res], log.valid
50
45
  end
51
46
 
52
47
  def test_invalid_tag
53
- res = Fraggle::Response.new(
54
- :tag => 0,
55
- :err_code => E::OTHER
56
- )
48
+ res = reply(0, :err_code => E::OTHER)
57
49
 
58
50
  assert_nothing_raised do
59
51
  cn.receive_response(res)
@@ -61,10 +53,11 @@ class FraggleTransactionTest < Test::Unit::TestCase
61
53
  end
62
54
 
63
55
  def test_deletes_callback
64
- req, log = nop
65
- req = cn.send_request(req)
56
+ req, log = request(V::REV)
57
+
58
+ cn.send_request(req, log)
66
59
 
67
- res = Fraggle::Response.new(:tag => req.tag)
60
+ res = reply(req.tag)
68
61
  cn.receive_response(res)
69
62
 
70
63
  # This should be ignored
@@ -74,70 +67,53 @@ class FraggleTransactionTest < Test::Unit::TestCase
74
67
  end
75
68
 
76
69
  def test_error_deletes_callback
77
- req, log = nop
78
- req = cn.send_request(req)
70
+ req, log = request(V::REV)
79
71
 
80
- res = Fraggle::Response.new(
81
- :tag => req.tag,
82
- :err_code => E::OTHER
83
- )
72
+ cn.send_request(req, log)
84
73
 
74
+ res = reply(req.tag, :err_code => E::OTHER)
85
75
  cn.receive_response(res)
86
76
 
87
77
  # This should be ignored
88
78
  cn.receive_response(res)
89
79
 
90
- assert_equal [res], log.error
80
+ assert_equal [res], log.valid
91
81
  end
92
82
 
93
83
  def test_cannot_reuse_sent_request
94
- req, _ = nop
95
- req = cn.send_request(req)
84
+ req, _ = request(V::REV)
85
+ cn.send_request(req, _)
96
86
 
97
87
  assert_raises Fraggle::Connection::SendError do
98
- cn.send_request(req)
88
+ cn.send_request(req, _)
99
89
  end
100
90
  end
101
91
 
102
- def test_disconnected
103
- a, al = nop
104
- a = cn.send_request(a)
105
- b, bl = nop
106
- b = cn.send_request(b)
107
- c, cl = nop
108
- c = cn.send_request(c)
92
+ def test_disconnect_with_pending_requests
93
+ a, al = request(V::REV)
94
+ a = cn.send_request(a, al)
95
+ b, bl = request(V::REV)
96
+ b = cn.send_request(b, bl)
97
+ c, cl = request(V::REV)
98
+ c = cn.send_request(c, cl)
109
99
 
110
100
  cn.unbind
111
101
 
112
- assert_equal 1, al.error.length
113
- assert_equal Fraggle::Connection::Disconnected, al.error.first
114
-
115
- assert_equal 1, bl.error.length
116
- assert_equal Fraggle::Connection::Disconnected, bl.error.first
117
-
118
- assert_equal 1, cl.error.length
119
- assert_equal Fraggle::Connection::Disconnected, cl.error.first
102
+ assert_equal [Fraggle::Connection::Disconnected], al.valid
103
+ assert_equal [Fraggle::Connection::Disconnected], bl.valid
104
+ assert_equal [Fraggle::Connection::Disconnected], cl.valid
120
105
  end
121
106
 
122
- def test_ignores_responses_in_err_state
123
- a, al = nop
124
- a = cn.send_request(a)
125
-
107
+ def test_send_when_disconnected
126
108
  cn.unbind
127
109
 
128
- res = Fraggle::Response.new(:tag => a.tag)
129
- cn.receive_response(res)
130
-
131
- assert_equal [], al.valid
132
- end
110
+ req, log = request(V::REV)
111
+ ret = cn.send_request(req, log)
133
112
 
134
- def test_send_request_in_error_state
135
- cn.err = true
113
+ assert_equal req, ret
136
114
 
137
- req, log = nop
138
- req = cn.send_request(req)
139
- assert_equal nil, req.tag
115
+ cn.tick!
140
116
 
141
- assert_equal nil, log.error.first
117
+ assert_equal [Fraggle::Connection::Disconnected], log.valid
142
118
  end
143
119
  end
data/test/helper.rb CHANGED
@@ -14,8 +14,8 @@ class TestConn
14
14
  @ticks = []
15
15
  end
16
16
 
17
- def send_request(req)
18
- @sent << super(req)
17
+ def send_request(req, blk)
18
+ @sent << super(req, blk)
19
19
  req
20
20
  end
21
21
 
@@ -50,23 +50,29 @@ class Test::Unit::TestCase
50
50
  F = Fraggle::Response
51
51
  E = Fraggle::Response::Err
52
52
 
53
- Log = Struct.new(:valid, :error, :done)
53
+ class Log
54
+ attr_reader :valid
55
+
56
+ def initialize
57
+ @valid = []
58
+ end
59
+
60
+ def call(e)
61
+ @valid << e
62
+ end
63
+
64
+ def to_proc
65
+ me = self
66
+ Proc.new {|e| me.call(e) }
67
+ end
68
+ end
54
69
 
55
70
  def request(verb, attrs={})
56
71
  logable(Fraggle::Request.new(attrs.merge(:verb => verb)))
57
72
  end
58
73
 
59
74
  def logable(req)
60
- log = Log.new([], [], [])
61
- req.valid do |e|
62
- log.valid << e
63
- end
64
- req.done do
65
- log.done << req
66
- end
67
- req.error do |e|
68
- log.error << e
69
- end
75
+ log = Log.new
70
76
  [req, log]
71
77
  end
72
78
 
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: 15
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
- - 2
7
+ - 3
8
8
  - 0
9
9
  - 0
10
- version: 2.0.0
10
+ version: 3.0.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-04-27 00:00:00 -07:00
18
+ date: 2011-04-29 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -76,19 +76,12 @@ files:
76
76
  - LICENSE
77
77
  - README.md
78
78
  - Rakefile
79
- - example/getdir.rb
80
- - example/readonly.rb
81
- - example/resend.rb
82
- - example/rev.rb
83
- - example/set.rb
84
- - example/stat.rb
85
- - example/walk.rb
79
+ - bench/gets.rb
86
80
  - fraggle.gemspec
87
81
  - lib/fraggle.rb
88
82
  - lib/fraggle/client.rb
89
83
  - lib/fraggle/connection.rb
90
84
  - lib/fraggle/msg.pb.rb
91
- - lib/fraggle/request.rb
92
85
  - lib/fraggle/response.rb
93
86
  - lib/fraggle/version.rb
94
87
  - test/fraggle_client_test.rb
data/example/getdir.rb DELETED
@@ -1,58 +0,0 @@
1
- require 'rubygems'
2
- require 'eventmachine'
3
- require 'fraggle'
4
-
5
- EM.run do
6
-
7
- ## NOTE: This will be easier the very near future.
8
-
9
- ## Collects names in a directory
10
-
11
- c = Fraggle.connect
12
- c.log.level = Logger::DEBUG
13
-
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|
39
- ents << e.path
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
56
- end
57
-
58
- end
data/example/readonly.rb DELETED
@@ -1,28 +0,0 @@
1
- require 'rubygems'
2
- require 'fraggle'
3
-
4
- # This example assumes you have a Doozer with CAL privledges listening on port
5
- # 8041 and a Doozer sink listening on 8042. This example will connect to the
6
- # sink and attempt a write operation that will be redirected by the sink.
7
- # Fraggle will pick the only remaining addr it has which is the CAL Doozer and
8
- # retry the write operation.
9
-
10
- EM.run do
11
- # Connect to a slave (be sure this is a slave)
12
- c = Fraggle.connect("doozer:?ca=127.0.0.1:8042&ca=127.0.0.1:8041")
13
- c.log.level = Logger::DEBUG
14
-
15
- a = c.set("/foo", "bar", -1) do |e|
16
- # This shouldn't happen
17
- p [:valid, a, e]
18
- end.error do |e|
19
- p [:err, a, e]
20
- end
21
-
22
- b = c.set("/foo", "bar", 1) do |e|
23
- p [:valid, b, e]
24
- end.error do |e|
25
- # This shouldn't happen
26
- p [:err, b, e]
27
- end
28
- end
data/example/resend.rb DELETED
@@ -1,26 +0,0 @@
1
- require 'rubygems'
2
- require 'fraggle'
3
-
4
- ###
5
- # To see this example in action, run 1 doozerd and attach 2
6
- # more to it before running.
7
- #
8
- # NOTE: If you have the doozerd source, you can run ./bin/test-cluster
9
- #
10
- EM.run do
11
- c = Fraggle.connect
12
- c.log.level = Logger::DEBUG
13
-
14
- puts "# To see this work, kill the doozer this is connected to"
15
- puts "# to see it resend the request to the next connection."
16
- puts
17
-
18
- # Wait for rev 100,000
19
- c.get("/foo", 100_000) do |e|
20
- p ["This should not be!", e]
21
- end.error do |e|
22
- p [:err, e]
23
- end.done do
24
- p [:done, "This should not be!"]
25
- end
26
- end
data/example/rev.rb DELETED
@@ -1,15 +0,0 @@
1
- require 'rubygems'
2
- require 'eventmachine'
3
- require 'fraggle'
4
-
5
- EM.run do
6
-
7
- c = Fraggle.connect
8
-
9
- EM.add_periodic_timer(1) do
10
- c.rev do |e|
11
- p [:rev, e.rev]
12
- end
13
- end
14
-
15
- end
data/example/set.rb DELETED
@@ -1,20 +0,0 @@
1
- require 'rubygems'
2
- require 'eventmachine'
3
- require 'fraggle'
4
-
5
- MaxInt64 = (1<<62)-1
6
-
7
- EM.run do
8
- c = Fraggle.connect
9
- c.log.level = Logger::DEBUG
10
-
11
- EM.add_periodic_timer(1) do
12
- c.get("/hello") do |e|
13
- p [:e, e]
14
- end
15
- end
16
-
17
- c.set('/hello', 'world', MaxInt64) do |e|
18
- p [:set, e]
19
- end
20
- end
data/example/stat.rb DELETED
@@ -1,19 +0,0 @@
1
- require 'rubygems'
2
- require 'eventmachine'
3
- require 'fraggle'
4
-
5
- EM.run do
6
- c = Fraggle.connect
7
-
8
- EM.add_periodic_timer(1) do
9
- c.stat("/example") do |e|
10
- p e
11
- end.error do |e|
12
- p [:err, e]
13
- end
14
- end
15
-
16
- EM.add_periodic_timer(0.5) do
17
- c.set("/example/#{rand(10)}", "test", -1)
18
- end
19
- end
data/example/walk.rb DELETED
@@ -1,29 +0,0 @@
1
- require 'rubygems'
2
- require 'eventmachine'
3
- require 'fraggle'
4
-
5
- EM.run do
6
- c = Fraggle.connect
7
-
8
- paths = []
9
-
10
- req = c.walk("/**", 1)
11
-
12
- valid = Proc.new do |e|
13
- paths << e.path+"="+e.value
14
- end
15
-
16
- done = Proc.new do
17
- puts "rev #{req.rev} " + ("-"*25)
18
- puts *paths
19
-
20
- paths.clear
21
-
22
- req = c.walk("/**", req.rev+1)
23
- req.valid(&valid)
24
- req.done(&done)
25
- end
26
-
27
- req.valid(&valid)
28
- req.done(&done)
29
- end
@@ -1,36 +0,0 @@
1
- require 'fraggle/msg.pb'
2
-
3
- module Fraggle
4
- class Request
5
-
6
- DEFAULT_PROC = Proc.new {}
7
-
8
- attr_accessor :cn
9
- attr_reader :cb
10
-
11
- def initialize(attrs={})
12
- super(attrs)
13
- @cb = Hash.new
14
- end
15
-
16
- def valid(&blk)
17
- @cb[:valid] = blk
18
- self
19
- end
20
-
21
- def done(&blk)
22
- @cb[:done] = blk
23
- self
24
- end
25
-
26
- def error(&blk)
27
- @cb[:error] = blk
28
- self
29
- end
30
-
31
- def emit(name, *args)
32
- (@cb[name] || DEFAULT_PROC).call(*args)
33
- end
34
-
35
- end
36
- end