message_bus 3.3.6 → 4.0.0

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +3 -2
  3. data/.github/workflows/ci.yml +79 -32
  4. data/.prettierrc +1 -0
  5. data/CHANGELOG +104 -53
  6. data/DEV.md +0 -2
  7. data/Gemfile +0 -27
  8. data/LICENSE +1 -1
  9. data/README.md +40 -62
  10. data/Rakefile +31 -26
  11. data/assets/message-bus-ajax.js +3 -3
  12. data/bench/codecs/marshal.rb +1 -1
  13. data/bench/codecs/packed_string.rb +1 -1
  14. data/docker-compose.yml +1 -1
  15. data/examples/bench/bench.lua +2 -2
  16. data/lib/message_bus/backends/base.rb +8 -3
  17. data/lib/message_bus/backends/memory.rb +6 -0
  18. data/lib/message_bus/backends/postgres.rb +29 -16
  19. data/lib/message_bus/backends/redis.rb +11 -2
  20. data/lib/message_bus/client.rb +6 -7
  21. data/lib/message_bus/connection_manager.rb +1 -1
  22. data/lib/message_bus/distributed_cache.rb +3 -1
  23. data/lib/message_bus/http_client.rb +2 -2
  24. data/lib/message_bus/rack/middleware.rb +6 -6
  25. data/lib/message_bus/rack/thin_ext.rb +2 -1
  26. data/lib/message_bus/version.rb +1 -1
  27. data/lib/message_bus.rb +47 -77
  28. data/message_bus.gemspec +21 -3
  29. data/package-lock.json +1575 -23
  30. data/package.json +9 -7
  31. data/spec/assets/SpecHelper.js +6 -5
  32. data/spec/assets/message-bus.spec.js +9 -6
  33. data/spec/helpers.rb +23 -7
  34. data/spec/integration/http_client_spec.rb +1 -1
  35. data/spec/lib/fake_async_middleware.rb +1 -0
  36. data/spec/lib/message_bus/backend_spec.rb +15 -46
  37. data/spec/lib/message_bus/client_spec.rb +7 -6
  38. data/spec/lib/message_bus/connection_manager_spec.rb +4 -0
  39. data/spec/lib/message_bus/distributed_cache_spec.rb +5 -7
  40. data/spec/lib/message_bus/multi_process_spec.rb +21 -10
  41. data/spec/lib/message_bus/rack/middleware_spec.rb +8 -44
  42. data/spec/lib/message_bus/timer_thread_spec.rb +1 -5
  43. data/spec/lib/message_bus_spec.rb +22 -9
  44. data/spec/performance/publish.rb +4 -4
  45. data/spec/spec_helper.rb +8 -9
  46. data/spec/support/jasmine-browser.json +16 -0
  47. data/vendor/assets/javascripts/message-bus-ajax.js +3 -3
  48. metadata +220 -19
  49. data/assets/application.jsx +0 -121
  50. data/assets/babel.min.js +0 -25
  51. data/assets/react-dom.js +0 -19851
  52. data/assets/react.js +0 -3029
  53. data/examples/diagnostics/Gemfile +0 -6
  54. data/examples/diagnostics/config.ru +0 -22
  55. data/lib/message_bus/diagnostics.rb +0 -62
  56. data/lib/message_bus/rack/diagnostics.rb +0 -98
  57. data/spec/assets/support/jasmine.yml +0 -126
  58. data/spec/assets/support/jasmine_helper.rb +0 -11
data/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "message-bus-client",
3
- "version": "3.3.5",
3
+ "version": "0.0.0-version-placeholder",
4
4
  "description": "A message bus client in Javascript",
5
5
  "main": "assets/message-bus.js",
6
- "keywords": "es6, modules",
6
+ "keywords": [
7
+ "es6",
8
+ "modules"
9
+ ],
7
10
  "files": [
8
11
  "assets/message-bus.js"
9
12
  ],
10
13
  "jsnext:main": "assets/message-bus.js",
11
14
  "module": "assets/message-bus.js",
