Merge pull request #139 from matrix-org/dbkr/rate_limit_funcs

Make the function call-rate limiting a generic thing and use it in more places.
This commit is contained in:
David Baker 2016-02-05 10:15:55 +00:00
commit 0ae548cf5d
4 changed files with 50 additions and 34 deletions

View File

@ -41,6 +41,7 @@ var Resend = require("../../Resend");
var SlashCommands = require("../../SlashCommands");
var dis = require("../../dispatcher");
var Tinter = require("../../Tinter");
var rate_limited_func = require('../../ratelimitedfunc');
var PAGINATE_SIZE = 20;
var INITIAL_SIZE = 20;
@ -619,7 +620,7 @@ module.exports = React.createClass({
}
},
_updateTabCompleteList: function(room) {
_updateTabCompleteList: new rate_limited_func(function(room) {
if (!room || !this.tabComplete) {
return;
}
@ -628,7 +629,7 @@ module.exports = React.createClass({
CommandEntry.fromCommands(SlashCommands.getCommandList())
)
);
},
}, 500),
_initialiseMessagePanel: function() {
var messagePanel = ReactDOM.findDOMNode(this.refs.messagePanel);

View File

@ -22,6 +22,7 @@ var Modal = require("../../../Modal");
var Entities = require("../../../Entities");
var sdk = require('../../../index');
var GeminiScrollbar = require('react-gemini-scrollbar');
var rate_limited_func = require('../../../ratelimitedfunc');
var INITIAL_LOAD_NUM_MEMBERS = 30;
var SHARE_HISTORY_WARNING = "Newly invited users will see the history of this room. "+
@ -147,14 +148,14 @@ module.exports = React.createClass({
}
},
_updateList: function() {
_updateList: new rate_limited_func(function() {
this.memberDict = this.getMemberDict();
var self = this;
this.setState({
members: self.roomMembers()
});
},
}, 500),
onInvite: function(inputText) {
var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");

View File

@ -24,6 +24,7 @@ var RoomListSorter = require("../../../RoomListSorter");
var Unread = require('../../../Unread');
var dis = require("../../../dispatcher");
var sdk = require('../../../index');
var rate_limited_func = require('../../../ratelimitedfunc');
var HIDE_CONFERENCE_CHANS = true;
@ -155,36 +156,9 @@ module.exports = React.createClass({
this._delayedRefreshRoomList();
},
_delayedRefreshRoomList: function() {
// There can be 1000s of JS SDK events when rooms are initially synced;
// we don't want to do lots of work rendering until things have settled.
// Therefore, keep a 1s refresh buffer which will refresh the room list
// at MOST once every 1s to prevent thrashing.
var MAX_REFRESH_INTERVAL_MS = 1000;
var self = this;
if (!self._lastRefreshRoomListTs) {
self.refreshRoomList(); // first refresh evar
}
else {
var timeWaitedMs = Date.now() - self._lastRefreshRoomListTs;
if (timeWaitedMs > MAX_REFRESH_INTERVAL_MS) {
clearTimeout(self._refreshRoomListTimerId);
self._refreshRoomListTimerId = null;
self.refreshRoomList(); // refreshed more than MAX_REFRESH_INTERVAL_MS ago
}
else {
// refreshed less than MAX_REFRESH_INTERVAL_MS ago, wait the difference
// if we aren't already waiting. If we are waiting then NOP, it will
// fire soon, promise!
if (!self._refreshRoomListTimerId) {
self._refreshRoomListTimerId = setTimeout(function() {
self.refreshRoomList();
}, 10 + MAX_REFRESH_INTERVAL_MS - timeWaitedMs); // 10 is a buffer amount
}
}
}
},
_delayedRefreshRoomList: new rate_limited_func(function() {
this.refreshRoomList();
}, 500),
refreshRoomList: function() {
// console.log("DEBUG: Refresh room list delta=%s ms",

40
src/ratelimitedfunc.js Normal file
View File

@ -0,0 +1,40 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
module.exports = function(f, minIntervalMs) {
this.lastCall = 0;
this.scheduledCall = undefined;
var self = this;
return function() {
var now = Date.now();
if (self.lastCall < now - minIntervalMs) {
f.apply(this);
self.lastCall = now;
} else if (self.scheduledCall === undefined) {
self.scheduledCall = setTimeout(
() => {
self.scheduledCall = undefined;
f.apply(this);
self.lastCall = now;
},
(self.lastCall + minIntervalMs) - now
);
}
};
};