faye 0.8.8 → 0.8.9
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of faye might be problematic. Click here for more details.
- data/History.txt +16 -10
- data/README.rdoc +1 -1
- data/lib/faye-browser-min.js +1 -1
- data/lib/faye-browser-min.js.map +2 -2
- data/lib/faye-browser.js +302 -287
- data/lib/faye.rb +21 -21
- data/lib/faye/adapters/rack_adapter.rb +50 -48
- data/lib/faye/adapters/static_server.rb +22 -22
- data/lib/faye/engines/connection.rb +13 -13
- data/lib/faye/engines/memory.rb +21 -21
- data/lib/faye/engines/proxy.rb +23 -23
- data/lib/faye/error.rb +6 -6
- data/lib/faye/mixins/logging.rb +12 -12
- data/lib/faye/mixins/publisher.rb +6 -6
- data/lib/faye/mixins/timeouts.rb +1 -1
- data/lib/faye/protocol/channel.rb +24 -24
- data/lib/faye/protocol/client.rb +71 -73
- data/lib/faye/protocol/extensible.rb +7 -7
- data/lib/faye/protocol/grammar.rb +13 -13
- data/lib/faye/protocol/server.rb +57 -57
- data/lib/faye/protocol/socket.rb +4 -4
- data/lib/faye/protocol/subscription.rb +4 -4
- data/lib/faye/transport/http.rb +13 -13
- data/lib/faye/transport/local.rb +5 -5
- data/lib/faye/transport/transport.rb +25 -25
- data/lib/faye/transport/web_socket.rb +34 -30
- data/lib/faye/util/namespace.rb +4 -4
- data/spec/browser.html +5 -5
- data/spec/javascript/channel_spec.js +3 -3
- data/spec/javascript/client_spec.js +104 -98
- data/spec/javascript/engine/memory_spec.js +1 -1
- data/spec/javascript/engine_spec.js +70 -70
- data/spec/javascript/faye_spec.js +6 -6
- data/spec/javascript/grammar_spec.js +12 -12
- data/spec/javascript/node_adapter_spec.js +46 -46
- data/spec/javascript/publisher_spec.js +4 -4
- data/spec/javascript/server/connect_spec.js +21 -21
- data/spec/javascript/server/disconnect_spec.js +15 -15
- data/spec/javascript/server/extensions_spec.js +6 -6
- data/spec/javascript/server/handshake_spec.js +18 -18
- data/spec/javascript/server/integration_spec.js +23 -23
- data/spec/javascript/server/publish_spec.js +9 -9
- data/spec/javascript/server/subscribe_spec.js +30 -30
- data/spec/javascript/server/unsubscribe_spec.js +30 -30
- data/spec/javascript/server_spec.js +15 -15
- data/spec/javascript/transport_spec.js +32 -27
- data/spec/node.js +2 -2
- data/spec/ruby/channel_spec.rb +2 -2
- data/spec/ruby/client_spec.rb +100 -92
- data/spec/ruby/engine_examples.rb +51 -51
- data/spec/ruby/faye_spec.rb +5 -5
- data/spec/ruby/grammar_spec.rb +12 -12
- data/spec/ruby/publisher_spec.rb +4 -4
- data/spec/ruby/rack_adapter_spec.rb +34 -34
- data/spec/ruby/server/connect_spec.rb +22 -22
- data/spec/ruby/server/disconnect_spec.rb +16 -16
- data/spec/ruby/server/extensions_spec.rb +8 -8
- data/spec/ruby/server/handshake_spec.rb +20 -20
- data/spec/ruby/server/integration_spec.rb +22 -24
- data/spec/ruby/server/publish_spec.rb +9 -9
- data/spec/ruby/server/subscribe_spec.rb +31 -31
- data/spec/ruby/server/unsubscribe_spec.rb +31 -31
- data/spec/ruby/server_spec.rb +17 -17
- data/spec/ruby/transport_spec.rb +23 -23
- data/spec/testswarm +23 -10
- data/spec/thin_proxy.rb +5 -5
- metadata +90 -59
data/lib/faye.rb
CHANGED
@@ -13,18 +13,18 @@ require 'uri'
|
|
13
13
|
require 'yajl'
|
14
14
|
|
15
15
|
module Faye
|
16
|
-
VERSION = '0.8.
|
17
|
-
|
16
|
+
VERSION = '0.8.9'
|
17
|
+
|
18
18
|
ROOT = File.expand_path(File.dirname(__FILE__))
|
19
|
-
|
19
|
+
|
20
20
|
autoload :Publisher, File.join(ROOT, 'faye', 'mixins', 'publisher')
|
21
21
|
autoload :Timeouts, File.join(ROOT, 'faye', 'mixins', 'timeouts')
|
22
22
|
autoload :Logging, File.join(ROOT, 'faye', 'mixins', 'logging')
|
23
|
-
|
23
|
+
|
24
24
|
autoload :Namespace, File.join(ROOT, 'faye', 'util', 'namespace')
|
25
|
-
|
25
|
+
|
26
26
|
autoload :Engine, File.join(ROOT, 'faye', 'engines', 'proxy')
|
27
|
-
|
27
|
+
|
28
28
|
autoload :Grammar, File.join(ROOT, 'faye', 'protocol', 'grammar')
|
29
29
|
autoload :Extensible, File.join(ROOT, 'faye', 'protocol', 'extensible')
|
30
30
|
autoload :Channel, File.join(ROOT, 'faye', 'protocol', 'channel')
|
@@ -32,37 +32,37 @@ module Faye
|
|
32
32
|
autoload :Publication, File.join(ROOT, 'faye', 'protocol', 'publication')
|
33
33
|
autoload :Client, File.join(ROOT, 'faye', 'protocol', 'client')
|
34
34
|
autoload :Server, File.join(ROOT, 'faye', 'protocol', 'server')
|
35
|
-
|
35
|
+
|
36
36
|
autoload :Transport, File.join(ROOT, 'faye', 'transport', 'transport')
|
37
37
|
autoload :Error, File.join(ROOT, 'faye', 'error')
|
38
|
-
|
38
|
+
|
39
39
|
autoload :RackAdapter, File.join(ROOT, 'faye', 'adapters', 'rack_adapter')
|
40
40
|
autoload :StaticServer, File.join(ROOT, 'faye', 'adapters', 'static_server')
|
41
|
-
|
41
|
+
|
42
42
|
BAYEUX_VERSION = '1.0'
|
43
43
|
JSONP_CALLBACK = 'jsonpcallback'
|
44
44
|
CONNECTION_TYPES = %w[long-polling cross-origin-long-polling callback-polling websocket eventsource in-process]
|
45
|
-
|
45
|
+
|
46
46
|
MANDATORY_CONNECTION_TYPES = %w[long-polling callback-polling in-process]
|
47
|
-
|
47
|
+
|
48
48
|
class << self
|
49
49
|
attr_accessor :logger
|
50
50
|
end
|
51
51
|
self.logger = method(:puts)
|
52
|
-
|
52
|
+
|
53
53
|
def self.ensure_reactor_running!
|
54
54
|
Engine.ensure_reactor_running!
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
def self.random(*args)
|
58
58
|
Engine.random(*args)
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
def self.client_id_from_messages(messages)
|
62
62
|
first = [messages].flatten.first
|
63
63
|
first && first['clientId']
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
def self.copy_object(object)
|
67
67
|
case object
|
68
68
|
when Hash
|
@@ -77,7 +77,7 @@ module Faye
|
|
77
77
|
object
|
78
78
|
end
|
79
79
|
end
|
80
|
-
|
80
|
+
|
81
81
|
def self.to_json(value)
|
82
82
|
case value
|
83
83
|
when Hash, Array then Yajl::Encoder.encode(value)
|
@@ -85,15 +85,15 @@ module Faye
|
|
85
85
|
else value.to_s
|
86
86
|
end
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
def self.async_each(list, iterator, callback)
|
90
90
|
n = list.size
|
91
91
|
i = -1
|
92
92
|
calls = 0
|
93
93
|
looping = false
|
94
|
-
|
94
|
+
|
95
95
|
loop, resume = nil, nil
|
96
|
-
|
96
|
+
|
97
97
|
iterate = lambda do
|
98
98
|
calls -= 1
|
99
99
|
i += 1
|
@@ -103,7 +103,7 @@ module Faye
|
|
103
103
|
iterator.call(list[i], resume)
|
104
104
|
end
|
105
105
|
end
|
106
|
-
|
106
|
+
|
107
107
|
loop = lambda do
|
108
108
|
unless looping
|
109
109
|
looping = true
|
@@ -111,7 +111,7 @@ module Faye
|
|
111
111
|
looping = false
|
112
112
|
end
|
113
113
|
end
|
114
|
-
|
114
|
+
|
115
115
|
resume = lambda do
|
116
116
|
calls += 1
|
117
117
|
loop.call
|
@@ -1,53 +1,53 @@
|
|
1
1
|
module Faye
|
2
2
|
class RackAdapter
|
3
|
-
|
3
|
+
|
4
4
|
include Logging
|
5
5
|
|
6
6
|
extend Forwardable
|
7
7
|
def_delegators "@server.engine", :bind, :unbind
|
8
8
|
|
9
9
|
ASYNC_RESPONSE = [-1, {}, []].freeze
|
10
|
-
|
10
|
+
|
11
11
|
DEFAULT_ENDPOINT = '/bayeux'
|
12
12
|
SCRIPT_PATH = 'faye-browser-min.js'
|
13
|
-
|
13
|
+
|
14
14
|
TYPE_JSON = {'Content-Type' => 'application/json; charset=utf-8'}
|
15
15
|
TYPE_SCRIPT = {'Content-Type' => 'text/javascript; charset=utf-8'}
|
16
16
|
TYPE_TEXT = {'Content-Type' => 'text/plain; charset=utf-8'}
|
17
|
-
|
17
|
+
|
18
18
|
# This header is passed by Rack::Proxy during testing. Rack::Proxy seems to
|
19
19
|
# set content-length for you, and setting it in here really slows the tests
|
20
20
|
# down. Better suggestions welcome.
|
21
21
|
HTTP_X_NO_CONTENT_LENGTH = 'HTTP_X_NO_CONTENT_LENGTH'
|
22
|
-
|
22
|
+
|
23
23
|
def initialize(app = nil, options = nil)
|
24
24
|
@app = app if app.respond_to?(:call)
|
25
25
|
@options = [app, options].grep(Hash).first || {}
|
26
|
-
|
26
|
+
|
27
27
|
@endpoint = @options[:mount] || DEFAULT_ENDPOINT
|
28
|
-
@endpoint_re = Regexp.new('^' + @endpoint + '(/[^/]+)*(\\.[^\\.]+)?$')
|
28
|
+
@endpoint_re = Regexp.new('^' + @endpoint.gsub(/\/$/, '') + '(/[^/]+)*(\\.[^\\.]+)?$')
|
29
29
|
@server = Server.new(@options)
|
30
|
-
|
30
|
+
|
31
31
|
@static = StaticServer.new(ROOT, /\.(?:js|map)$/)
|
32
32
|
@static.map(File.basename(@endpoint) + '.js', SCRIPT_PATH)
|
33
33
|
@static.map('client.js', SCRIPT_PATH)
|
34
|
-
|
34
|
+
|
35
35
|
return unless extensions = @options[:extensions]
|
36
36
|
[*extensions].each { |extension| add_extension(extension) }
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
def add_extension(extension)
|
40
40
|
@server.add_extension(extension)
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
def remove_extension(extension)
|
44
44
|
@server.remove_extension(extension)
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
def get_client
|
48
48
|
@client ||= Client.new(@server)
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
def listen(port, ssl_options = nil)
|
52
52
|
Faye::WebSocket.load_adapter('thin')
|
53
53
|
handler = Rack::Handler.get('thin')
|
@@ -62,56 +62,56 @@ module Faye
|
|
62
62
|
@thin_server = s
|
63
63
|
end
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
def stop
|
67
67
|
return unless @thin_server
|
68
68
|
@thin_server.stop
|
69
69
|
@thin_server = nil
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
def call(env)
|
73
73
|
Faye.ensure_reactor_running!
|
74
74
|
request = Rack::Request.new(env)
|
75
|
-
|
75
|
+
|
76
76
|
unless request.path_info =~ @endpoint_re
|
77
77
|
env['faye.client'] = get_client
|
78
78
|
return @app ? @app.call(env) :
|
79
79
|
[404, TYPE_TEXT, ["Sure you're not looking for #{@endpoint} ?"]]
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
# http://groups.google.com/group/faye-users/browse_thread/thread/4a01bb7d25d3636a
|
83
83
|
if env['REQUEST_METHOD'] == 'OPTIONS' or env['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'POST'
|
84
84
|
return handle_options(request)
|
85
85
|
end
|
86
|
-
|
86
|
+
|
87
87
|
return @static.call(env) if @static =~ request.path_info
|
88
88
|
return handle_websocket(env) if Faye::WebSocket.websocket?(env)
|
89
89
|
return handle_eventsource(env) if Faye::EventSource.eventsource?(env)
|
90
|
-
|
90
|
+
|
91
91
|
handle_request(request)
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
private
|
95
|
-
|
95
|
+
|
96
96
|
def handle_request(request)
|
97
97
|
unless json_msg = message_from_request(request)
|
98
98
|
error 'Received request with no message: ?', format_request(request)
|
99
99
|
return [400, TYPE_TEXT, ['Bad request']]
|
100
100
|
end
|
101
|
-
|
101
|
+
|
102
102
|
debug "Received message via HTTP #{request.request_method}: ?", json_msg
|
103
|
-
|
103
|
+
|
104
104
|
message = Yajl::Parser.parse(json_msg)
|
105
105
|
jsonp = request.params['jsonp'] || JSONP_CALLBACK
|
106
106
|
headers = request.get? ? TYPE_SCRIPT.dup : TYPE_JSON.dup
|
107
107
|
origin = request.env['HTTP_ORIGIN']
|
108
108
|
callback = request.env['async.callback']
|
109
|
-
|
109
|
+
|
110
110
|
@server.flush_connection(message) if request.get?
|
111
|
-
|
111
|
+
|
112
112
|
headers['Access-Control-Allow-Origin'] = origin if origin
|
113
113
|
headers['Cache-Control'] = 'no-cache, no-store'
|
114
|
-
|
114
|
+
|
115
115
|
@server.process(message, false) do |replies|
|
116
116
|
response = Faye.to_json(replies)
|
117
117
|
response = "#{ jsonp }(#{ response });" if request.get?
|
@@ -120,26 +120,28 @@ module Faye
|
|
120
120
|
debug 'HTTP response: ?', response
|
121
121
|
callback.call [200, headers, [response]]
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
ASYNC_RESPONSE
|
125
125
|
rescue => e
|
126
126
|
error "#{e.message}\nBacktrace:\n#{e.backtrace * "\n"}"
|
127
127
|
[400, TYPE_TEXT, ['Bad request']]
|
128
128
|
end
|
129
|
-
|
129
|
+
|
130
130
|
def handle_websocket(env)
|
131
131
|
ws = Faye::WebSocket.new(env, nil, :ping => @options[:ping])
|
132
132
|
client_id = nil
|
133
|
-
|
133
|
+
|
134
134
|
ws.onmessage = lambda do |event|
|
135
135
|
begin
|
136
136
|
debug "Received message via WebSocket[#{ws.version}]: ?", event.data
|
137
|
-
|
138
|
-
message
|
139
|
-
|
140
|
-
|
141
|
-
@server.
|
142
|
-
|
137
|
+
|
138
|
+
message = Yajl::Parser.parse(event.data)
|
139
|
+
cid = Faye.client_id_from_messages(message)
|
140
|
+
|
141
|
+
@server.close_socket(client_id) if client_id and cid != client_id
|
142
|
+
@server.open_socket(cid, ws)
|
143
|
+
client_id = cid
|
144
|
+
|
143
145
|
@server.process(message, false) do |replies|
|
144
146
|
ws.send(Faye.to_json(replies)) if ws
|
145
147
|
end
|
@@ -147,57 +149,57 @@ module Faye
|
|
147
149
|
error "#{e.message}\nBacktrace:\n#{e.backtrace * "\n"}"
|
148
150
|
end
|
149
151
|
end
|
150
|
-
|
152
|
+
|
151
153
|
ws.onclose = lambda do |event|
|
152
154
|
@server.close_socket(client_id)
|
153
155
|
ws = nil
|
154
156
|
end
|
155
|
-
|
157
|
+
|
156
158
|
ws.rack_response
|
157
159
|
end
|
158
|
-
|
160
|
+
|
159
161
|
def handle_eventsource(env)
|
160
162
|
es = Faye::EventSource.new(env, :ping => @options[:ping])
|
161
163
|
client_id = es.url.split('/').pop
|
162
|
-
|
164
|
+
|
163
165
|
debug 'Opened EventSource connection for ?', client_id
|
164
166
|
@server.open_socket(client_id, es)
|
165
|
-
|
167
|
+
|
166
168
|
es.onclose = lambda do |event|
|
167
169
|
@server.close_socket(client_id)
|
168
170
|
es = nil
|
169
171
|
end
|
170
|
-
|
172
|
+
|
171
173
|
es.rack_response
|
172
174
|
end
|
173
|
-
|
175
|
+
|
174
176
|
def message_from_request(request)
|
175
177
|
message = request.params['message']
|
176
178
|
return message if message
|
177
|
-
|
179
|
+
|
178
180
|
# Some clients do not send a content-type, e.g.
|
179
181
|
# Internet Explorer when using cross-origin-long-polling
|
180
182
|
# Some use application/xml when using CORS
|
181
183
|
content_type = request.env['CONTENT_TYPE'] || ''
|
182
|
-
|
184
|
+
|
183
185
|
if content_type.split(';').first == 'application/json'
|
184
186
|
request.body.read
|
185
187
|
else
|
186
188
|
CGI.parse(request.body.read)['message'][0]
|
187
189
|
end
|
188
190
|
end
|
189
|
-
|
191
|
+
|
190
192
|
def format_request(request)
|
191
193
|
request.body.rewind
|
192
194
|
string = "curl -X #{request.request_method.upcase}"
|
193
195
|
string << " '#{request.url}'"
|
194
196
|
if request.post?
|
195
|
-
string << " -H 'Content-Type: #{request.env['CONTENT_TYPE']}'"
|
197
|
+
string << " -H 'Content-Type: #{request.env['CONTENT_TYPE']}'"
|
196
198
|
string << " -d '#{request.body.read}'"
|
197
199
|
end
|
198
200
|
string
|
199
201
|
end
|
200
|
-
|
202
|
+
|
201
203
|
def handle_options(request)
|
202
204
|
headers = {
|
203
205
|
'Access-Control-Allow-Origin' => '*',
|
@@ -208,7 +210,7 @@ module Faye
|
|
208
210
|
}
|
209
211
|
[200, headers, ['']]
|
210
212
|
end
|
211
|
-
|
213
|
+
|
212
214
|
end
|
213
215
|
end
|
214
216
|
|
@@ -1,29 +1,28 @@
|
|
1
1
|
module Faye
|
2
2
|
class StaticServer
|
3
|
-
|
3
|
+
|
4
4
|
def initialize(directory, path_regex)
|
5
5
|
@directory = directory
|
6
6
|
@path_regex = path_regex
|
7
7
|
@path_map = {}
|
8
8
|
@index = {}
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def map(request_path, filename)
|
12
12
|
@path_map[request_path] = filename
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def =~(pathname)
|
16
16
|
@path_regex =~ pathname
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def call(env)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
20
|
+
filename = File.basename(env['PATH_INFO'])
|
21
|
+
filename = @path_map[filename] || filename
|
22
|
+
|
23
|
+
cache = @index[filename] ||= {}
|
24
|
+
fullpath = File.join(@directory, filename)
|
25
|
+
|
27
26
|
begin
|
28
27
|
cache[:content] ||= File.read(fullpath)
|
29
28
|
cache[:digest] ||= Digest::SHA1.hexdigest(cache[:content])
|
@@ -31,26 +30,27 @@ module Faye
|
|
31
30
|
rescue
|
32
31
|
return [404, {}, []]
|
33
32
|
end
|
34
|
-
|
35
|
-
type
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
|
34
|
+
type = /\.js$/ =~ fullpath ? RackAdapter::TYPE_SCRIPT : RackAdapter::TYPE_JSON
|
35
|
+
ims = env['HTTP_IF_MODIFIED_SINCE']
|
36
|
+
|
39
37
|
no_content_length = env[RackAdapter::HTTP_X_NO_CONTENT_LENGTH]
|
40
|
-
|
41
|
-
headers
|
42
|
-
|
43
|
-
|
44
|
-
|
38
|
+
|
39
|
+
headers = {
|
40
|
+
'ETag' => cache[:digest],
|
41
|
+
'Last-Modified' => cache[:mtime].httpdate
|
42
|
+
}
|
43
|
+
|
45
44
|
if env['HTTP_IF_NONE_MATCH'] == cache[:digest]
|
46
45
|
[304, headers, ['']]
|
47
46
|
elsif ims and cache[:mtime] <= Time.httpdate(ims)
|
48
47
|
[304, headers, ['']]
|
49
48
|
else
|
50
49
|
headers['Content-Length'] = cache[:content].bytesize.to_s unless no_content_length
|
50
|
+
headers.update(type)
|
51
51
|
[200, headers, [cache[:content]]]
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
end
|
56
56
|
end
|
@@ -1,60 +1,60 @@
|
|
1
1
|
module Faye
|
2
2
|
module Engine
|
3
|
-
|
3
|
+
|
4
4
|
class Connection
|
5
5
|
include EventMachine::Deferrable
|
6
6
|
include Timeouts
|
7
|
-
|
7
|
+
|
8
8
|
attr_accessor :socket
|
9
|
-
|
9
|
+
|
10
10
|
def initialize(engine, id, options = {})
|
11
11
|
@engine = engine
|
12
12
|
@id = id
|
13
13
|
@options = options
|
14
14
|
@inbox = Set.new
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def deliver(message)
|
18
18
|
return socket.send(message) if socket
|
19
19
|
return unless @inbox.add?(message)
|
20
20
|
begin_delivery_timeout
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def connect(options, &block)
|
24
24
|
options = options || {}
|
25
25
|
timeout = options['timeout'] ? options['timeout'] / 1000.0 : @engine.timeout
|
26
|
-
|
26
|
+
|
27
27
|
set_deferred_status(:deferred)
|
28
28
|
callback(&block)
|
29
|
-
|
29
|
+
|
30
30
|
begin_delivery_timeout
|
31
31
|
begin_connection_timeout(timeout)
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def flush!(force = false)
|
35
35
|
release_connection!(force)
|
36
36
|
set_deferred_status(:succeeded, @inbox.entries)
|
37
37
|
@inbox = []
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
private
|
41
|
-
|
41
|
+
|
42
42
|
def release_connection!(force = false)
|
43
43
|
@engine.close_connection(@id) if force or socket.nil?
|
44
44
|
remove_timeout(:connection)
|
45
45
|
remove_timeout(:delivery)
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def begin_delivery_timeout
|
49
49
|
return if @inbox.empty?
|
50
50
|
add_timeout(:delivery, MAX_DELAY) { flush! }
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
def begin_connection_timeout(timeout)
|
54
54
|
add_timeout(:connection, timeout) { flush! }
|
55
55
|
end
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|