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
@@ -1,271 +0,0 @@
|
|
1
|
-
require_relative '../../../spec_helper'
|
2
|
-
require 'message_bus'
|
3
|
-
|
4
|
-
if MESSAGE_BUS_CONFIG[:backend] == :redis
|
5
|
-
describe PUB_SUB_CLASS do
|
6
|
-
|
7
|
-
def new_test_bus
|
8
|
-
PUB_SUB_CLASS.new(MESSAGE_BUS_CONFIG.merge(db: 10))
|
9
|
-
end
|
10
|
-
|
11
|
-
before do
|
12
|
-
@bus = new_test_bus
|
13
|
-
@bus.reset!
|
14
|
-
end
|
15
|
-
|
16
|
-
describe "readonly" do
|
17
|
-
|
18
|
-
after do
|
19
|
-
@bus.pub_redis.slaveof "no", "one"
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should be able to store messages in memory for a period while in read only" do
|
23
|
-
|
24
|
-
skip "This spec changes redis behavior that in turn means other specs run slow"
|
25
|
-
|
26
|
-
@bus.pub_redis.slaveof "127.0.0.80", "666"
|
27
|
-
@bus.max_in_memory_publish_backlog = 2
|
28
|
-
|
29
|
-
current_threads = Thread.list
|
30
|
-
current_threads_length = current_threads.count
|
31
|
-
|
32
|
-
3.times do
|
33
|
-
result = @bus.publish "/foo", "bar"
|
34
|
-
assert_nil result
|
35
|
-
Thread.list.length.must_equal (current_threads_length + 1)
|
36
|
-
end
|
37
|
-
|
38
|
-
@bus.pub_redis.slaveof "no", "one"
|
39
|
-
sleep 0.01
|
40
|
-
|
41
|
-
(Thread.list - current_threads).each(&:join)
|
42
|
-
Thread.list.length.must_equal current_threads_length
|
43
|
-
|
44
|
-
@bus.backlog("/foo", 0).map(&:data).must_equal ["bar", "bar"]
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
it "can set backlog age" do
|
49
|
-
@bus.max_backlog_age = 100
|
50
|
-
@bus.publish "/foo", "bar"
|
51
|
-
@bus.pub_redis.ttl(@bus.backlog_key("/foo")).must_be :<=, 100
|
52
|
-
@bus.pub_redis.ttl(@bus.backlog_key("/foo")).must_be :>, 0
|
53
|
-
end
|
54
|
-
|
55
|
-
it "can set backlog age on publish" do
|
56
|
-
@bus.max_backlog_age = 100
|
57
|
-
|
58
|
-
@bus.publish "/foo", "bar", max_backlog_age: 50
|
59
|
-
@bus.pub_redis.ttl(@bus.backlog_key("/foo")).must_be :<=, 50
|
60
|
-
@bus.pub_redis.ttl(@bus.backlog_key("/foo")).must_be :>, 0
|
61
|
-
end
|
62
|
-
|
63
|
-
it "can set backlog size on publish" do
|
64
|
-
@bus.max_backlog_size = 100
|
65
|
-
|
66
|
-
@bus.publish "/foo", "bar", max_backlog_size: 2
|
67
|
-
@bus.publish "/foo", "bar", max_backlog_size: 2
|
68
|
-
@bus.publish "/foo", "bar", max_backlog_size: 2
|
69
|
-
|
70
|
-
@bus.backlog("/foo").length.must_equal 2
|
71
|
-
end
|
72
|
-
|
73
|
-
it "should be able to access the backlog" do
|
74
|
-
@bus.publish "/foo", "bar"
|
75
|
-
@bus.publish "/foo", "baz"
|
76
|
-
|
77
|
-
@bus.backlog("/foo", 0).to_a.must_equal [
|
78
|
-
MessageBus::Message.new(1, 1, '/foo', 'bar'),
|
79
|
-
MessageBus::Message.new(2, 2, '/foo', 'baz')
|
80
|
-
]
|
81
|
-
end
|
82
|
-
|
83
|
-
it "should initialize with max_backlog_size" do
|
84
|
-
PUB_SUB_CLASS.new({}, 2000).max_backlog_size.must_equal 2000
|
85
|
-
end
|
86
|
-
|
87
|
-
it "should truncate channels correctly" do
|
88
|
-
@bus.max_backlog_size = 2
|
89
|
-
4.times do |t|
|
90
|
-
@bus.publish "/foo", t.to_s
|
91
|
-
end
|
92
|
-
|
93
|
-
@bus.backlog("/foo").to_a.must_equal [
|
94
|
-
MessageBus::Message.new(3, 3, '/foo', '2'),
|
95
|
-
MessageBus::Message.new(4, 4, '/foo', '3'),
|
96
|
-
]
|
97
|
-
end
|
98
|
-
|
99
|
-
it "should truncate global backlog correctly" do
|
100
|
-
@bus.max_global_backlog_size = 2
|
101
|
-
@bus.publish "/foo", "1"
|
102
|
-
@bus.publish "/bar", "2"
|
103
|
-
@bus.publish "/baz", "3"
|
104
|
-
|
105
|
-
@bus.global_backlog.length.must_equal 2
|
106
|
-
end
|
107
|
-
|
108
|
-
it "should be able to grab a message by id" do
|
109
|
-
id1 = @bus.publish "/foo", "bar"
|
110
|
-
id2 = @bus.publish "/foo", "baz"
|
111
|
-
@bus.get_message("/foo", id2).must_equal MessageBus::Message.new(2, 2, "/foo", "baz")
|
112
|
-
@bus.get_message("/foo", id1).must_equal MessageBus::Message.new(1, 1, "/foo", "bar")
|
113
|
-
end
|
114
|
-
|
115
|
-
it "should be able to access the global backlog" do
|
116
|
-
@bus.publish "/foo", "bar"
|
117
|
-
@bus.publish "/hello", "world"
|
118
|
-
@bus.publish "/foo", "baz"
|
119
|
-
@bus.publish "/hello", "planet"
|
120
|
-
|
121
|
-
@bus.global_backlog.to_a.must_equal [
|
122
|
-
MessageBus::Message.new(1, 1, "/foo", "bar"),
|
123
|
-
MessageBus::Message.new(2, 1, "/hello", "world"),
|
124
|
-
MessageBus::Message.new(3, 2, "/foo", "baz"),
|
125
|
-
MessageBus::Message.new(4, 2, "/hello", "planet")
|
126
|
-
]
|
127
|
-
end
|
128
|
-
|
129
|
-
it "should correctly omit dropped messages from the global backlog" do
|
130
|
-
@bus.max_backlog_size = 1
|
131
|
-
@bus.publish "/foo", "a"
|
132
|
-
@bus.publish "/foo", "b"
|
133
|
-
@bus.publish "/bar", "a"
|
134
|
-
@bus.publish "/bar", "b"
|
135
|
-
|
136
|
-
@bus.global_backlog.to_a.must_equal [
|
137
|
-
MessageBus::Message.new(2, 2, "/foo", "b"),
|
138
|
-
MessageBus::Message.new(4, 2, "/bar", "b")
|
139
|
-
]
|
140
|
-
end
|
141
|
-
|
142
|
-
it "should have the correct number of messages for multi threaded access" do
|
143
|
-
threads = []
|
144
|
-
4.times do
|
145
|
-
threads << Thread.new do
|
146
|
-
bus = new_test_bus
|
147
|
-
25.times {
|
148
|
-
bus.publish "/foo", "."
|
149
|
-
}
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
threads.each(&:join)
|
154
|
-
@bus.backlog("/foo").length == 100
|
155
|
-
end
|
156
|
-
|
157
|
-
it "should be able to subscribe globally with recovery" do
|
158
|
-
@bus.publish("/foo", "1")
|
159
|
-
@bus.publish("/bar", "2")
|
160
|
-
got = []
|
161
|
-
|
162
|
-
t = Thread.new do
|
163
|
-
new_test_bus.global_subscribe(0) do |msg|
|
164
|
-
got << msg
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
@bus.publish("/bar", "3")
|
169
|
-
|
170
|
-
wait_for(100) do
|
171
|
-
got.length == 3
|
172
|
-
end
|
173
|
-
|
174
|
-
t.kill
|
175
|
-
|
176
|
-
got.length.must_equal 3
|
177
|
-
got.map { |m| m.data }.must_equal ["1", "2", "3"]
|
178
|
-
end
|
179
|
-
|
180
|
-
it "should be able to encode and decode messages properly" do
|
181
|
-
m = MessageBus::Message.new 1, 2, '||', '||'
|
182
|
-
MessageBus::Message.decode(m.encode).must_equal m
|
183
|
-
end
|
184
|
-
|
185
|
-
it "should handle subscribe on single channel, with recovery" do
|
186
|
-
@bus.publish("/foo", "1")
|
187
|
-
@bus.publish("/bar", "2")
|
188
|
-
got = []
|
189
|
-
|
190
|
-
t = Thread.new do
|
191
|
-
new_test_bus.subscribe("/foo", 0) do |msg|
|
192
|
-
got << msg
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
@bus.publish("/foo", "3")
|
197
|
-
|
198
|
-
wait_for(100) do
|
199
|
-
got.length == 2
|
200
|
-
end
|
201
|
-
|
202
|
-
t.kill
|
203
|
-
|
204
|
-
got.map { |m| m.data }.must_equal ["1", "3"]
|
205
|
-
end
|
206
|
-
|
207
|
-
it "should not get backlog if subscribe is called without params" do
|
208
|
-
@bus.publish("/foo", "1")
|
209
|
-
got = []
|
210
|
-
|
211
|
-
t = Thread.new do
|
212
|
-
new_test_bus.subscribe("/foo") do |msg|
|
213
|
-
got << msg
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
# sleep 50ms to allow the bus to correctly subscribe,
|
218
|
-
# I thought about adding a subscribed callback, but outside of testing it matters less
|
219
|
-
sleep 0.05
|
220
|
-
|
221
|
-
@bus.publish("/foo", "2")
|
222
|
-
|
223
|
-
wait_for(100) do
|
224
|
-
got.length == 1
|
225
|
-
end
|
226
|
-
|
227
|
-
t.kill
|
228
|
-
|
229
|
-
got.map { |m| m.data }.must_equal ["2"]
|
230
|
-
end
|
231
|
-
|
232
|
-
it "should cope with a redis reset cleanly" do
|
233
|
-
|
234
|
-
@bus.publish("/foo", "1")
|
235
|
-
got = []
|
236
|
-
|
237
|
-
t = Thread.new do
|
238
|
-
new_test_bus.subscribe("/foo") do |msg|
|
239
|
-
got << msg
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
# sleep 50ms to allow the bus to correctly subscribe,
|
244
|
-
# I thought about adding a subscribed callback, but outside of testing it matters less
|
245
|
-
sleep 0.05
|
246
|
-
|
247
|
-
@bus.publish("/foo", "2")
|
248
|
-
|
249
|
-
@bus.pub_redis.flushdb
|
250
|
-
|
251
|
-
@bus.publish("/foo", "3")
|
252
|
-
|
253
|
-
wait_for(100) do
|
254
|
-
got.length == 2
|
255
|
-
end
|
256
|
-
|
257
|
-
t.kill
|
258
|
-
|
259
|
-
got.map { |m| m.data }.must_equal ["2", "3"]
|
260
|
-
got[1].global_id.must_equal 1
|
261
|
-
|
262
|
-
end
|
263
|
-
|
264
|
-
it "should allow us to get last id on a channel" do
|
265
|
-
@bus.last_id("/foo").must_equal 0
|
266
|
-
@bus.publish("/foo", "1")
|
267
|
-
@bus.last_id("/foo").must_equal 1
|
268
|
-
end
|
269
|
-
|
270
|
-
end
|
271
|
-
end
|