message_bus 4.3.1 → 4.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15a820bf3ce7658e466132cbc2dd41c4f71b5c68db2e993437698192922377b9
4
- data.tar.gz: 2c698b0e82d3d17dc3c0aa682e34ffaf32713f47fe207c1e8b1d55d2fb7cbe48
3
+ metadata.gz: e36107abe5d2f970df28804121149c63c3fc7b7708013673340564f511bbfbbe
4
+ data.tar.gz: 5a3b55c06cd1137c152025b08e8ca3bba0b47c5cdb2330721c9c9c3559db454d
5
5
  SHA512:
6
- metadata.gz: 0ea1a5c7a8c80bdddb487eed1442e6364b37518407c1809b0fe76bc3bf5fcba96bb66df04d02d4e491350d415abbae1cd0ecc91ef1079838d6455b6063c0459f
7
- data.tar.gz: 981cc3d93b7ca7a3af50179c9450033f4e4566edca5d1269c73d3fd94952f5a77d5ce14b87aa58bc5845e377a2c5c6cbe64cd1dc7905dd7689dfe1295f0668cf
6
+ metadata.gz: 19ecda3ef5c20ffd217e491dcd784c4e2f04a360b0ad27d3aeee96b468ae55e88e23827a0d5fab787af05cf9afa9df2d2a0c7d3b1a7ccb8b3b4544164e430595
7
+ data.tar.gz: 05c2411c4b17495306d7c33da0a73759ceab0ec7f332e4626d914b68d4ae8febc53ab552a854197a0335c5f4483195a3389eec7c6b4774d14a719c7b8429bf7a
data/CHANGELOG CHANGED
@@ -1,5 +1,12 @@
1
1
  FUTURE
2
2
 
3
+
4
+ 13-01-2023
5
+
6
+ - Version 4.2.1
7
+
8
+ - FIX: Do not disable chunking on cancel/error
9
+
3
10
  06-01-2023
4
11
 
5
12
  - Version 4.2.1
@@ -205,10 +205,11 @@
205
205
  return handle_progress(payload, endChunk + separator.length);
206
206
  };
207
207
 
208
+ var chunkedTimeout;
208
209
  var disableChunked = function () {
209
210
  if (me.longPoll) {
210
211
  me.longPoll.abort();
211
- chunkedBackoff = 30;
212
+ chunkedBackoff = me.retryChunkedAfterRequests;
212
213
  }
213
214
  };
214
215
 
@@ -235,9 +236,9 @@
235
236
  chunked: chunked,
