Skip to content

Commit

Permalink
Debounce timeout if an XMLHTTPRequest is making progress
Browse files Browse the repository at this point in the history
  * Add a timeoutContext object to track last loaded state of a request
  * debounce the timeout function if the number of loaded bytes is increasing
  • Loading branch information
pik committed Jan 17, 2017
1 parent c60e004 commit e5a689a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
41 changes: 37 additions & 4 deletions src/http-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,30 @@ module.exports.MatrixHttpApi = function MatrixHttpApi(event_emitter, opts) {
this.uploads = [];
};

var TimeoutContext = function TimeoutContext(timeoutFunction, waitMs) {
this.lastLoaded = null;
this.jobName = null;
this.timeoutFunction = timeoutFunction;
this.waitMs = waitMs;
};

TimeoutContext.prototype.onProgressCheck = function(progressEvent) {
if (this.lastLoaded || progressEvent.loaded > this.lastLoaded) {
callbacks.debounce(this.jobName);
this.lastLoaded = progressEvent.loaded;
}
return progressEvent;
};

TimeoutContext.prototype.stop = function() {
callbacks.clearDebounce(this.jobName);
};

TimeoutContext.prototype.start = function() {
this.jobName = callbacks.debounce(undefined, this.timeoutFunction, this.waitMs);
};


module.exports.MatrixHttpApi.prototype = {

/**
Expand Down Expand Up @@ -630,9 +654,11 @@ module.exports.MatrixHttpApi.prototype = {
let timeoutId;
let timedOut = false;
let req;
let timeoutContext;
let localTimeoutMs = opts.localTimeoutMs || this.opts.localTimeoutMs;
if (localTimeoutMs) {
timeoutId = callbacks.setTimeout(function() {
var timeoutFunction = function() {
console.log('TIMED OUT')
timedOut = true;
if (req && req.abort) {
req.abort();
Expand All @@ -642,7 +668,8 @@ module.exports.MatrixHttpApi.prototype = {
errcode: "ORG.MATRIX.JSSDK_TIMEOUT",
timeout: localTimeoutMs,
}));
}, localTimeoutMs);
};
timeoutContext = new TimeoutContext(timeoutFunction, localTimeoutMs);
}

let reqPromise = defer.promise;
Expand All @@ -661,8 +688,9 @@ module.exports.MatrixHttpApi.prototype = {
_matrix_opts: this.opts,
},
function(err, response, body) {
if (localTimeoutMs) {
callbacks.clearTimeout(timeoutId);
if (timeoutContext) {
timeoutContext.stop()
delete req.onprogres;
if (timedOut) {
return; // already rejected promise
}
Expand All @@ -679,6 +707,11 @@ module.exports.MatrixHttpApi.prototype = {
handlerFn(err, response, body);
}
);
if (timeoutContext) {
req.onprogress = timeoutContext.onProgressCheck;
console.log('START TIMEOUT CONTEXT')
timeoutContext.start();
}
if (req && req.abort) {
// FIXME: This is EVIL, but I can't think of a better way to expose
// abort() operations on underlying HTTP requests :(
Expand Down
2 changes: 1 addition & 1 deletion src/sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ let DEBUG = true;
// beyond that and wedge forever, so we need to track how long we are willing
// to keep open the connection. This constant is *ADDED* to the timeout= value
// to determine the max time we're willing to wait.
let BUFFER_PERIOD_MS = 80 * 1000;
let BUFFER_PERIOD_MS = 30 * 1000;

function getFilterName(userId, suffix) {
// scope this on the user ID because people may login on many accounts
Expand Down

0 comments on commit e5a689a

Please sign in to comment.