12
- "repository": {
13
- "type": "git",
14
- "url": "git+https://github.com/discourse/message_bus.git"
15
- },
15
+ "repository": "https://github.com/discourse/message_bus",
16
16
  "author": "Sam Saffron, Robin Ward",
17
17
  "license": "MIT",
18
18
  "bugs": {
@@ -20,6 +20,8 @@
20
20
  },
21
21
  "homepage": "https://github.com/discourse/message_bus#readme",
22
22
  "devDependencies": {
23
- "eslint": "^7.27.0"
23
+ "eslint": "^7.27.0",
24
+ "jasmine-browser-runner": "^0.10.0",
25
+ "jasmine-core": "^3.10.1"
24
26
  }
25
27
  }
@@ -1,3 +1,5 @@
1
+ /* global beforeEach, afterEach, it, spyOn, MessageBus */
2
+
1
3
  var message_id = 1;
2
4
  var SEPARATOR = "\r\n|\r\n";
3
5
 
@@ -12,7 +14,7 @@ var encodeChunks = function(xhr, chunks) {
12
14
  }
13
15
  if (xhr.onprogress){ // using longPoll if onprogress is set
14
16
  var responses = []
15
- for (var i=0;i<chunks.length;i++) {
17
+ for (var j=0;j<chunks.length;j++) {
16
18
  responses.push( JSON.stringify([chunk]) );
17
19
  }
18
20
  return responses.join(SEPARATOR) + SEPARATOR;
@@ -26,7 +28,7 @@ beforeEach(function () {
26
28
 
27
29
  function MockedXMLHttpRequest(){
28
30
  this.headers = {};
29
- };
31
+ }
30
32
 
31
33
  MockedXMLHttpRequest.prototype.send = function(){
32
34
  this.readyState = 4
@@ -75,8 +77,8 @@ window.testMB = function(description, testFn, path, data){
75
77
  {channel: path || '/test', data: data || {password: 'MessageBusRocks!'}}
76
78
  ];
77
79
  it(description, function(done){
78
- spec = this;
79
- promisy = {
80
+ var spec = this;
81
+ var promisy = {
80
82
  finally: function(fn){
81
83
  this.resolve = fn;
82
84
  }
@@ -105,4 +107,3 @@ window.testMB = function(description, testFn, path, data){
105
107
  });
106
108
 
107
109
  }
108
-
@@ -1,3 +1,5 @@
1
+ /* global describe, it, spyOn, MessageBus, expect, jasmine, testMB */
2
+
1
3
  describe("Messagebus", function() {
2
4
 
3
5
  it("submits change requests", function(done){
@@ -6,10 +8,11 @@ describe("Messagebus", function() {
6
8
  MessageBus.subscribe('/test', function(){
7
9
  expect(spec.MockedXMLHttpRequest.prototype.send)
8
10
  .toHaveBeenCalled()
9
- var req = JSON.parse(spec.MockedXMLHttpRequest.prototype.send.calls.argsFor(0)[0]);
10
- expect(req['/test']).toEqual(-1)
11
- expect(req['__seq']).not.toBeUndefined();
12
- done()
11
+ var data = spec.MockedXMLHttpRequest.prototype.send.calls.argsFor(0)[0];
12
+ var params = new URLSearchParams(data);
13
+ expect(params.get("/test")).toEqual("-1");
14
+ expect(params.get("__seq")).toMatch(/\d+/);
15
+ done();
13
16
  });
14
17
  });
15
18
 
@@ -57,7 +60,7 @@ describe("Messagebus", function() {
57
60
  });
58
61
  });
59
62
 
60
- testMB('sets dlp paramater when longPolling is disabled', function(){
63
+ testMB('sets dlp parameter when longPolling is disabled', function(){
61
64
  MessageBus.enableLongPolling = false
62
65
  this.perform(function(message, xhr){
63
66
  expect(xhr.url).toMatch("dlp=t");
@@ -87,7 +90,7 @@ describe("Messagebus", function() {
87
90
  expect(xhr.headers).toEqual({
88
91
  'X-SILENCE-LOGGER': 'true',
89
92
  'X-MB-TEST-VALUE': '42',
90
- 'Content-Type': 'application/json'
93
+ 'Content-Type': 'application/x-www-form-urlencoded'
91
94
  });
92
95
  }).finally(function(){
93
96
  MessageBus.headers = {};
data/spec/helpers.rb CHANGED
@@ -1,20 +1,36 @@
1
1
  # frozen_string_literal: true
2
- def wait_for(timeout_milliseconds = 2000)
3
- timeout = (timeout_milliseconds + 0.0) / 1000
2
+
3
+ require 'logger'
4
+ require 'method_source'
5
+
6
+ def wait_for(timeout_milliseconds = 2000, &blk)
7
+ timeout = timeout_milliseconds / 1000.0
4
8
  finish = Time.now + timeout
9
+ result = nil
5
10
 
6
- Thread.new do
7
- sleep(0.001) while Time.now < finish && !yield
8
- end.join
11
+ while Time.now < finish && !(result = blk.call)
12
+ sleep(0.001)
13
+ end
14
+
15
+ flunk("wait_for timed out:\n#{blk.source}") if !result
9
16
  end
10
17
 
11
18
  def test_config_for_backend(backend)
12
- config = { backend: backend }
19
+ config = {
20
+ backend: backend,
21
+ logger: Logger.new(IO::NULL),
22
+ }
23
+
13
24
  case backend
14
25
  when :redis
15
26
  config[:url] = ENV['REDISURL']
16
27
  when :postgres
17
- config[:backend_options] = { host: ENV['PGHOST'], user: ENV['PGUSER'] || ENV['USER'], password: ENV['PGPASSWORD'], dbname: ENV['PGDATABASE'] || 'message_bus_test' }
28
+ config[:backend_options] = {
29
+ host: ENV['PGHOST'],
30
+ user: ENV['PGUSER'] || ENV['USER'],
31
+ password: ENV['PGPASSWORD'],
32
+ dbname: ENV['PGDATABASE'] || 'message_bus_test'
33
+ }
18
34
  end
19
35
  config
20
36
  end
@@ -71,7 +71,7 @@ describe MessageBus::HTTPClient do
71
71
  # that we sleep for the right interval after failure
72
72
  sleep 0.5
73
73
 
74
- assert_equal(1, fake.string.scan("Errno::ECONNREFUSED").size)
74
+ assert_match(/Errno::ECONNREFUSED|SocketError/, fake.string)
75
75
  ensure
76
76
  $stderr = original_stderr
77
77
  end
@@ -7,6 +7,7 @@ class FakeAsyncMiddleware
7
7
  @simulate_thin_async = false
8
8
  @simulate_hijack = false
9
9
  @in_async = false
10
+ @allow_chunked = false
10
11
  end
11
12
 
12
13
  def app
@@ -3,19 +3,19 @@
3
3
  require_relative '../../spec_helper'
4
4
  require 'message_bus'
5
5
 
6
- describe PUB_SUB_CLASS do
7
- def new_test_bus
8
- PUB_SUB_CLASS.new(MESSAGE_BUS_CONFIG)
6
+ describe BACKEND_CLASS do
7
+ before do
8
+ @bus = BACKEND_CLASS.new(test_config_for_backend(CURRENT_BACKEND))
9
9
  end
10
10
 
11
- before do
12
- @bus = new_test_bus
11
+ after do
13
12
  @bus.reset!
13
+ @bus.destroy
14
14
  end
15
15
 
16
16
  describe "API parity" do
17
17
  it "has the same public methods as the base class" do
18
- @bus.public_methods.sort.must_equal MessageBus::Backends::Base.new(MESSAGE_BUS_CONFIG).public_methods.sort
18
+ @bus.public_methods.sort.must_equal MessageBus::Backends::Base.new(test_config_for_backend(CURRENT_BACKEND)).public_methods.sort
19
19
  end
20
20
  end
21
21
 
@@ -30,7 +30,7 @@ describe PUB_SUB_CLASS do
30
30
  end
31
31
 
32
32
  it "should initialize with max_backlog_size" do
33
- PUB_SUB_CLASS.new({}, 2000).max_backlog_size.must_equal 2000
33
+ BACKEND_CLASS.new({}, 2000).max_backlog_size.must_equal 2000
34
34
  end
35
35
 
36
36
  it "should truncate channels correctly" do
@@ -77,7 +77,7 @@ describe PUB_SUB_CLASS do
77
77
  end
78
78
 
79
79
  threads.each(&:join)
80
- @bus.backlog("/foo").length == 100
80
+ @bus.backlog("/foo").length.must_equal 100
81
81
  end
82
82
 
83
83
  it "should be able to encode and decode messages properly" do
@@ -91,37 +91,6 @@ describe PUB_SUB_CLASS do
91
91
  @bus.last_id("/foo").must_equal 1
92
92
  end
93
93
 
94
- describe "readonly" do
95
- after do
96
- @bus.pub_redis.slaveof "no", "one"
97
- end
98
-
99
- it "should be able to store messages in memory for a period while in read only" do
100
- test_only :redis
101
- skip "This spec changes redis behavior that in turn means other specs run slow"
102
-
103
- @bus.pub_redis.slaveof "127.0.0.80", "666"
104
- @bus.max_in_memory_publish_backlog = 2
105
-
106
- current_threads = Thread.list
107
- current_threads_length = current_threads.count
108
-
109
- 3.times do
110
- result = @bus.publish "/foo", "bar"
111
- assert_nil result
112
- Thread.list.length.must_equal(current_threads_length + 1)
113
- end
114
-
115
- @bus.pub_redis.slaveof "no", "one"
116
- sleep 0.01
117
-
118
- (Thread.list - current_threads).each(&:join)
119
- Thread.list.length.must_equal current_threads_length
120
-
121
- @bus.backlog("/foo", 0).map(&:data).must_equal ["bar", "bar"]
122
- end
123
- end
124
-
125
94
  it "can set backlog age" do
126
95
  @bus.max_backlog_age = 1
127
96
 
@@ -137,7 +106,7 @@ describe PUB_SUB_CLASS do
137
106
  sleep 1.25 # Should now be at time =~ 1.25s. Our backlog should have expired by now.
138
107
  expected_backlog_size = 0
139
108
 
140
- case MESSAGE_BUS_CONFIG[:backend]
109
+ case CURRENT_BACKEND
141
110
  when :postgres
142
111
  # Force triggering backlog expiry: postgres backend doesn't expire backlogs on a timer, but at publication time.
143
112
  @bus.global_backlog.length.wont_equal expected_backlog_size
@@ -161,7 +130,7 @@ describe PUB_SUB_CLASS do
161
130
  @bus.publish "/foo", "baz" # Publish something else to ward off another expiry
162
131
  expected_backlog_size += 1
163
132
 
164
- case MESSAGE_BUS_CONFIG[:backend]
133
+ case CURRENT_BACKEND
165
134
  when :postgres
166
135
  # Postgres expires individual messages that have lived longer than the TTL, not whole backlogs
167
136
  expected_backlog_size -= 1
@@ -189,7 +158,7 @@ describe PUB_SUB_CLASS do
189
158
  sleep 1.25 # Should now be at time =~ 1.25s. Our backlog should have expired by now.
190
159
  expected_backlog_size = 0
191
160
 
192
- case MESSAGE_BUS_CONFIG[:backend]
161
+ case CURRENT_BACKEND
193
162
  when :postgres
194
163
  # Force triggering backlog expiry: postgres backend doesn't expire backlogs on a timer, but at publication time.
195
164
  @bus.global_backlog.length.wont_equal expected_backlog_size
@@ -204,7 +173,7 @@ describe PUB_SUB_CLASS do
204
173
 
205
174
  # for the time being we can give pg a pass here
206
175
  # TODO: make the implementation here consistent
207
- if MESSAGE_BUS_CONFIG[:backend] != :postgres
176
+ if CURRENT_BACKEND != :postgres
208
177
  # ids are not opaque we expect them to be reset on our channel if it
209
178
  # got cleared due to an expire, the reason for this is cause we will leak entries due to tracking
210
179
  # this in turn can bloat storage for the backend
@@ -222,7 +191,7 @@ describe PUB_SUB_CLASS do
222
191
  @bus.publish "/foo", "baz", max_backlog_age: 1 # Publish something else to ward off another expiry
223
192
  expected_backlog_size += 1
224
193
 
225
- case MESSAGE_BUS_CONFIG[:backend]
194
+ case CURRENT_BACKEND
226
195
  when :postgres
227
196
  # Postgres expires individual messages that have lived longer than the TTL, not whole backlogs
228
197
  expected_backlog_size -= 1
@@ -249,7 +218,7 @@ describe PUB_SUB_CLASS do
249
218
  @bus.publish "/foo", "baz"
250
219
  @bus.publish "/hello", "planet"
251
220
 
252
- expected_messages = case MESSAGE_BUS_CONFIG[:backend]
221
+ expected_messages = case CURRENT_BACKEND
253
222
  when :redis
254
223
  # Redis has channel-specific message IDs
255
224
  [
@@ -277,7 +246,7 @@ describe PUB_SUB_CLASS do
277
246
  @bus.publish "/bar", "a1"
278
247
  @bus.publish "/bar", "b1"
279
248
 
280
- expected_messages = case MESSAGE_BUS_CONFIG[:backend]
249
+ expected_messages = case CURRENT_BACKEND
281
250
  when :redis
282
251
  # Redis has channel-specific message IDs
283
252
  [
@@ -11,11 +11,12 @@ describe MessageBus::Client do
11
11
 
12
12
  before do
13
13
  @bus = MessageBus::Instance.new
14
- @bus.configure(MESSAGE_BUS_CONFIG)
14
+ @bus.configure(test_config_for_backend(CURRENT_BACKEND))
15
15
  @client = setup_client('abc')
16
16
  end
17
17
 
18
18
  after do
19
+ @client.close
19
20
  @bus.reset!
20
21
  @bus.destroy
21
22
  end
@@ -98,7 +99,7 @@ describe MessageBus::Client do
98
99
  chunk2.length.must_equal 0
99
100
  end
100
101
 
101
- it "does not bleed data accross sites" do
102
+ it "does not bleed data across sites" do
102
103
  @client.site_id = "test"
103
104
 
104
105
  @client.subscribe('/hello', nil)
@@ -107,7 +108,7 @@ describe MessageBus::Client do
107
108
  log.length.must_equal 0
108
109
  end
109
110
 
110
- it "does not bleed status accross sites" do
111
+ it "does not bleed status across sites" do
111
112
  @client.site_id = "test"
112
113
 
113
114
  @client.subscribe('/hello', -1)
@@ -190,7 +191,7 @@ describe MessageBus::Client do
190
191
  @client.allowed?(@message).must_equal true
191
192
  end
192
193
 
193
- describe 'targetted at user' do
194
+ describe 'targeted at user' do
194
195
  before do
195
196
  @message = MessageBus::Message.new(1, 2, '/test', 'hello')
196
197
  @message.user_ids = [1, 2, 3]
@@ -241,7 +242,7 @@ describe MessageBus::Client do
241
242
  end
242
243
  end
243
244
 
244
- describe "targetted at group" do
245
+ describe "targeted at group" do
245
246
  before do
246
247
  @message = MessageBus::Message.new(1, 2, '/test', 'hello')
247
248
  @message.group_ids = [1, 2, 3]
@@ -291,7 +292,7 @@ describe MessageBus::Client do
291
292
  end
292
293
  end
293
294
 
294
- describe 'targetted at group and user' do
295
+ describe 'targeted at group and user' do
295
296
  before do
296
297
  @message = MessageBus::Message.new(1, 2, '/test', 'hello')
297
298
  @message.group_ids = [1, 2, 3]
@@ -6,6 +6,10 @@ require 'message_bus'
6
6
  class FakeAsync
7
7
  attr_accessor :cleanup_timer
8
8
 
9
+ def initialize
10
+ @sent = nil
11
+ end
12
+
9
13
  def <<(val)
10
14
  sleep 0.01 # simulate IO
11
15
  @sent ||= +""
@@ -6,13 +6,16 @@ require 'message_bus'
6
6
  require 'message_bus/distributed_cache'
7
7
 
8
8
  describe MessageBus::DistributedCache do
9
- before :all do
9
+ before do
10
10
  @bus = MessageBus::Instance.new
11
11
  @bus.configure(backend: :memory)
12
12
  @manager = MessageBus::DistributedCache::Manager.new(@bus)
13
+ @cache1 = cache(cache_name)
14
+ @cache2 = cache(cache_name)
13
15
  end
14
16
 
15
- after :all do
17
+ after do
18
+ @bus.reset!
16
19
  @bus.destroy
17
20
  end
18
21
 
@@ -24,11 +27,6 @@ describe MessageBus::DistributedCache do
24
27
  SecureRandom.hex
25
28
  end
26
29
 
27
- before do
28
- @cache1 = cache(cache_name)
29
- @cache2 = cache(cache_name)
30
- end
31
-
32
30
  it 'supports arrays with hashes' do
33
31
  c1 = cache("test1")
34
32
  c2 = cache("test1")
@@ -3,7 +3,7 @@
3
3
  require_relative '../../spec_helper'
4
4
  require 'message_bus'
5
5
 
6
- describe PUB_SUB_CLASS do
6
+ describe BACKEND_CLASS do
7
7
  def self.error!
8
8
  @error = true
9
9
  end
@@ -13,18 +13,20 @@ describe PUB_SUB_CLASS do
13
13
  end
14
14
 
15
15
  def new_bus
16
- PUB_SUB_CLASS.new(MESSAGE_BUS_CONFIG.merge(db: 10))
16
+ BACKEND_CLASS.new(test_config_for_backend(CURRENT_BACKEND).merge(db: 10))
17
17
  end
18
18
 
19
19
  def work_it
20
20
  bus = new_bus
21
- $stdout.reopen("/dev/null", "w")
22
- $stderr.reopen("/dev/null", "w")
23
- # subscribe blocks, so we need a new bus to transmit
24
- new_bus.subscribe("/echo", 0) do |msg|
25
- bus.publish("/response", "#{msg.data}-#{Process.pid.to_s}")
21
+ bus.subscribe("/echo", 0) do |msg|
22
+ if msg.data == "done"
23
+ bus.global_unsubscribe
24
+ else
25
+ bus.publish("/response", "#{msg.data}-#{Process.pid.to_s}")
26
+ end
26
27
  end
27
28
  ensure
29
+ bus.destroy
28
30
  exit!(0)
29
31
  end
30
32
 
@@ -44,12 +46,14 @@ describe PUB_SUB_CLASS do
44
46
  test_never :memory
45
47
  skip("previous error") if self.class.error?
46
48
  GC.start
47
- new_bus.reset!
49
+ bus = new_bus
50
+ bus.reset!
51
+
48
52
  begin
49
53
  pids = (1..10).map { spawn_child }
50
54
  expected_responses = pids.map { |x| (0...10).map { |i| "0#{i}-#{x}" } }.flatten
51
55
  unexpected_responses = []
52
- bus = new_bus
56
+
53
57
  t = Thread.new do
54
58
  bus.subscribe("/response", 0) do |msg|
55
59
  if expected_responses.include?(msg.data)
@@ -59,10 +63,14 @@ describe PUB_SUB_CLASS do
59
63
  end
60
64
  end
61
65
  end
66
+
62
67
  10.times { |i| bus.publish("/echo", "0#{i}") }
63
- wait_for 4000 do
68
+
69
+ wait_for(2000) do
64
70
  expected_responses.empty?
65
71
  end
72
+
73
+ bus.publish("/echo", "done")
66
74
  bus.global_unsubscribe
67
75
  t.join
68
76
 
@@ -81,7 +89,10 @@ describe PUB_SUB_CLASS do
81
89
  Process.wait(pid)
82
90
  end
83
91
  end
92
+
84
93
  bus.global_unsubscribe
94
+ bus.reset!
95
+ bus.destroy
85
96
  end
86
97
  end
87
98
  end
@@ -12,7 +12,7 @@ describe MessageBus::Rack::Middleware do
12
12
 
13
13
  before do
14
14
  bus = @bus = MessageBus::Instance.new
15
- @bus.configure(MESSAGE_BUS_CONFIG)
15
+ @bus.configure(test_config_for_backend(CURRENT_BACKEND))
16
16
  @bus.long_polling_enabled = false
17
17
  @bus.base_route = base_route if base_route
18
18
 
@@ -26,7 +26,6 @@ describe MessageBus::Rack::Middleware do
26
26
 
27
27
  @async_middleware = builder.to_app
28
28
  @message_bus_middleware = @async_middleware.app
29
- @bus.reset!
30
29
  end
31
30
 
32
31
  after do
@@ -84,7 +83,7 @@ describe MessageBus::Rack::Middleware do
84
83
  { "FOO" => "BAR" }
85
84
  end
86
85
 
87
- Thread.new do
86
+ t = Thread.new do
88
87
  wait_for(2000) { middleware.in_async? }
89
88
  bus.publish "/foo", "םוֹלשָׁ"
90
89
  end
@@ -97,6 +96,7 @@ describe MessageBus::Rack::Middleware do
97
96
  parsed[0]["data"].must_equal "םוֹלשָׁ"
98
97
 
99
98
  last_response.headers["FOO"].must_equal "BAR"
99
+ t.join
100
100
  end
101
101
 
102
102
  it "should timeout within its alloted slot" do
@@ -142,47 +142,6 @@ describe MessageBus::Rack::Middleware do
142
142
  end
143
143
  end
144
144
 
145
- describe "diagnostics" do
146
- it "should return a 403 if a user attempts to get at the _diagnostics path" do
147
- get "/message-bus/_diagnostics"
148
- last_response.status.must_equal 403
149
- end
150
-
151
- it "should get a 200 with html for an authorized user" do
152
-
153
- def @bus.is_admin_lookup
154
- proc { |_| true }
155
- end
156
-
157
- get "/message-bus/_diagnostics"
158
- last_response.status.must_equal 200
159
- end
160
-
161
- describe "with an altered base_route" do
162
- let(:base_route) { "/base/route/" }
163
-
164
- it "should get a 200 with html for an authorized user" do
165
- def @bus.is_admin_lookup
166
- proc { |_| true }
167
- end
168
-
169
- get "/base/route/message-bus/_diagnostics"
170
- last_response.status.must_equal 200
171
- end
172
- end
173
-
174
- it "should get the script it asks for" do
175
-
176
- def @bus.is_admin_lookup
177
- proc { |_| true }
178
- end
179
-
180
- get "/message-bus/_diagnostics/assets/message-bus.js"
181
- last_response.status.must_equal 200
182
- last_response.content_type.must_equal "application/javascript;charset=UTF-8"
183
- end
184
- end
185
-
186
145
  describe "polling" do
187
146
  before do
188
147
  @bus.long_polling_enabled = false
@@ -414,6 +373,11 @@ describe MessageBus::Rack::Middleware do
414
373
  JSON.parse(last_response.body).first["data"].must_equal('json' => true)
415
374
  end
416
375
 
376
+ it "should tell Rack to skip committing the session" do
377
+ post "/message-bus/1234", {}, { "rack.session.options" => {} }
378
+ last_request.env["rack.session.options"][:skip].must_equal true
379
+ end
380
+
417
381
  describe "on_middleware_error handling" do
418
382
  it "allows error handling of middleware failures" do
419
383
  @bus.on_middleware_error do |_env, err|
@@ -52,10 +52,6 @@ describe MessageBus::TimerThread do
52
52
  it "should call the error callback if something goes wrong" do
53
53
  error = nil
54
54
 
55
- @timer.queue do
56
- boom
57
- end
58
-
59
55
  @timer.on_error do |e|
60
56
  error = e
61
57
  end
@@ -64,7 +60,7 @@ describe MessageBus::TimerThread do
64
60
  boom
65
61
  end
66
62
 
67
- wait_for(10) do
63
+ wait_for(100) do
68
64
  error
69
65
  end
70
66