236
237
  onProgressListener: function (xhr) {
237
238
  var position = 0;
238
- // if it takes longer than 3000 ms to get first chunk, we have some proxy
239
- // this is messing with us, so just backoff from using chunked for now
240
- var chunkedTimeout = setTimeout(disableChunked, 3000);
239
+ // if it takes longer than firstChunkTimeout to get first chunk, there may be a proxy
240
+ // buffering the response. Switch to non-chunked long-polling mode.
241
+ chunkedTimeout = setTimeout(disableChunked, me.firstChunkTimeout);
241
242
  return (xhr.onprogress = function () {
242
243
  clearTimeout(chunkedTimeout);
243
244
  if (
@@ -269,6 +270,7 @@
269
270
  }
270
271
  },
271
272
  error: function (xhr, textStatus) {
273
+ clearTimeout(chunkedTimeout);
272
274
  if (xhr.status === 429) {
273
275
  var tryAfter =
274
276
  parseInt(
@@ -364,6 +366,8 @@
364
366
  clientId: clientId,
365
367
  alwaysLongPoll: false,
366
368
  shouldLongPollCallback: undefined,
369
+ firstChunkTimeout: 3000,
370
+ retryChunkedAfterRequests: 30,
367
371
  baseUrl: baseUrl,
368
372
  headers: {},
369
373
  ajax: typeof jQuery !== "undefined" && jQuery.ajax,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MessageBus
4
- VERSION = "4.3.1"
4
+ VERSION = "4.3.2"
5
5
  end
@@ -34,8 +34,23 @@ beforeEach(function () {
34
34
  this.readyState = 4
35
35
  this.responseText = encodeChunks(this, spec.responseChunks);
36
36
  this.status = spec.responseStatus;
37
- if (this.onprogress){ this.onprogress(); }
38
- this.onreadystatechange()
37
+
38
+ spec.requestStarted?.();
39
+
40
+ const complete = () => {
41
+ if(this.statusText === "abort"){
42
+ return;
43
+ }
44
+ this.onprogress?.();
45
+ this.onreadystatechange();
46
+ }
47
+
48
+ if(spec.delayResponsePromise){
49
+ spec.delayResponsePromise.then(() => complete())
50
+ spec.delayResponsePromise = null;
51
+ }else{
52
+ complete();
53
+ }
39
54
  }
40
55
 
41
56
  MockedXMLHttpRequest.prototype.open = function(){ }
@@ -43,8 +58,8 @@ beforeEach(function () {
43
58
  MockedXMLHttpRequest.prototype.abort = function(){
44
59
  this.readyState = 4
45
60
  this.responseText = '';
46
- this.statusText = '';
47
- this.status = 400;
61
+ this.statusText = 'abort';
62
+ this.status = 0;
48
63
  this.onreadystatechange()
49
64
  }
50
65
 
@@ -68,6 +83,10 @@ beforeEach(function () {
68
83
  "Content-Type": 'text/plain; charset=utf-8',
69
84
  };
70
85
 
86
+ MessageBus.enableChunkedEncoding = true;
87
+ MessageBus.firstChunkTimeout = 3000;
88
+ MessageBus.retryChunkedAfterRequests = 1;
89
+
71
90
  MessageBus.start();
72
91
  });
73
92
 
@@ -75,7 +94,6 @@ afterEach(function(){
75
94
  MessageBus.stop()
76
95
  MessageBus.callbacks.splice(0, MessageBus.callbacks.length)
77
96
  MessageBus.shouldLongPollCallback = null;
78
- MessageBus.enableChunkedEncoding = true;
79
97
  });
80
98
 
81
99
  window.testMB = function(description, testFn, path, data){
@@ -166,4 +166,63 @@ describe("Messagebus", function () {
166
166
  const nextPollScheduledIn = window.setTimeout.calls.mostRecent().args[1];
167
167
  expect(nextPollScheduledIn).toEqual(MessageBus.minPollInterval);
168
168
  });
169
+
170
+ it("enters don't-chunk-mode if first chunk times out", async function () {
171
+ spyOn(this.MockedXMLHttpRequest.prototype, "send").and.callThrough();
172
+ spyOn(
173
+ this.MockedXMLHttpRequest.prototype,
174
+ "setRequestHeader"
175
+ ).and.callThrough();
176
+
177
+ let resolveFirstResponse;
178
+ this.delayResponsePromise = new Promise(
179
+ (resolve) => (resolveFirstResponse = resolve)
180
+ );
181
+ MessageBus.firstChunkTimeout = 50;
182
+
183
+ await new Promise((resolve) => MessageBus.subscribe("/test", resolve));
184
+ resolveFirstResponse();
185
+
186
+ const calls =
187
+ this.MockedXMLHttpRequest.prototype.setRequestHeader.calls.all();
188
+
189
+ const dontChunkCalls = calls.filter((c) => c.args[0] === "Dont-Chunk");
190
+ expect(dontChunkCalls.length).toEqual(1);
191
+ });
192
+
193
+ it("doesn't enter don't-chunk-mode if aborted before first chunk", async function () {
194
+ spyOn(
195
+ this.MockedXMLHttpRequest.prototype,
196
+ "setRequestHeader"
197
+ ).and.callThrough();
198
+
199
+ this.delayResponsePromise = new Promise(() => {});
200
+ MessageBus.firstChunkTimeout = 300;
201
+
202
+ const requestWasStarted = new Promise(
203
+ (resolve) => (this.requestStarted = resolve)
204
+ );
205
+
206
+ // Trigger request
207
+ const subscribedPromise = new Promise((resolve) =>
208
+ MessageBus.subscribe("/test", resolve)
209
+ );
210
+
211
+ await requestWasStarted;
212
+
213
+ // Change subscription (triggers an abort and re-poll)
214
+ MessageBus.subscribe("/test2", () => {});
215
+
216
+ // Wait for stuff to settle
217
+ await subscribedPromise;
218
+
219
+ // Wait 300ms to ensure dontChunk timeout has passed
220
+ await new Promise((resolve) => setTimeout(resolve, 300));
221
+
222
+ const calls =
223
+ this.MockedXMLHttpRequest.prototype.setRequestHeader.calls.all();
224
+
225
+ const dontChunkCalls = calls.filter((c) => c.args[0] === "Dont-Chunk");
226
+ expect(dontChunkCalls.length).toEqual(0);
227
+ });
169
228
  });
@@ -205,10 +205,11 @@
205
205
  return handle_progress(payload, endChunk + separator.length);
206
206
  };
207
207
 
208
+ var chunkedTimeout;
208
209
  var disableChunked = function () {
209
210
  if (me.longPoll) {
210
211
  me.longPoll.abort();
211
- chunkedBackoff = 30;
212
+ chunkedBackoff = me.retryChunkedAfterRequests;
212
213
  }
213
214
  };
214
215
 
@@ -235,9 +236,9 @@
235
236
  chunked: chunked,
236
237
  onProgressListener: function (xhr) {
237
238
  var position = 0;
238
- // if it takes longer than 3000 ms to get first chunk, we have some proxy
239
- // this is messing with us, so just backoff from using chunked for now
240
- var chunkedTimeout = setTimeout(disableChunked, 3000);
239
+ // if it takes longer than firstChunkTimeout to get first chunk, there may be a proxy
240
+ // buffering the response. Switch to non-chunked long-polling mode.
241
+ chunkedTimeout = setTimeout(disableChunked, me.firstChunkTimeout);
241
242
  return (xhr.onprogress = function () {
242
243
  clearTimeout(chunkedTimeout);
243
244
  if (
@@ -269,6 +270,7 @@
269
270
  }
270
271
  },
271
272
  error: function (xhr, textStatus) {
273
+ clearTimeout(chunkedTimeout);
272
274
  if (xhr.status === 429) {
273
275
  var tryAfter =
274
276
  parseInt(
@@ -364,6 +366,8 @@
364
366
  clientId: clientId,
365
367
  alwaysLongPoll: false,
366
368
  shouldLongPollCallback: undefined,
369
+ firstChunkTimeout: 3000,
370
+ retryChunkedAfterRequests: 30,
367
371
  baseUrl: baseUrl,
368
372
  headers: {},
369
373
  ajax: typeof jQuery !== "undefined" && jQuery.ajax,
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: 4.3.1
4
+ version: 4.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-06 00:00:00.000000000 Z
11
+ date: 2023-01-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack