fraggle 2.0.0 → 3.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 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