message_bus 1.1.1 → 2.0.0.beta.1

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.

@@ -79,51 +79,12 @@ describe MessageBus::Rack::Middleware do
79
79
  @bus.long_polling_interval = 10
80
80
  s = Time.now.to_f * 1000
81
81
  post "/message-bus/ABC", '/foo' => nil
82
- (Time.now.to_f * 1000 - s).should < 30
82
+ # allow for some jitter
83
+ (Time.now.to_f * 1000 - s).should < 50
83
84
  ensure
84
85
  @bus.long_polling_interval = 5000
85
86
  end
86
87
  end
87
-
88
- it "should support batch filtering" do
89
- bus = @bus
90
- async_middleware = @async_middleware
91
-
92
- bus.user_id_lookup do |env|
93
- 1
94
- end
95
-
96
- bus.around_client_batch("/demo") do |message, user_ids, callback|
97
- begin
98
- Thread.current["test"] = user_ids
99
- callback.call
100
- ensure
101
- Thread.current["test"] = nil
102
- end
103
- end
104
-
105
- test = nil
106
-
107
- bus.client_filter("/demo") do |user_id, message|
108
- test = Thread.current["test"]
109
- message
110
- end
111
-
112
- client_id = "ABCD"
113
-
114
- id = bus.publish("/demo", "test")
115
-
116
- Thread.new do
117
- wait_for(2000) { async_middleware.in_async? }
118
- bus.publish "/demo", "test"
119
- end
120
-
121
- post "/message-bus/#{client_id}", {
122
- '/demo' => id
123
- }
124
-
125
- test.should == [1]
126
- end
127
88
  end
128
89
 
129
90
  describe "thin async" do
@@ -304,54 +265,6 @@ describe MessageBus::Rack::Middleware do
304
265
  parsed.length.should == 1
305
266
  end
306
267
 
307
-
308
- it "should filter by client_filter correctly" do
309
- id = @bus.publish("/filter", "test")
310
- uid = 0
311
-
312
- @bus.user_id_lookup do |env|
313
- uid
314
- end
315
-
316
- @bus.client_filter("/filter") do |user_id, message|
317
- if user_id == 0
318
- message = message.dup
319
- message.data += "_filter"
320
- message
321
- elsif user_id == 1
322
- message
323
- end
324
- end
325
-
326
- client_id = "ABCD"
327
-
328
- post "/message-bus/#{client_id}", {
329
- '/filter' => id - 1
330
- }
331
-
332
- parsed = JSON.parse(last_response.body)
333
- parsed[0]['data'].should == "test_filter"
334
-
335
- uid = 1
336
-
337
- post "/message-bus/#{client_id}", {
338
- '/filter' => id - 1
339
- }
340
-
341
- parsed = JSON.parse(last_response.body)
342
- parsed.length.should == 1
343
- parsed[0]["data"].should == "test"
344
-
345
- uid = 2
346
-
347
- post "/message-bus/#{client_id}", {
348
- '/filter' => id - 1
349
- }
350
-
351
- parsed = JSON.parse(last_response.body)
352
- parsed.length.should == 0
353
- end
354
-
355
268
  it "should filter by group correctly" do
356
269
  id =@bus.publish("/foo", "test", group_ids: [3,4,5])
357
270
  @bus.group_ids_lookup do |env|
@@ -13,15 +13,16 @@ describe MessageBus::Redis::ReliablePubSub do
13
13
  end
14
14
 
15
15
  context "readonly" do
16
- before do
17
- @bus.pub_redis.slaveof "127.0.0.80", "666"
18
- end
19
16
 
20
17
  after do
21
18
  @bus.pub_redis.slaveof "no", "one"
22
19
  end
23
20
 
24
21
  it "should be able to store messages in memory for a period while in read only" do
22
+
23
+ skip "This spec changes redis behavior that in turn means other specs run slow"
24
+
25
+ @bus.pub_redis.slaveof "127.0.0.80", "666"
25
26
  @bus.max_in_memory_publish_backlog = 2
26
27
 
27
28
  3.times do
@@ -33,35 +33,19 @@ describe MessageBus::TimerThread do
33
33
  end
34
34
 
35
35
  it "queues jobs in the correct order" do
