message_bus 2.1.6 → 2.2.0.pre
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.
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'
|