message_bus 2.1.6 → 2.2.0.pre
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of message_bus might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rubocop.yml +13 -92
- data/.rubocop_todo.yml +659 -0
- data/.travis.yml +1 -1
- data/CHANGELOG +61 -0
- data/Dockerfile +18 -0
- data/Gemfile +3 -1
- data/Guardfile +0 -1
- data/README.md +188 -101
- data/Rakefile +12 -1
- data/assets/message-bus.js +1 -1
- data/docker-compose.yml +46 -0
- data/examples/bench/config.ru +8 -9
- data/examples/bench/unicorn.conf.rb +1 -1
- data/examples/chat/chat.rb +150 -153
- data/examples/minimal/config.ru +2 -3
- data/lib/message_bus.rb +224 -36
- data/lib/message_bus/backends.rb +7 -0
- data/lib/message_bus/backends/base.rb +184 -0
- data/lib/message_bus/backends/memory.rb +304 -226
- data/lib/message_bus/backends/postgres.rb +359 -318
- data/lib/message_bus/backends/redis.rb +380 -337
- data/lib/message_bus/client.rb +99 -41
- data/lib/message_bus/connection_manager.rb +29 -21
- data/lib/message_bus/diagnostics.rb +50 -41
- data/lib/message_bus/distributed_cache.rb +5 -7
- data/lib/message_bus/message.rb +2 -2
- data/lib/message_bus/rack/diagnostics.rb +65 -55
- data/lib/message_bus/rack/middleware.rb +64 -44
- data/lib/message_bus/rack/thin_ext.rb +13 -9
- data/lib/message_bus/rails/railtie.rb +2 -0
- data/lib/message_bus/timer_thread.rb +2 -2
- data/lib/message_bus/version.rb +2 -1
- data/message_bus.gemspec +3 -2
- data/spec/assets/support/jasmine_helper.rb +1 -1
- data/spec/lib/fake_async_middleware.rb +1 -6
- data/spec/lib/message_bus/assets/asset_encoding_spec.rb +3 -3
- data/spec/lib/message_bus/backend_spec.rb +409 -0
- data/spec/lib/message_bus/client_spec.rb +8 -11
- data/spec/lib/message_bus/connection_manager_spec.rb +8 -14
- data/spec/lib/message_bus/distributed_cache_spec.rb +0 -4
- data/spec/lib/message_bus/multi_process_spec.rb +6 -7
- data/spec/lib/message_bus/rack/middleware_spec.rb +47 -43
- data/spec/lib/message_bus/timer_thread_spec.rb +0 -2
- data/spec/lib/message_bus_spec.rb +59 -43
- data/spec/spec_helper.rb +16 -4
- metadata +12 -9
- data/spec/lib/message_bus/backends/postgres_spec.rb +0 -221
- data/spec/lib/message_bus/backends/redis_spec.rb +0 -271
@@ -2,7 +2,6 @@ require_relative '../../spec_helper'
|
|
2
2
|
require 'message_bus'
|
3
3
|
|
4
4
|
class FakeAsync
|
5
|
-
|
6
5
|
attr_accessor :cleanup_timer
|
7
6
|
|
8
7
|
def <<(val)
|
@@ -12,7 +11,9 @@ class FakeAsync
|
|
12
11
|
end
|
13
12
|
|
14
13
|
def sent; @sent; end
|
14
|
+
|
15
15
|
def done; @done = true; end
|
16
|
+
|
16
17
|
def done?; @done; end
|
17
18
|
end
|
18
19
|
|
@@ -22,7 +23,6 @@ class FakeTimer
|
|
22
23
|
end
|
23
24
|
|
24
25
|
describe MessageBus::ConnectionManager do
|
25
|
-
|
26
26
|
before do
|
27
27
|
@bus = MessageBus
|
28
28
|
@manager = MessageBus::ConnectionManager.new(@bus)
|
@@ -35,7 +35,7 @@ describe MessageBus::ConnectionManager do
|
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should cancel the timer after its responds" do
|
38
|
-
m = MessageBus::Message.new(1,1,"test","data")
|
38
|
+
m = MessageBus::Message.new(1, 1, "test", "data")
|
39
39
|
m.site_id = 10
|
40
40
|
@manager.notify_clients(m)
|
41
41
|
@client.cleanup_timer.cancelled.must_equal true
|
@@ -45,26 +45,22 @@ describe MessageBus::ConnectionManager do
|
|
45
45
|
@manager.lookup_client(@client.client_id).must_equal @client
|
46
46
|
end
|
47
47
|
|
48
|
-
it "should be subscribed to a channel" do
|
49
|
-
@manager.stats[:subscriptions][10]["test"].length == 1
|
50
|
-
end
|
51
|
-
|
52
48
|
it "should not notify clients on incorrect site" do
|
53
|
-
m = MessageBus::Message.new(1,1,"test","data")
|
49
|
+
m = MessageBus::Message.new(1, 1, "test", "data")
|
54
50
|
m.site_id = 9
|
55
51
|
@manager.notify_clients(m)
|
56
52
|
assert_nil @resp.sent
|
57
53
|
end
|
58
54
|
|
59
55
|
it "should notify clients on the correct site" do
|
60
|
-
m = MessageBus::Message.new(1,1,"test","data")
|
56
|
+
m = MessageBus::Message.new(1, 1, "test", "data")
|
61
57
|
m.site_id = 10
|
62
58
|
@manager.notify_clients(m)
|
63
59
|
@resp.sent.wont_equal nil
|
64
60
|
end
|
65
61
|
|
66
62
|
it "should strip site id and user id from the payload delivered" do
|
67
|
-
m = MessageBus::Message.new(1,1,"test","data")
|
63
|
+
m = MessageBus::Message.new(1, 1, "test", "data")
|
68
64
|
m.user_ids = [1]
|
69
65
|
m.site_id = 10
|
70
66
|
@manager.notify_clients(m)
|
@@ -74,7 +70,7 @@ describe MessageBus::ConnectionManager do
|
|
74
70
|
end
|
75
71
|
|
76
72
|
it "should not deliver unselected" do
|
77
|
-
m = MessageBus::Message.new(1,1,"test","data")
|
73
|
+
m = MessageBus::Message.new(1, 1, "test", "data")
|
78
74
|
m.user_ids = [5]
|
79
75
|
m.site_id = 10
|
80
76
|
@manager.notify_clients(m)
|
@@ -83,7 +79,6 @@ describe MessageBus::ConnectionManager do
|
|
83
79
|
end
|
84
80
|
|
85
81
|
describe MessageBus::ConnectionManager, "notifying and subscribing concurrently" do
|
86
|
-
|
87
82
|
it "does not subscribe incorrect clients" do
|
88
83
|
manager = MessageBus::ConnectionManager.new
|
89
84
|
|
@@ -114,7 +109,7 @@ describe MessageBus::ConnectionManager, "notifying and subscribing concurrently"
|
|
114
109
|
|
115
110
|
subscriber_threads = 10.times.map do |id|
|
116
111
|
Thread.new do
|
117
|
-
m = MessageBus::Message.new(1,id,"test","data_#{id}")
|
112
|
+
m = MessageBus::Message.new(1, id, "test", "data_#{id}")
|
118
113
|
m.site_id = 10
|
119
114
|
@manager.notify_clients(m)
|
120
115
|
1
|
@@ -124,5 +119,4 @@ describe MessageBus::ConnectionManager, "notifying and subscribing concurrently"
|
|
124
119
|
client_threads.each(&:join).map(&:value).must_equal([1] * 10)
|
125
120
|
subscriber_threads.each(&:join).map(&:value).must_equal([1] * 10)
|
126
121
|
end
|
127
|
-
|
128
122
|
end
|
@@ -4,7 +4,6 @@ require 'message_bus'
|
|
4
4
|
require 'message_bus/distributed_cache'
|
5
5
|
|
6
6
|
describe MessageBus::DistributedCache do
|
7
|
-
|
8
7
|
before :all do
|
9
8
|
@bus = MessageBus::Instance.new
|
10
9
|
@bus.configure(backend: :memory)
|
@@ -29,7 +28,6 @@ describe MessageBus::DistributedCache do
|
|
29
28
|
end
|
30
29
|
|
31
30
|
it 'supports arrays with hashes' do
|
32
|
-
|
33
31
|
c1 = cache("test1")
|
34
32
|
c2 = cache("test1")
|
35
33
|
|
@@ -81,7 +79,6 @@ describe MessageBus::DistributedCache do
|
|
81
79
|
|
82
80
|
Thread.pass
|
83
81
|
assert_nil(@cache1["hi"])
|
84
|
-
|
85
82
|
end
|
86
83
|
|
87
84
|
it 'allows coerces symbol keys to strings' do
|
@@ -129,5 +126,4 @@ describe MessageBus::DistributedCache do
|
|
129
126
|
@cache2["boom"] == nil
|
130
127
|
end
|
131
128
|
end
|
132
|
-
|
133
129
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require_relative '../../spec_helper'
|
2
2
|
require 'message_bus'
|
3
3
|
|
4
|
-
unless MESSAGE_BUS_CONFIG[:backend] == :memory
|
5
4
|
describe PUB_SUB_CLASS do
|
6
5
|
def self.error!
|
7
6
|
@error = true
|
@@ -12,7 +11,7 @@ describe PUB_SUB_CLASS do
|
|
12
11
|
end
|
13
12
|
|
14
13
|
def new_bus
|
15
|
-
PUB_SUB_CLASS.new(MESSAGE_BUS_CONFIG.merge(:
|
14
|
+
PUB_SUB_CLASS.new(MESSAGE_BUS_CONFIG.merge(db: 10))
|
16
15
|
end
|
17
16
|
|
18
17
|
def work_it
|
@@ -38,14 +37,15 @@ describe PUB_SUB_CLASS do
|
|
38
37
|
|
39
38
|
n = ENV['MULTI_PROCESS_TIMES'].to_i
|
40
39
|
n = 1 if n < 1
|
41
|
-
n.times do
|
40
|
+
n.times do
|
42
41
|
it 'gets every response from child processes' do
|
42
|
+
test_never :memory
|
43
43
|
skip("previous error") if self.class.error?
|
44
44
|
GC.start
|
45
45
|
new_bus.reset!
|
46
46
|
begin
|
47
|
-
pids = (1..10).map{spawn_child}
|
48
|
-
expected_responses = pids.map{|x| (0...10).map{|i| "0#{i}-#{x}"}}.flatten
|
47
|
+
pids = (1..10).map { spawn_child }
|
48
|
+
expected_responses = pids.map { |x| (0...10).map { |i| "0#{i}-#{x}" } }.flatten
|
49
49
|
unexpected_responses = []
|
50
50
|
bus = new_bus
|
51
51
|
t = Thread.new do
|
@@ -57,7 +57,7 @@ describe PUB_SUB_CLASS do
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
60
|
-
10.times{|i| bus.publish("/echo", "0#{i}")}
|
60
|
+
10.times { |i| bus.publish("/echo", "0#{i}") }
|
61
61
|
wait_for 4000 do
|
62
62
|
expected_responses.empty?
|
63
63
|
end
|
@@ -84,4 +84,3 @@ describe PUB_SUB_CLASS do
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
87
|
-
end
|
@@ -18,7 +18,7 @@ describe MessageBus::Rack::Middleware do
|
|
18
18
|
use FakeAsyncMiddleware, message_bus: bus
|
19
19
|
use e_m if e_m
|
20
20
|
use MessageBus::Rack::Middleware, message_bus: bus
|
21
|
-
run lambda { |
|
21
|
+
run lambda { |_env| [500, { 'Content-Type' => 'text/html' }, 'should not be called'] }
|
22
22
|
}
|
23
23
|
|
24
24
|
@async_middleware = builder.to_app
|
@@ -62,7 +62,7 @@ describe MessageBus::Rack::Middleware do
|
|
62
62
|
middleware = @async_middleware
|
63
63
|
bus = @bus
|
64
64
|
|
65
|
-
@bus.extra_response_headers_lookup do |
|
65
|
+
@bus.extra_response_headers_lookup do |_env|
|
66
66
|
{ "FOO" => "BAR" }
|
67
67
|
end
|
68
68
|
|
@@ -111,8 +111,20 @@ describe MessageBus::Rack::Middleware do
|
|
111
111
|
include LongPolling
|
112
112
|
end
|
113
113
|
|
114
|
-
describe "
|
114
|
+
describe "start listener" do
|
115
|
+
let(:app) { ->(_) { [200, {}, []] } }
|
116
|
+
|
117
|
+
it "never subscribes" do
|
118
|
+
bus = MessageBus::Instance.new
|
119
|
+
bus.off
|
120
|
+
|
121
|
+
middleware = MessageBus::Rack::Middleware.new(app, message_bus: bus)
|
122
|
+
|
123
|
+
middleware.started_listener.must_equal false
|
124
|
+
end
|
125
|
+
end
|
115
126
|
|
127
|
+
describe "diagnostics" do
|
116
128
|
it "should return a 403 if a user attempts to get at the _diagnostics path" do
|
117
129
|
get "/message-bus/_diagnostics"
|
118
130
|
last_response.status.must_equal 403
|
@@ -130,7 +142,6 @@ describe MessageBus::Rack::Middleware do
|
|
130
142
|
last_response.status.must_equal 200
|
131
143
|
last_response.content_type.must_equal "text/javascript;"
|
132
144
|
end
|
133
|
-
|
134
145
|
end
|
135
146
|
|
136
147
|
describe "polling" do
|
@@ -139,7 +150,7 @@ describe MessageBus::Rack::Middleware do
|
|
139
150
|
end
|
140
151
|
|
141
152
|
it "should include access control headers" do
|
142
|
-
@bus.extra_response_headers_lookup do |
|
153
|
+
@bus.extra_response_headers_lookup do |_env|
|
143
154
|
{ "FOO" => "BAR" }
|
144
155
|
end
|
145
156
|
|
@@ -147,8 +158,8 @@ describe MessageBus::Rack::Middleware do
|
|
147
158
|
|
148
159
|
# client always keeps a list of channels with last message id they got on each
|
149
160
|
post "/message-bus/#{client_id}",
|
150
|
-
|
151
|
-
|
161
|
+
'/foo' => nil,
|
162
|
+
'/bar' => nil
|
152
163
|
|
153
164
|
last_response.headers["FOO"].must_equal "BAR"
|
154
165
|
end
|
@@ -158,8 +169,8 @@ describe MessageBus::Rack::Middleware do
|
|
158
169
|
|
159
170
|
# client always keeps a list of channels with last message id they got on each
|
160
171
|
post "/message-bus/#{client_id}",
|
161
|
-
|
162
|
-
|
172
|
+
'/foo' => nil,
|
173
|
+
'/bar' => nil
|
163
174
|
|
164
175
|
last_response.ok?.must_equal true
|
165
176
|
end
|
@@ -171,9 +182,9 @@ describe MessageBus::Rack::Middleware do
|
|
171
182
|
@bus.publish('/boom', 'bang')
|
172
183
|
|
173
184
|
post "/message-bus/ABCD",
|
174
|
-
|
175
|
-
|
176
|
-
|
185
|
+
'/foo' => 1_000_000,
|
186
|
+
'/baz' => @bus.last_id('/baz') + 1,
|
187
|
+
'/boom' => 1_000_000
|
177
188
|
|
178
189
|
last_response.ok?.must_equal true
|
179
190
|
parsed = JSON.parse(last_response.body)
|
@@ -185,7 +196,6 @@ describe MessageBus::Rack::Middleware do
|
|
185
196
|
end
|
186
197
|
|
187
198
|
it "should correctly understand that -1 means stuff from now onwards" do
|
188
|
-
|
189
199
|
# even if allow chunked
|
190
200
|
@bus.chunked_encoding_enabled = true
|
191
201
|
|
@@ -194,9 +204,9 @@ describe MessageBus::Rack::Middleware do
|
|
194
204
|
@bus.publish('/boom', 'bang')
|
195
205
|
|
196
206
|
post "/message-bus/ABCD",
|
197
|
-
|
198
|
-
|
199
|
-
|
207
|
+
'/foo' => -1,
|
208
|
+
'/baz' => @bus.last_id('/baz') + 1,
|
209
|
+
'/boom' => -1
|
200
210
|
|
201
211
|
last_response.ok?.must_equal true
|
202
212
|
parsed = JSON.parse(last_response.body)
|
@@ -205,7 +215,6 @@ describe MessageBus::Rack::Middleware do
|
|
205
215
|
parsed[0]["channel"].must_equal "/__status"
|
206
216
|
parsed[0]["data"]["/foo"].must_equal @bus.last_id("/foo")
|
207
217
|
parsed[0]["data"]["/boom"].must_equal @bus.last_id("/boom")
|
208
|
-
|
209
218
|
end
|
210
219
|
|
211
220
|
it "should respond with the data if messages exist in the backlog" do
|
@@ -216,8 +225,8 @@ describe MessageBus::Rack::Middleware do
|
|
216
225
|
|
217
226
|
client_id = "ABCD"
|
218
227
|
post "/message-bus/#{client_id}",
|
219
|
-
|
220
|
-
|
228
|
+
'/foo' => id,
|
229
|
+
'/bar' => nil
|
221
230
|
|
222
231
|
parsed = JSON.parse(last_response.body)
|
223
232
|
parsed.length.must_equal 2
|
@@ -226,7 +235,6 @@ describe MessageBus::Rack::Middleware do
|
|
226
235
|
end
|
227
236
|
|
228
237
|
it "should have no cross talk" do
|
229
|
-
|
230
238
|
seq = 0
|
231
239
|
@bus.site_id_lookup do
|
232
240
|
(seq += 1).to_s
|
@@ -237,15 +245,13 @@ describe MessageBus::Rack::Middleware do
|
|
237
245
|
|
238
246
|
# subscribed on channel 2
|
239
247
|
post "/message-bus/ABCD",
|
240
|
-
|
248
|
+
'/foo' => (msg - 1)
|
241
249
|
|
242
250
|
parsed = JSON.parse(last_response.body)
|
243
251
|
parsed.length.must_equal 0
|
244
|
-
|
245
252
|
end
|
246
253
|
|
247
254
|
it "should have global cross talk" do
|
248
|
-
|
249
255
|
seq = 0
|
250
256
|
@bus.site_id_lookup do
|
251
257
|
(seq += 1).to_s
|
@@ -254,7 +260,7 @@ describe MessageBus::Rack::Middleware do
|
|
254
260
|
msg = @bus.publish("/global/foo", "test")
|
255
261
|
|
256
262
|
post "/message-bus/ABCD",
|
257
|
-
|
263
|
+
'/global/foo' => (msg - 1)
|
258
264
|
|
259
265
|
parsed = JSON.parse(last_response.body)
|
260
266
|
parsed.length.must_equal 1
|
@@ -266,7 +272,7 @@ describe MessageBus::Rack::Middleware do
|
|
266
272
|
|
267
273
|
client_id = "ABCD"
|
268
274
|
post "/message-bus/#{client_id}",
|
269
|
-
|
275
|
+
'/foo' => id
|
270
276
|
|
271
277
|
parsed = JSON.parse(last_response.body)
|
272
278
|
parsed.length.must_equal 0
|
@@ -274,13 +280,13 @@ describe MessageBus::Rack::Middleware do
|
|
274
280
|
|
275
281
|
it "should filter by user correctly" do
|
276
282
|
id = @bus.publish("/foo", "test", user_ids: [1])
|
277
|
-
@bus.user_id_lookup do |
|
283
|
+
@bus.user_id_lookup do |_env|
|
278
284
|
0
|
279
285
|
end
|
280
286
|
|
281
287
|
client_id = "ABCD"
|
282
288
|
post "/message-bus/#{client_id}",
|
283
|
-
|
289
|
+
'/foo' => id - 1
|
284
290
|
|
285
291
|
parsed = JSON.parse(last_response.body)
|
286
292
|
parsed.length.must_equal 1
|
@@ -290,12 +296,12 @@ describe MessageBus::Rack::Middleware do
|
|
290
296
|
message["channel"].must_equal "/__status"
|
291
297
|
message["data"].must_equal("/foo" => 1)
|
292
298
|
|
293
|
-
@bus.user_id_lookup do |
|
299
|
+
@bus.user_id_lookup do |_env|
|
294
300
|
1
|
295
301
|
end
|
296
302
|
|
297
303
|
post "/message-bus/#{client_id}",
|
298
|
-
|
304
|
+
'/foo' => id - 1
|
299
305
|
|
300
306
|
parsed = JSON.parse(last_response.body)
|
301
307
|
parsed.length.must_equal 1
|
@@ -303,13 +309,13 @@ describe MessageBus::Rack::Middleware do
|
|
303
309
|
|
304
310
|
it "should filter by group correctly" do
|
305
311
|
id = @bus.publish("/foo", "test", group_ids: [3, 4, 5])
|
306
|
-
@bus.group_ids_lookup do |
|
312
|
+
@bus.group_ids_lookup do |_env|
|
307
313
|
[0, 1, 2]
|
308
314
|
end
|
309
315
|
|
310
316
|
client_id = "ABCD"
|
311
317
|
post "/message-bus/#{client_id}",
|
312
|
-
|
318
|
+
'/foo' => id - 1
|
313
319
|
|
314
320
|
parsed = JSON.parse(last_response.body)
|
315
321
|
message = parsed.first
|
@@ -317,12 +323,12 @@ describe MessageBus::Rack::Middleware do
|
|
317
323
|
message["channel"].must_equal "/__status"
|
318
324
|
message["data"].must_equal("/foo" => 1)
|
319
325
|
|
320
|
-
@bus.group_ids_lookup do |
|
326
|
+
@bus.group_ids_lookup do |_env|
|
321
327
|
[1, 7, 4, 100]
|
322
328
|
end
|
323
329
|
|
324
330
|
post "/message-bus/#{client_id}",
|
325
|
-
|
331
|
+
'/foo' => id - 1
|
326
332
|
|
327
333
|
parsed = JSON.parse(last_response.body)
|
328
334
|
parsed.length.must_equal 1
|
@@ -332,30 +338,28 @@ describe MessageBus::Rack::Middleware do
|
|
332
338
|
id = @bus.last_id('/foo')
|
333
339
|
@bus.publish("/foo", json: true)
|
334
340
|
post("/message-bus/1234",
|
335
|
-
|
336
|
-
|
341
|
+
JSON.generate('/foo' => id),
|
342
|
+
"CONTENT_TYPE" => "application/json")
|
337
343
|
JSON.parse(last_response.body).first["data"].must_equal('json' => true)
|
338
344
|
end
|
339
345
|
|
340
346
|
describe "on_middleware_error handling" do
|
341
347
|
it "allows error handling of middleware failures" do
|
342
|
-
|
343
|
-
@bus.on_middleware_error do |env, err|
|
348
|
+
@bus.on_middleware_error do |_env, err|
|
344
349
|
if ArgumentError === err
|
345
350
|
[407, {}, []]
|
346
351
|
end
|
347
352
|
end
|
348
353
|
|
349
|
-
@bus.group_ids_lookup do |
|
354
|
+
@bus.group_ids_lookup do |_env|
|
350
355
|
raise ArgumentError
|
351
356
|
end
|
352
357
|
|
353
358
|
post("/message-bus/1234",
|
354
|
-
|
355
|
-
|
359
|
+
JSON.generate('/foo' => 1),
|
360
|
+
"CONTENT_TYPE" => "application/json")
|
356
361
|
|
357
362
|
last_response.status.must_equal 407
|
358
|
-
|
359
363
|
end
|
360
364
|
end
|
361
365
|
|
@@ -380,13 +384,13 @@ describe MessageBus::Rack::Middleware do
|
|
380
384
|
bar_id = @bus.publish("/bar", "testbar")
|
381
385
|
|
382
386
|
post "/message-bus/ABCD",
|
383
|
-
|
387
|
+
'/foo' => foo_id - 1
|
384
388
|
|
385
389
|
parsed = JSON.parse(last_response.body)
|
386
390
|
parsed.first['data'].must_equal 'testfoo'
|
387
391
|
|
388
392
|
post "/message-bus/ABCD",
|
389
|
-
|
393
|
+
'/bar' => bar_id - 1
|
390
394
|
|
391
395
|
parsed = JSON.parse(last_response.body)
|
392
396
|
parsed.first['data'].must_equal 'testfoo'
|