36
- counter = 0
37
- failed = nil
38
36
 
39
- ready = 0
40
-
41
- items = (0...4).to_a.shuffle
42
- items.map do |i|
43
- # threading introduces a delay meaning we need to wait a long time
44
- Thread.new do
45
- ready += 1
46
- while ready < 4
47
- sleep 0
48
- end
49
- # on my mbp I measure at least 200ms of schedule jitter for Thread
50
- @timer.queue(i/3.0) do
51
- #puts "counter #{counter} i #{i}"
52
- failed = true if counter != i
53
- counter += 1
54
- end
55
- #puts "\nqueued #{i/200.0} #{i} #{Time.now.to_f}\n"
37
+ results = []
38
+ (0..3).to_a.reverse.each do |i|
39
+ @timer.queue(0.005 * i) do
40
+ results << i
56
41
  end
57
42
  end
58
43
 
59
44
  wait_for(3000) {
60
- counter == items.length
45
+ 4 == results.length
61
46
  }
62
47
 
63
- counter.should == items.length
64
- failed.should == nil
48
+ results.should == [0,1,2,3]
65
49
  end
66
50
 
67
51
  it "should call the error callback if something goes wrong" do
data/spec/spec_helper.rb CHANGED
@@ -11,7 +11,12 @@ RSpec.configure do |config|
11
11
 
12
12
  # to debug hanging tests
13
13
  # config.before :each do |x|
14
- # p x.metadata[:location]
14
+ # $start = Time.now
15
+ # puts "Start: #{x.metadata[:location]}"
16
+ # end
17
+ #
18
+ # config.after :each do |x|
19
+ # puts "#{x.metadata[:location]} #{Time.now - $start}"
15
20
  # end
16
21
  end
17
22
 
@@ -1,12 +1,6 @@
1
1
  /*jshint bitwise: false*/
2
+ "use strict;"
2
3
 
