1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-08-18 05:42:00 +03:00

Scrollback improvements

Add a 3s delay between scrollback requests if the previous scrollback request
failed.

Return the same promise if scrollback() is called multiple times whilst a
scrollback request is ongoing.
This commit is contained in:
Kegan Dougal
2015-12-04 17:27:16 +00:00
parent d16dfdaee3
commit 73e0216f78
2 changed files with 39 additions and 1 deletions

View File

@@ -19,6 +19,7 @@ var webRtcCall = require("./webrtc/call");
var utils = require("./utils"); var utils = require("./utils");
var contentRepo = require("./content-repo"); var contentRepo = require("./content-repo");
var SCROLLBACK_DELAY_MS = 3000;
var CRYPTO_ENABLED = false; var CRYPTO_ENABLED = false;
try { try {
@@ -155,6 +156,7 @@ function MatrixClient(opts) {
this._syncingRetry = null; this._syncingRetry = null;
this._guestRooms = null; this._guestRooms = null;
this._isGuest = false; this._isGuest = false;
this._ongoingScrollbacks = {};
} }
utils.inherits(MatrixClient, EventEmitter); utils.inherits(MatrixClient, EventEmitter);
@@ -1767,6 +1769,12 @@ MatrixClient.prototype.roomState = function(roomId, callback) {
/** /**
* Retrieve older messages from the given room and put them in the timeline. * Retrieve older messages from the given room and put them in the timeline.
*
* If this is called multiple times whilst a request is ongoing, the <i>same</i>
* Promise will be returned. If there was a problem requesting scrollback, there
* will be a small delay before another request can be made (to prevent tight-looping
* when there is no connection).
*
* @param {Room} room The room to get older messages in. * @param {Room} room The room to get older messages in.
* @param {Integer} limit Optional. The maximum number of previous events to * @param {Integer} limit Optional. The maximum number of previous events to
* pull in. Default: 30. * pull in. Default: 30.
@@ -1779,6 +1787,16 @@ MatrixClient.prototype.roomState = function(roomId, callback) {
MatrixClient.prototype.scrollback = function(room, limit, callback) { MatrixClient.prototype.scrollback = function(room, limit, callback) {
if (utils.isFunction(limit)) { callback = limit; limit = undefined; } if (utils.isFunction(limit)) { callback = limit; limit = undefined; }
limit = limit || 30; limit = limit || 30;
var timeToWaitMs = 0;
var info = this._ongoingScrollbacks[room.roomId] || {};
if (info.promise) {
return info.promise;
}
else if (info.errorTs) {
var timeWaitedMs = Date.now() - info.errorTs;
timeToWaitMs = Math.max(SCROLLBACK_DELAY_MS - timeWaitedMs, 0);
}
if (room.oldState.paginationToken === null) { if (room.oldState.paginationToken === null) {
return q(room); // already at the start. return q(room); // already at the start.
@@ -1801,8 +1819,16 @@ MatrixClient.prototype.scrollback = function(room, limit, callback) {
dir: 'b' dir: 'b'
}; };
var defer = q.defer(); var defer = q.defer();
info = {
promise: defer.promise,
errorTs: null
};
var self = this; var self = this;
this._http.authedRequest(callback, "GET", path, params).done(function(res) { // wait for a time before doing this request
// (which may be 0 in order not to special case the code paths)
q.delay(timeToWaitMs).then(function() {
return self._http.authedRequest(callback, "GET", path, params);
}).done(function(res) {
var matrixEvents = utils.map(res.chunk, _PojoToMatrixEventMapper(self)); var matrixEvents = utils.map(res.chunk, _PojoToMatrixEventMapper(self));
room.addEventsToTimeline(matrixEvents, true); room.addEventsToTimeline(matrixEvents, true);
room.oldState.paginationToken = res.end; room.oldState.paginationToken = res.end;
@@ -1810,10 +1836,15 @@ MatrixClient.prototype.scrollback = function(room, limit, callback) {
room.oldState.paginationToken = null; room.oldState.paginationToken = null;
} }
self.store.storeEvents(room, matrixEvents, res.end, true); self.store.storeEvents(room, matrixEvents, res.end, true);
self._ongoingScrollbacks[room.roomId] = null;
_resolve(callback, defer, room); _resolve(callback, defer, room);
}, function(err) { }, function(err) {
self._ongoingScrollbacks[room.roomId] = {
errorTs: Date.now()
};
_reject(callback, defer, err); _reject(callback, defer, err);
}); });
this._ongoingScrollbacks[room.roomId] = info;
return defer.promise; return defer.promise;
}; };

View File

@@ -28,6 +28,7 @@ HttpBackend.prototype = {
var defer = q.defer(); var defer = q.defer();
var self = this; var self = this;
var flushed = 0; var flushed = 0;
var triedWaiting = false;
console.log( console.log(
"HTTP backend flushing... (path=%s numToFlush=%s)", path, numToFlush "HTTP backend flushing... (path=%s numToFlush=%s)", path, numToFlush
); );
@@ -49,6 +50,12 @@ HttpBackend.prototype = {
setTimeout(tryFlush, 0); setTimeout(tryFlush, 0);
} }
} }
else if (flushed === 0 && !triedWaiting) {
// we may not have made the request yet, wait a generous amount of
// time before giving up.
setTimeout(tryFlush, 5);
triedWaiting = true;
}
else { else {
console.log(" no more flushes. [%s]", path); console.log(" no more flushes. [%s]", path);
defer.resolve(); defer.resolve();