Skip to content

Commit 7ebbd5f

Browse files
authored
fix #7116 only send one frame request at a time to the server (#7446)
1 parent 96aceec commit 7ebbd5f

File tree

2 files changed

+81
-67
lines changed

2 files changed

+81
-67
lines changed

sirepo/package_data/static/js/sirepo-components.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -4776,7 +4776,7 @@ SIREPO.app.directive('sbatchLoginModal', function() {
47764776
<div class="modal-dialog" role="document">
47774777
<div class="modal-content">
47784778
<div class="modal-header bg-warning">
4779-
<span class="lead modal-title text-info">Login to {{ authState.sbatchHostDisplayName }}</span>
4779+
<span class="lead modal-title text-info">{{ loginHeading() }}</span>
47804780
<button data-ng-click="cancel()" type="button" class="close" data-ng-disabled="! sbatchLoginService.query('showLogin')"><span>&times;</span></button>
47814781
</div>
47824782
<div class="modal-body">
@@ -4823,6 +4823,8 @@ SIREPO.app.directive('sbatchLoginModal', function() {
48234823
sbatchLoginService.event('credsCancel');
48244824
};
48254825

4826+
$scope.loginHeading = () => sbatchLoginService.loginButtonLabel();
4827+
48264828
$scope.submit = () => {
48274829
$scope.warning = null;
48284830
sbatchLoginService.event(

sirepo/package_data/static/js/sirepo.js

+78-66
Original file line numberDiff line numberDiff line change
@@ -1737,10 +1737,11 @@ SIREPO.app.factory('srCache', function(appState, $rootScope) {
17371737
});
17381738

17391739

1740-
SIREPO.app.factory('frameCache', function(appState, panelState, requestSender, srCache, $interval, $rootScope, $timeout) {
1741-
var self = {};
1742-
var frameCountByModelKey = {};
1743-
var masterFrameCount = 0;
1740+
SIREPO.app.factory('frameCache', function(appState, panelState, requestSender, srCache, $rootScope, $timeout) {
1741+
const self = {};
1742+
let frameCountByModelKey = {};
1743+
let masterFrameCount = 0;
1744+
const requestByModelKey = {};
17441745
self.modelToCurrentFrame = {};
17451746

17461747
function frameId(frameReport, frameIndex) {
@@ -1782,92 +1783,105 @@ SIREPO.app.factory('frameCache', function(appState, panelState, requestSender, s
17821783
return self.modelToCurrentFrame[modelName] || 0;
17831784
};
17841785

1785-
self.getFrame = function(modelName, index, isPlaying, callback) {
1786-
const isHidden = panelState.isHidden(modelName);
1787-
let frameRequestTime = now();
1788-
let setPanelStateIsLoadingTimer = null;
1789-
1790-
function cancelSetPanelStateIsLoadingTimer() {
1791-
if (setPanelStateIsLoadingTimer) {
1792-
$timeout.cancel(setPanelStateIsLoadingTimer);
1793-
setPanelStateIsLoadingTimer = null;
1794-
}
1795-
}
1786+
self.getFrame = function(modelKey, index, isPlaying, callback) {
1787+
let loadingTimer = null;
17961788

1797-
function onError(response) {
1798-
if (! (response && response.error)) {
1799-
panelState.reportNotGenerated(modelName);
1800-
}
1801-
else if (! response.sbatchLoginServiceSRException) {
1802-
panelState.setLoading(modelName, false);
1803-
panelState.setError(modelName, response.error);
1789+
const callbackData = (data, frameRequestTime) => {
1790+
const t = framePeriod() - (now() - frameRequestTime);
1791+
if (t <= 0) {
1792+
callback(index, data);
1793+
return;
18041794
}
1805-
cancelSetPanelStateIsLoadingTimer();
1806-
}
1795+
$timeout(() => callback(index, data), t);
1796+
};
18071797

1808-
function now() {
1809-
return new Date().getTime();
1810-
}
1798+
const cancelLoadingTimer = () => {
1799+
panelState.setLoading(modelKey, false);
1800+
if (loadingTimer) {
1801+
$timeout.cancel(loadingTimer);
1802+
loadingTimer = null;
1803+
}
1804+
};
18111805

18121806
const framePeriod = () => {
1813-
if (! isPlaying || isHidden) {
1807+
if (! isPlaying || panelState.isHidden(modelKey)) {
18141808
return 0;
18151809
}
1816-
const milliseconds = 1000;
1817-
var x = appState.models[modelName].framesPerSecond;
1818-
if (! x) {
1819-
return 0.5 * milliseconds;
1810+
const s = appState.models[modelKey].framesPerSecond;
1811+
return 1000 / (s && parseInt(s) ? parseInt(s) : 2);
1812+
};
1813+
1814+
const now = () => new Date().getTime();
1815+
1816+
const onError = (response) => {
1817+
if (! (response && response.error)) {
1818+
panelState.reportNotGenerated(modelKey);
1819+
}
1820+
else if (! response.sbatchLoginServiceSRException) {
1821+
panelState.setError(modelKey, response.error);
18201822
}
1821-
return milliseconds / parseInt(x);
1823+
cancelLoadingTimer();
18221824
};
18231825

1824-
const callbackData = (data) => {
1825-
let e = framePeriod() - (now() - frameRequestTime);
1826-
if (e <= 0) {
1827-
callback(index, data);
1828-
return;
1826+
const checkNextRequest = () => {
1827+
const i = requestByModelKey[modelKey];
1828+
delete requestByModelKey[modelKey];
1829+
if (i != index) {
1830+
index = i;
1831+
// avoid a recursive stack overflow
1832+
$timeout(() => requestFunction(true), 0);
18291833
}
1830-
$interval(
1831-
function() {
1832-
callback(index, data);
1833-
},
1834-
e,
1835-
1
1836-
);
18371834
};
18381835

1839-
const requestFunction = function() {
1840-
const id = frameId(modelName, index);
1841-
srCache.getFrame(id, modelName, (data) => {
1836+
const requestFunction = (isRetry) => {
1837+
const id = frameId(modelKey, index);
1838+
const frameRequestTime = now();
1839+
srCache.getFrame(id, modelKey, (data) => {
1840+
if (isRetry && modelKey in requestByModelKey) {
1841+
// another frame has been requested since the retry was started
1842+
return;
1843+
}
18421844
if (data) {
1843-
callbackData(data);
1845+
callbackData(data, frameRequestTime);
1846+
return;
1847+
}
1848+
if (modelKey in requestByModelKey) {
1849+
requestByModelKey[modelKey] = index;
18441850
return;
18451851
}
1846-
setPanelStateIsLoadingTimer = $timeout(() => {
1847-
panelState.setLoading(modelName, true);
1848-
}, 5000);
1852+
if (! loadingTimer) {
1853+
loadingTimer = $timeout(() => {
1854+
panelState.setLoading(modelKey, true);
1855+
}, 5000);
1856+
}
1857+
requestByModelKey[modelKey] = index;
18491858
requestSender.sendRequest(
18501859
{
18511860
routeName: 'simulationFrame',
18521861
frame_id: id,
18531862
},
1854-
function(data) {
1855-
cancelSetPanelStateIsLoadingTimer();
1856-
panelState.setLoading(modelName, false);
1863+
(data) => {
1864+
cancelLoadingTimer();
18571865
if ('state' in data && data.state === 'missing') {
18581866
onError();
1859-
return;
18601867
}
1861-
callbackData(data);
1862-
srCache.saveFrame(id, modelName, data);
1868+
else {
1869+
callbackData(data, frameRequestTime);
1870+
srCache.saveFrame(id, modelKey, data);
1871+
}
1872+
checkNextRequest();
18631873
},
18641874
null,
1865-
onError
1875+
(response) => {
1876+
onError(response);
1877+
checkNextRequest();
1878+
}
18661879
);
18671880
});
18681881
};
1869-
if (isHidden) {
1870-
panelState.addPendingRequest(modelName, requestFunction);
1882+
1883+
if (panelState.isHidden(modelKey)) {
1884+
panelState.setPendingRequest(modelKey, requestFunction);
18711885
}
18721886
else {
18731887
requestFunction();
@@ -2145,10 +2159,6 @@ SIREPO.app.factory('panelState', function(appState, uri, simulationQueue, utilit
21452159
return uri.format(route, {...a, ...args});
21462160
}
21472161

2148-
self.addPendingRequest = function(name, requestFunction) {
2149-
pendingRequests[name] = requestFunction;
2150-
};
2151-
21522162
self.clear = function(name) {
21532163
if (name) {
21542164
clearPanel(name);
@@ -2332,7 +2342,7 @@ SIREPO.app.factory('panelState', function(appState, uri, simulationQueue, utilit
23322342
if (queueItems[name]) {
23332343
simulationQueue.cancelItem(queueItems[name]);
23342344
}
2335-
self.addPendingRequest(name, function() {
2345+
self.setPendingRequest(name, () => {
23362346
queueItems[name] = sendRequest(name, wrappedCallback, errorCallback);
23372347
});
23382348
if (! self.isHidden(name)) {
@@ -2360,6 +2370,8 @@ SIREPO.app.factory('panelState', function(appState, uri, simulationQueue, utilit
23602370

23612371
self.setData = (name, data) => setPanelValue(name, 'data', data);
23622372

2373+
self.setPendingRequest = (name, requestFunction) => pendingRequests[name] = requestFunction;
2374+
23632375
self.setWaiting = (name, isWaiting) => {
23642376
setPanelValue(name, 'waiting', isWaiting);
23652377
};

0 commit comments

Comments
 (0)