3
- /**
4
- Message Bus functionality.
5
-
6
- @class MessageBus
7
- @namespace Discourse
8
- @module Discourse
9
- **/
10
4
  window.MessageBus = (function() {
11
5
  // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript
12
6
  var callbacks, clientId, failCount, shouldLongPoll, queue, responseCallbacks, uniqueId, baseUrl;
@@ -30,12 +24,13 @@ window.MessageBus = (function() {
30
24
  baseUrl = "/";
31
25
  paused = false;
32
26
  later = [];
27
+ chunkedBackoff = 0;
33
28
 
34
29
  var hiddenProperty;
35
30
 
36
31
 
37
32
  (function(){
38
- var prefixes = ["","webkit","ms","moz","ms"];
33
+ var prefixes = ["","webkit","ms","moz"];
39
34
  for(var i=0; i<prefixes.length; i++) {
40
35
  var prefix = prefixes[i];
41
36
  var check = prefix + (prefix === "" ? "hidden" : "Hidden");
@@ -53,6 +48,11 @@ window.MessageBus = (function() {
53
48
  }
54
49
  };
55
50
 
51
+ var hasonprogress = (new XMLHttpRequest()).onprogress === null;
52
+ var allowChunked = function(){
53
+ return me.enableChunkedEncoding && hasonprogress;
54
+ };
55
+
56
56
  shouldLongPoll = function() {
57
57
  return me.alwaysLongPoll || !isHidden();
58
58
  };
@@ -65,7 +65,6 @@ window.MessageBus = (function() {
65
65
  var gotData = false;
66
66
  if (!messages) return false; // server unexpectedly closed connection
67
67
 
68
-
69
68
  for (var i=0; i<messages.length; i++) {
70
69
  var message = messages[i];
71
70
  gotData = true;
@@ -93,6 +92,20 @@ window.MessageBus = (function() {
93
92
  return gotData;
94
93
  };
95
94
 
95
+ var reqSuccess = function(messages) {
96
+ failCount = 0;
97
+ if (paused) {
98
+ if (messages) {
99
+ for (var i=0; i<messages.length; i++) {
100
+ later.push(messages[i]);
101
+ }
102
+ }
103
+ } else {
104
+ return processMessages(messages);
105
+ }
106
+ return false;
107
+ };
108
+
96
109
  longPoller = function(poll,data){
97
110
  var gotData = false;
98
111
  var aborted = false;
@@ -100,27 +113,97 @@ window.MessageBus = (function() {
100
113
  totalAjaxCalls += 1;
101
114
  data.__seq = totalAjaxCalls;
102
115
 
103
- return me.ajax({
104
- url: me.baseUrl + "message-bus/" + me.clientId + "/poll?" + (!shouldLongPoll() || !me.enableLongPolling ? "dlp=t" : ""),
116
+ var longPoll = shouldLongPoll() && me.enableLongPolling;
117
+ var chunked = longPoll && allowChunked();
118
+ if (chunkedBackoff > 0) {
119
+ chunkedBackoff--;
120
+ chunked = false;
121
+ }
122
+
123
+ var headers = {
124
+ 'X-SILENCE-LOGGER': 'true'
125
+ };
126
+
127
+ if (!chunked){
128
+ headers["Dont-Chunk"] = 'true';
129
+ }
130
+
131
+ var dataType = chunked ? "text" : "json";
132
+
133
+ var handle_progress = function(payload, position) {
134
+
135
+ var separator = "\r\n|\r\n";
136
+ var endChunk = payload.indexOf(separator, position);
137
+
138
+ if (endChunk === -1) {
139
+ return position;
140
+ }
141
+
142
+ var chunk = payload.substring(position, endChunk);
143
+ chunk = chunk.replace(/\r\n\|\|\r\n/g, separator);
144
+
145
+ try {
146
+ console.log(chunk);
147
+ reqSuccess(JSON.parse(chunk));
148
+ } catch(e) {
149
+ if (console.log) {
150
+ console.log("FAILED TO PARSE CHUNKED REPLY");
151
+ console.log(data);
152
+ }
153
+ }
154
+
155
+ return handle_progress(payload, endChunk + separator.length);
156
+ }
157
+
158
+ var disableChunked = function(){
159
+ if (me.longPoll) {
160
+ me.longPoll.abort();
161
+ chunkedBackoff = 30;
162
+ }
163
+ };
164
+
165
+ var req = me.ajax({
166
+ url: me.baseUrl + "message-bus/" + me.clientId + "/poll?" + (!longPoll ? "dlp=t" : ""),
105
167
  data: data,
106
168
  cache: false,
107
- dataType: 'json',
169
+ dataType: dataType,
108
170
  type: 'POST',
109
- headers: {
110
- 'X-SILENCE-LOGGER': 'true'
171
+ headers: headers,
172
+ xhr: function() {
173
+ var xhr = jQuery.ajaxSettings.xhr();
174
+
175
+ if (!chunked) {
176
+ return xhr;
177
+ }
178
+
179
+ var position = 0;
180
+
181
+ // if it takes longer than 3000 ms to get first chunk, we have some proxy
182
+ // this is messing with us, so just backoff from using chunked for now
183
+ var chunkedTimeout = setTimeout(disableChunked,3000);
184
+
185
+ xhr.onprogress = function () {
186
+ clearTimeout(chunkedTimeout);
187
+
188
+ if(xhr.getResponseHeader('Content-Type') === 'application/json; charset=utf-8') {
189
+ // not chunked we are sending json back
190
+ chunked = false;
191
+ return;
192
+ }
193
+ position = handle_progress(xhr.responseText, position);
194
+ }
195
+
196
+ return xhr;
111
197
  },
112
198
  success: function(messages) {
113
- failCount = 0;
114
- if (paused) {
115
- if (messages) {
116
- for (var i=0; i<messages.length; i++) {
117
- later.push(messages[i]);
118
- }
119
- }
120
- } else {
121
- gotData = processMessages(messages);
122
- }
123
- },
199
+ if (!chunked) {
200
+ // we may have requested text so jQuery will not parse
201
+ if (typeof(messages) === "string") {
202
+ messages = JSON.parse(messages);
203
+ }
204
+ gotData = reqSuccess(messages);
205
+ }
206
+ },
124
207
  error: function(xhr, textStatus, err) {
125
208
  if(textStatus === "abort") {
126
209
  aborted = true;
@@ -161,9 +244,12 @@ window.MessageBus = (function() {
161
244
  me.longPoll = null;
162
245
  }
163
246
  });
247
+
248
+ return req;
164
249
  };
165
250
 
166
251
  me = {
252
+ enableChunkedEncoding: true,
167
253
  enableLongPolling: true,
168
254
  callbackInterval: 15000,
169
255
  backgroundCallbackInterval: 60000,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: message_bus
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 2.0.0.beta.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-09 00:00:00.000000000 Z
11
+ date: 2016-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -76,7 +76,6 @@ files:
76
76
  - lib/message_bus/diagnostics.rb
77
77
  - lib/message_bus/em_ext.rb
78
78
  - lib/message_bus/message.rb
79
- - lib/message_bus/message_handler.rb
80
79
  - lib/message_bus/rack/diagnostics.rb
81
80
  - lib/message_bus/rack/middleware.rb
82
81
  - lib/message_bus/rack/thin_ext.rb
@@ -85,17 +84,15 @@ files:
85
84
  - lib/message_bus/timer_thread.rb
86
85
  - lib/message_bus/version.rb
87
86
  - message_bus.gemspec
88
- - spec/lib/assets/asset_encoding_spec.rb
89
- - spec/lib/client_spec.rb
90
- - spec/lib/connection_manager_spec.rb
91
87
  - spec/lib/fake_async_middleware.rb
92
- - spec/lib/handlers/demo_message_handler.rb
88
+ - spec/lib/message_bus/assets/asset_encoding_spec.rb
89
+ - spec/lib/message_bus/client_spec.rb
90
+ - spec/lib/message_bus/connection_manager_spec.rb
91
+ - spec/lib/message_bus/multi_process_spec.rb
92
+ - spec/lib/message_bus/rack/middleware_spec.rb
93
+ - spec/lib/message_bus/redis/reliable_pub_sub_spec.rb
94
+ - spec/lib/message_bus/timer_thread_spec.rb
93
95
  - spec/lib/message_bus_spec.rb
94
- - spec/lib/message_handler_spec.rb
95
- - spec/lib/middleware_spec.rb
96
- - spec/lib/multi_process_spec.rb
97
- - spec/lib/redis/reliable_pub_sub_spec.rb
98
- - spec/lib/timer_thread_spec.rb
99
96
  - spec/spec_helper.rb
100
97
  - vendor/assets/javascripts/message-bus.js
101
98
  homepage: https://github.com/SamSaffron/message_bus
@@ -113,25 +110,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
113
110
  version: '0'
114
111
  required_rubygems_version: !ruby/object:Gem::Requirement
115
112
  requirements:
116
- - - ">="
113
+ - - ">"
117
114
  - !ruby/object:Gem::Version
118
- version: '0'
115
+ version: 1.3.1
119
116
  requirements: []
120
117
  rubyforge_project:
121
- rubygems_version: 2.4.5.1
118
+ rubygems_version: 2.4.5
122
119
  signing_key:
123
120
  specification_version: 4
124
121
  summary: ''
125
122
  test_files:
126
- - spec/lib/assets/asset_encoding_spec.rb
127
- - spec/lib/client_spec.rb
128
- - spec/lib/connection_manager_spec.rb
129
123
  - spec/lib/fake_async_middleware.rb
130
- - spec/lib/handlers/demo_message_handler.rb
124
+ - spec/lib/message_bus/assets/asset_encoding_spec.rb
125
+ - spec/lib/message_bus/client_spec.rb
126
+ - spec/lib/message_bus/connection_manager_spec.rb
127
+ - spec/lib/message_bus/multi_process_spec.rb
128
+ - spec/lib/message_bus/rack/middleware_spec.rb
129
+ - spec/lib/message_bus/redis/reliable_pub_sub_spec.rb
130
+ - spec/lib/message_bus/timer_thread_spec.rb
131
131
  - spec/lib/message_bus_spec.rb
132
- - spec/lib/message_handler_spec.rb
133
- - spec/lib/middleware_spec.rb
134
- - spec/lib/multi_process_spec.rb
135
- - spec/lib/redis/reliable_pub_sub_spec.rb
136
- - spec/lib/timer_thread_spec.rb
137
132
  - spec/spec_helper.rb