fraggle 0.4.0 → 1.0.0pre
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/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Rakefile +17 -0
- data/example/again.rb +21 -0
- data/example/getdir.rb +24 -0
- data/example/ping.rb +19 -0
- data/example/session.rb +16 -0
- data/example/set.rb +21 -0
- data/example/stat.rb +23 -0
- data/example/walk.rb +23 -0
- data/example/watch.rb +22 -0
- data/fraggle.gemspec +25 -0
- data/lib/fraggle.rb +28 -35
- data/lib/fraggle/client.rb +70 -287
- data/lib/fraggle/connection.rb +139 -0
- data/lib/fraggle/msg.pb.rb +62 -0
- data/lib/fraggle/request.rb +37 -10
- data/lib/fraggle/response.rb +17 -38
- data/lib/fraggle/version.rb +3 -0
- data/test/fraggle_client_test.rb +185 -165
- data/test/fraggle_protocol_test.rb +27 -39
- data/test/fraggle_test.rb +5 -10
- data/test/fraggle_transaction_test.rb +220 -0
- data/test/helper.rb +84 -0
- metadata +59 -36
- data/lib/fraggle/emitter.rb +0 -39
- data/lib/fraggle/errors.rb +0 -3
- data/lib/fraggle/logger.rb +0 -32
- data/lib/fraggle/meta.rb +0 -9
- data/lib/fraggle/msg.rb +0 -77
- data/lib/fraggle/protocol.rb +0 -43
- data/lib/fraggle/test.rb +0 -72
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
HOME = ENV["HOME"]
|
5
|
+
PBDIR = HOME+"/src/doozer/src/pkg/proto"
|
6
|
+
|
7
|
+
namespace :proto do
|
8
|
+
task :update do
|
9
|
+
ENV["BEEFCAKE_NAMESPACE"] = "Fraggle"
|
10
|
+
sh(
|
11
|
+
"protoc",
|
12
|
+
"--beefcake_out", "lib/fraggle",
|
13
|
+
"-I", PBDIR,
|
14
|
+
PBDIR+"/msg.proto"
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
data/example/again.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'fraggle'
|
4
|
+
|
5
|
+
EM.run do
|
6
|
+
|
7
|
+
c = Fraggle.connect
|
8
|
+
c.level = Fraggle::Logger::INFO
|
9
|
+
|
10
|
+
paths = []
|
11
|
+
|
12
|
+
c.walk("/**") do |e|
|
13
|
+
paths << e.path+"="+e.value
|
14
|
+
end.again do |w|
|
15
|
+
# We've been connected to to a new server, Resend the request
|
16
|
+
c.send(w)
|
17
|
+
end.done do
|
18
|
+
puts "## DONE", *paths
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/example/getdir.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'fraggle'
|
4
|
+
|
5
|
+
EM.run do
|
6
|
+
|
7
|
+
EM.error_handler do |e|
|
8
|
+
$stderr.puts e.message + "\n" + (e.backtrace * "\n")
|
9
|
+
end
|
10
|
+
|
11
|
+
c = Fraggle.connect
|
12
|
+
c.level = Fraggle::Logger::INFO
|
13
|
+
|
14
|
+
ents = []
|
15
|
+
req = c.getdir "/doozer" do |e|
|
16
|
+
ents << e.path
|
17
|
+
end
|
18
|
+
|
19
|
+
req.error do
|
20
|
+
puts *ents
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
end
|
data/example/ping.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'fraggle'
|
4
|
+
|
5
|
+
EM.run do
|
6
|
+
|
7
|
+
EM.error_handler do |e|
|
8
|
+
$stderr.puts e.message + "\n" + (e.backtrace * "\n")
|
9
|
+
end
|
10
|
+
|
11
|
+
c = Fraggle.connect
|
12
|
+
|
13
|
+
EM.add_periodic_timer(1) do
|
14
|
+
c.get nil, "/ping" do |e|
|
15
|
+
p [:e, e]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/example/session.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'fraggle'
|
4
|
+
|
5
|
+
EM.run do
|
6
|
+
|
7
|
+
EM.error_handler do |e|
|
8
|
+
$stderr.puts e.message + "\n" + (e.backtrace * "\n")
|
9
|
+
end
|
10
|
+
|
11
|
+
c = Fraggle.connect :level => Fraggle::Client::DEBUG
|
12
|
+
|
13
|
+
c.session "example." do |session_id|
|
14
|
+
c.debug "established session (#{session_id})!"
|
15
|
+
end
|
16
|
+
end
|
data/example/set.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'fraggle'
|
4
|
+
|
5
|
+
EM.run do
|
6
|
+
EM.error_handler do |e|
|
7
|
+
$stderr.puts e.message + "\n" + (e.backtrace * "\n")
|
8
|
+
end
|
9
|
+
|
10
|
+
c = Fraggle.connect
|
11
|
+
|
12
|
+
EM.add_periodic_timer(1) do
|
13
|
+
c.get "/hello" do |e|
|
14
|
+
p [:e, e]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
c.set '/hello', 'world', :missing do |e|
|
19
|
+
p e
|
20
|
+
end
|
21
|
+
end
|
data/example/stat.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'fraggle'
|
4
|
+
|
5
|
+
EM.run do
|
6
|
+
|
7
|
+
EM.error_handler do |e|
|
8
|
+
$stderr.puts e.message + "\n" + (e.backtrace * "\n")
|
9
|
+
end
|
10
|
+
|
11
|
+
c = Fraggle.connect
|
12
|
+
|
13
|
+
EM.add_periodic_timer(1) do
|
14
|
+
c.stat "/example" do |e|
|
15
|
+
p e
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
EM.add_periodic_timer(0.5) do
|
20
|
+
c.set "/example/#{rand(10)}", "test", :clobber
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/example/walk.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'fraggle'
|
4
|
+
|
5
|
+
EM.run do
|
6
|
+
|
7
|
+
EM.error_handler do |e|
|
8
|
+
$stderr.puts e.message + "\n" + (e.backtrace * "\n")
|
9
|
+
end
|
10
|
+
|
11
|
+
c = Fraggle.connect
|
12
|
+
|
13
|
+
paths = []
|
14
|
+
req = c.walk "/**" do |e|
|
15
|
+
paths << e.path+"="+e.value
|
16
|
+
end
|
17
|
+
|
18
|
+
req.done do
|
19
|
+
puts *paths
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
end
|
data/example/watch.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'fraggle'
|
4
|
+
|
5
|
+
EM.run do
|
6
|
+
|
7
|
+
EM.error_handler do |e|
|
8
|
+
$stderr.puts e.message + "\n" + (e.backtrace * "\n")
|
9
|
+
end
|
10
|
+
|
11
|
+
c = Fraggle.connect
|
12
|
+
c.level = Fraggle::Logger::WARN
|
13
|
+
|
14
|
+
c.watch "/example/*" do |e|
|
15
|
+
p e
|
16
|
+
end
|
17
|
+
|
18
|
+
EM.add_periodic_timer(0.5) do
|
19
|
+
c.set "/example/#{rand(10)}", "test", :clobber
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/fraggle.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "fraggle/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "fraggle"
|
7
|
+
s.version = Fraggle::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Blake Mizerany"]
|
10
|
+
s.email = ["blake.mizerany@gmail.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{An EventMachine Client for Doozer}
|
13
|
+
s.description = s.summary
|
14
|
+
|
15
|
+
s.rubyforge_project = "fraggle"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency "beefcake", "~>0.3"
|
23
|
+
|
24
|
+
s.add_development_dependency "turn"
|
25
|
+
end
|
data/lib/fraggle.rb
CHANGED
@@ -1,50 +1,43 @@
|
|
1
1
|
require 'fraggle/client'
|
2
|
-
require 'fraggle/errors'
|
3
|
-
require 'fraggle/logger'
|
4
|
-
require 'uri'
|
5
2
|
|
6
3
|
module Fraggle
|
7
|
-
extend Logger
|
8
4
|
|
9
|
-
|
10
|
-
|
11
|
-
"ca=127.0.0.1:
|
12
|
-
|
13
|
-
# Default host + test-cluster ports
|
14
|
-
"ca=127.0.0.1:8041&"+
|
15
|
-
"ca=127.0.0.1:8042&"+
|
5
|
+
DEFAULT_URI = "doozerd:?" + [
|
6
|
+
"ca=127.0.0.1:8046",
|
7
|
+
"ca=127.0.0.1:8041",
|
8
|
+
"ca=127.0.0.1:8042",
|
16
9
|
"ca=127.0.0.1:8043"
|
10
|
+
].join("&")
|
11
|
+
|
12
|
+
def self.connect(uri=nil)
|
13
|
+
uri = uri || ENV["DOOZER_URI"] || DEFAULT_URI
|
14
|
+
|
15
|
+
addrs = uri(uri)
|
16
|
+
|
17
|
+
if addrs.length == 0
|
18
|
+
raise ArgumentError, "there were no addrs supplied in the uri (#{uri.inspect})"
|
19
|
+
end
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
uri = args.shift || ENV["DOOZER_URI"] || DefaultUri
|
21
|
-
addrs = addrs_for(uri)
|
21
|
+
addr = addrs.shift
|
22
|
+
host, port = addr.split(":")
|
22
23
|
|
23
|
-
host, port
|
24
|
-
|
24
|
+
cn = EM.connect(host, port, Connection, addr)
|
25
|
+
Client.new(cn, addrs)
|
25
26
|
end
|
26
27
|
|
27
|
-
def self.
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
# Perform a liberal validation to weed out most mistakes
|
35
|
-
if v =~ /^[\d\w\-.]+:\d+$/
|
36
|
-
addrs << v
|
37
|
-
else
|
38
|
-
warn "invalid addr (#{v}) in #{uri}"
|
28
|
+
def self.uri(u)
|
29
|
+
if u =~ /^doozerd:\?(.*)$/
|
30
|
+
parts = $1.split("&")
|
31
|
+
parts.inject([]) do |m, pt|
|
32
|
+
k, v = pt.split("=")
|
33
|
+
if k == "ca"
|
34
|
+
m << v
|
39
35
|
end
|
36
|
+
m
|
40
37
|
end
|
38
|
+
else
|
39
|
+
raise ArgumentError, "invalid doozerd uri"
|
41
40
|
end
|
42
|
-
|
43
|
-
if addrs.empty?
|
44
|
-
raise NoAddrs
|
45
|
-
end
|
46
|
-
|
47
|
-
addrs
|
48
41
|
end
|
49
42
|
|
50
43
|
end
|
data/lib/fraggle/client.rb
CHANGED
@@ -1,253 +1,99 @@
|
|
1
|
-
require '
|
2
|
-
require 'fraggle/
|
3
|
-
require 'fraggle/meta'
|
4
|
-
require 'fraggle/protocol'
|
5
|
-
require 'fraggle/request'
|
6
|
-
require 'fraggle/response'
|
7
|
-
require 'set'
|
8
|
-
require 'uri'
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'fraggle/connection'
|
9
3
|
|
10
4
|
module Fraggle
|
5
|
+
class Client
|
6
|
+
include Request::Verb
|
11
7
|
|
12
|
-
|
13
|
-
include Protocol
|
14
|
-
include Logger
|
15
|
-
|
16
|
-
class Error < StandardError ; end
|
17
|
-
|
18
|
-
|
19
|
-
MinTag = 0
|
20
|
-
MaxTag = (1<<32)
|
21
|
-
|
22
|
-
Nibbles = "0123456789abcdef"
|
23
|
-
|
24
|
-
def initialize(addr, addrs=[], opts={})
|
25
|
-
@cbx = {}
|
26
|
-
|
27
|
-
@addr = addr
|
28
|
-
@addrs = {}
|
29
|
-
|
30
|
-
addrs.each_with_index do |addr, i|
|
31
|
-
@addrs[i] = addr
|
32
|
-
end
|
33
|
-
|
34
|
-
# Logging
|
35
|
-
@level = opts[:level] || ERROR
|
36
|
-
@writer = $stderr
|
8
|
+
class NoMoreAddrs < StandardError
|
37
9
|
end
|
38
10
|
|
39
|
-
|
40
|
-
debug "received response: #{res.inspect}"
|
41
|
-
|
42
|
-
if res.err_code
|
43
|
-
if req = @cbx.delete(res.tag)
|
44
|
-
req.emit(:error, res)
|
45
|
-
return
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
if (res.flags & Response::Flag::VALID) > 0
|
50
|
-
if req = @cbx[res.tag]
|
51
|
-
req.emit(:valid, res)
|
52
|
-
end
|
53
|
-
end
|
11
|
+
attr_reader :cn
|
54
12
|
|
55
|
-
|
56
|
-
|
57
|
-
req.emit(:done)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def rev
|
63
|
-
req = Request.new
|
64
|
-
req.verb = Request::Verb::REV
|
65
|
-
|
66
|
-
resend(req)
|
13
|
+
def initialize(cn, addrs)
|
14
|
+
@cn, @addrs = cn, addrs
|
67
15
|
end
|
68
16
|
|
69
|
-
def
|
17
|
+
def set(rev, path, value, &blk)
|
70
18
|
req = Request.new
|
71
|
-
req.verb
|
72
|
-
req.
|
73
|
-
req.
|
74
|
-
|
75
|
-
|
76
|
-
end
|
77
|
-
|
78
|
-
def session(prefix=nil, &blk)
|
79
|
-
name = "#{prefix}#{genkey}"
|
80
|
-
estab = false
|
81
|
-
|
82
|
-
f = Proc.new do |e|
|
83
|
-
# If this is the first response from the server, it's go-time.
|
84
|
-
if ! estab
|
85
|
-
blk.call(name)
|
86
|
-
end
|
87
|
-
|
88
|
-
# We've successfully established a session. Say so.
|
89
|
-
estab = true
|
90
|
-
|
91
|
-
# Get back to the server ASAP
|
92
|
-
checkin(name, e.rev).valid(&f)
|
93
|
-
end
|
19
|
+
req.verb = SET
|
20
|
+
req.rev = rev
|
21
|
+
req.path = path
|
22
|
+
req.value = value
|
23
|
+
req.valid(&blk)
|
94
24
|
|
95
|
-
|
25
|
+
send(req)
|
96
26
|
end
|
97
27
|
|
98
|
-
def get(rev, path)
|
28
|
+
def get(rev, path, &blk)
|
99
29
|
req = Request.new
|
30
|
+
req.verb = GET
|
100
31
|
req.rev = rev
|
101
|
-
req.verb = Request::Verb::GET
|
102
32
|
req.path = path
|
33
|
+
req.valid(&blk)
|
103
34
|
|
104
|
-
|
35
|
+
send(req)
|
105
36
|
end
|
106
37
|
|
107
|
-
def
|
38
|
+
def del(rev, path, &blk)
|
108
39
|
req = Request.new
|
40
|
+
req.verb = DEL
|
109
41
|
req.rev = rev
|
110
|
-
req.verb = Request::Verb::STAT
|
111
42
|
req.path = path
|
112
|
-
|
113
|
-
resend(req)
|
114
|
-
end
|
115
|
-
|
116
|
-
def getdir(rev, path, offset, limit)
|
117
|
-
req = Request.new
|
118
|
-
req.rev = rev
|
119
|
-
req.verb = Request::Verb::GETDIR
|
120
|
-
req.offset = offset if offset != 0
|
121
|
-
req.limit = limit if limit != 0
|
122
|
-
req.path = path
|
123
|
-
|
124
|
-
resend(req)
|
125
|
-
end
|
126
|
-
|
127
|
-
def set(path, value, rev)
|
128
|
-
req = Request.new
|
129
|
-
req.verb = Request::Verb::SET
|
130
|
-
req.path = path
|
131
|
-
req.value = value
|
132
|
-
req.rev = casify(rev)
|
133
|
-
|
134
|
-
send(req)
|
135
|
-
end
|
136
|
-
|
137
|
-
def del(path, rev)
|
138
|
-
req = Request.new
|
139
|
-
req.verb = Request::Verb::DEL
|
140
|
-
req.path = path
|
141
|
-
req.rev = casify(rev)
|
43
|
+
req.valid(&blk)
|
142
44
|
|
143
45
|
send(req)
|
144
46
|
end
|
145
47
|
|
146
|
-
def
|
48
|
+
def getdir(rev, path, offset=nil, limit=nil, &blk)
|
147
49
|
req = Request.new
|
148
|
-
req.verb
|
149
|
-
req.rev
|
150
|
-
req.path
|
50
|
+
req.verb = GETDIR
|
51
|
+
req.rev = rev
|
52
|
+
req.path = path
|
151
53
|
req.offset = offset
|
152
54
|
req.limit = limit
|
55
|
+
req.valid(&blk)
|
153
56
|
|
154
|
-
|
57
|
+
send(req)
|
155
58
|
end
|
156
59
|
|
157
|
-
def
|
60
|
+
def walk(rev, path, offset=nil, limit=nil, &blk)
|
158
61
|
req = Request.new
|
62
|
+
req.verb = WALK
|
159
63
|
req.rev = rev
|
160
|
-
req.
|
161
|
-
req.
|
64
|
+
req.path = path
|
65
|
+
req.offset = offset
|
66
|
+
req.limit = limit
|
67
|
+
req.valid(&blk)
|
162
68
|
|
163
|
-
|
69
|
+
send(req)
|
164
70
|
end
|
165
71
|
|
166
|
-
def
|
72
|
+
def watch(rev, path, &blk)
|
167
73
|
req = Request.new
|
74
|
+
req.verb = WATCH
|
168
75
|
req.rev = rev
|
169
|
-
req.path =
|
170
|
-
|
171
|
-
wt = nil
|
172
|
-
wk = nil
|
173
|
-
|
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
|
192
|
-
|
193
|
-
req
|
194
|
-
end
|
195
|
-
|
196
|
-
def noop(&blk)
|
197
|
-
req = Request.new
|
198
|
-
req.verb = Request::Verb::NOOP
|
76
|
+
req.path = path
|
77
|
+
req.valid(&blk)
|
199
78
|
|
200
79
|
send(req)
|
201
80
|
end
|
202
81
|
|
203
|
-
|
204
|
-
# returned to ensure you don't run into a race-condition where you cancel an
|
205
|
-
# operation you may have thought was something else.
|
206
|
-
def __cancel__(what)
|
82
|
+
def rev(&blk)
|
207
83
|
req = Request.new
|
208
|
-
req.verb =
|
209
|
-
req.
|
210
|
-
|
211
|
-
# Hold on to the tag as unavaiable for reuse until the cancel succeeds.
|
212
|
-
@cbx[what.tag] = nil
|
213
|
-
|
214
|
-
send(req).valid do |res|
|
215
|
-
# Do not send any more responses from the server to this request.
|
216
|
-
@cbx.delete(what.tag)
|
217
|
-
what.emit(:valid, res)
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
def next_tag
|
222
|
-
tag = MinTag
|
223
|
-
|
224
|
-
while @cbx.has_key?(tag)
|
225
|
-
tag += 1
|
226
|
-
if tag > MaxTag
|
227
|
-
tag = MinTag
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
tag
|
232
|
-
end
|
233
|
-
|
234
|
-
def send(req)
|
235
|
-
req.tag ||= next_tag
|
84
|
+
req.verb = REV
|
85
|
+
req.valid(&blk)
|
236
86
|
|
237
|
-
|
238
|
-
|
239
|
-
debug "sending request: #{req.inspect}"
|
240
|
-
send_request(req)
|
241
|
-
|
242
|
-
req
|
87
|
+
send(req)
|
243
88
|
end
|
244
89
|
|
245
|
-
def
|
246
|
-
req.
|
90
|
+
def send(req, &onre)
|
91
|
+
wr = Request.new(req.to_hash)
|
92
|
+
wr = cn.send_request(wr)
|
247
93
|
|
248
|
-
|
94
|
+
req.tag = wr.tag
|
249
95
|
|
250
|
-
|
96
|
+
wr.valid do |e|
|
251
97
|
if req.offset
|
252
98
|
req.offset += 1
|
253
99
|
end
|
@@ -260,108 +106,45 @@ module Fraggle
|
|
260
106
|
req.rev = e.rev
|
261
107
|
end
|
262
108
|
|
263
|
-
|
264
|
-
end
|
265
|
-
|
266
|
-
req.error do |err|
|
267
|
-
if err.disconnected?
|
268
|
-
send(req)
|
269
|
-
else
|
270
|
-
wrap.emit(:error, err)
|
271
|
-
end
|
109
|
+
req.emit(:valid, e)
|
272
110
|
end
|
273
111
|
|
274
|
-
|
275
|
-
|
112
|
+
wr.done do
|
113
|
+
req.emit(:done)
|
276
114
|
end
|
277
115
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
can = true
|
286
|
-
|
287
|
-
req.metadef :cancel do
|
288
|
-
if can
|
289
|
-
can = false
|
290
|
-
c.__cancel__(self)
|
116
|
+
wr.error do |e|
|
117
|
+
case true
|
118
|
+
when cn.err? || e.redirect?
|
119
|
+
reconnect!
|
120
|
+
onre.call if onre
|
121
|
+
else
|
122
|
+
req.emit(:error, e)
|
291
123
|
end
|
292
124
|
end
|
293
125
|
|
294
|
-
req.metadef :canceled? do
|
295
|
-
!can
|
296
|
-
end
|
297
|
-
|
298
126
|
req
|
299
127
|
end
|
300
128
|
|
301
|
-
def
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
@cbx.values.compact.each do |req|
|
306
|
-
debug "sending disconnected error to #{req.inspect}"
|
307
|
-
req.emit(:error, res)
|
308
|
-
end
|
309
|
-
|
310
|
-
if ! @tracking
|
311
|
-
trackaddrs
|
312
|
-
@tracking = true
|
313
|
-
end
|
314
|
-
end
|
315
|
-
|
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
|
327
|
-
end
|
328
|
-
end
|
329
|
-
end.error do |err|
|
330
|
-
error "address tracking: #{err.inspect} for #{req.inspect}"
|
331
|
-
end
|
332
|
-
end
|
333
|
-
end
|
334
|
-
|
335
|
-
# What happens when a connection is closed for any reason.
|
336
|
-
def unbind
|
337
|
-
info "disconnected from #{@addr}"
|
338
|
-
|
339
|
-
_, @addr = @addrs.shift
|
340
|
-
if ! @addr
|
341
|
-
raise "No more addrs"
|
129
|
+
def resend(req)
|
130
|
+
send(req) do
|
131
|
+
req.tag = nil
|
132
|
+
resend(req)
|
342
133
|
end
|
343
|
-
|
344
|
-
host, port = @addr.split(":")
|
345
|
-
|
346
|
-
info "attempting connection to #{@addr}"
|
347
|
-
|
348
|
-
reconnect(host, port.to_i)
|
349
|
-
|
350
|
-
post_init
|
351
134
|
end
|
352
135
|
|
353
|
-
def
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
136
|
+
def reconnect!
|
137
|
+
if addr = @addrs.shift
|
138
|
+
reconnect(addr)
|
139
|
+
else
|
140
|
+
raise NoMoreAddrs
|
358
141
|
end
|
359
142
|
end
|
360
143
|
|
361
|
-
def
|
362
|
-
|
144
|
+
def reconnect(addr)
|
145
|
+
host, port = addr.split(":")
|
146
|
+
@cn = EM.connect(host, port, Fraggle::Connection, @addrs)
|
363
147
|
end
|
364
148
|
|
365
149
|
end
|
366
|
-
|
367
150
|
end
|