Skip to content

Commit ee1010e

Browse files
committed
Bug 1427289 - Fix log updates when switching containers
The `onClose` callback for log streamers happens asynchronously. Make sure the `onClose` cleanup happens before we begin streaming the next container log. Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1427289
1 parent cfbf483 commit ee1010e

File tree

2 files changed

+192
-175
lines changed

2 files changed

+192
-175
lines changed

app/scripts/directives/logViewer.js

Lines changed: 106 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ angular.module('openshiftConsole')
77
'$timeout',
88
'$window',
99
'$filter',
10+
'$q',
1011
'AuthService',
1112
'APIService',
1213
'APIDiscovery',
@@ -19,6 +20,7 @@ angular.module('openshiftConsole')
1920
$timeout,
2021
$window,
2122
$filter,
23+
$q,
2224
AuthService,
2325
APIService,
2426
APIDiscovery,
@@ -299,9 +301,15 @@ angular.module('openshiftConsole')
299301
// since the user can (potentially) swap between multiple containers
300302
var streamer;
301303
var stopStreaming = function(keepContent) {
304+
var deferred = $q.defer();
302305
if (streamer) {
306+
streamer.onClose(function() {
307+
deferred.resolve();
308+
});
303309
streamer.stop();
304-
streamer = null;
310+
} else {
311+
// Resolve immediately if no active stream.
312+
deferred.resolve();
305313
}
306314

307315
if (!keepContent) {
@@ -310,117 +318,119 @@ angular.module('openshiftConsole')
310318
cachedLogNode && (cachedLogNode.innerHTML = '');
311319
buffer = document.createDocumentFragment();
312320
}
321+
322+
return deferred.promise;
313323
};
314324

315325
var streamLogs = function() {
316326
// Stop any active streamer.
317-
stopStreaming();
318-
319-
if(!$scope.run) {
320-
return;
321-
}
322-
323-
angular.extend($scope, {
324-
loading: true,
325-
autoScrollActive: true,
326-
limitReached: false,
327-
showScrollLinks: false
328-
});
329-
330-
var options = angular.extend({
331-
follow: true,
332-
tailLines: 5000,
333-
// Limit log size to 10 MiB. Note: This can't be more than 500 MiB,
334-
// otherwise save log will break because we'll exceed the max Blob
335-
// size for some browsers.
336-
// https://github.com/eligrey/FileSaver.js#supported-browsers
337-
limitBytes: 10 * 1024 * 1024
338-
}, $scope.options);
339-
340-
streamer = DataService.createStream(logSubresource, name, $scope.context, options);
341-
342-
var lastLineNumber = 0;
343-
var addLine = function(text) {
344-
lastLineNumber++;
345-
// Append the line to the document fragment buffer.
346-
buffer.appendChild(buildLogLineNode(lastLineNumber, text));
347-
update();
348-
};
349-
350-
streamer.onMessage(function(msg, raw, cumulativeBytes) {
351-
// ensures the digest loop will catch the state change.
327+
stopStreaming().then(function() {
352328
$scope.$evalAsync(function() {
353-
$scope.empty = false;
354-
if($scope.state !== 'logs') {
355-
$scope.state = 'logs';
356-
resizeWhenVisible();
329+
if(!$scope.run) {
330+
return;
357331
}
358-
});
359332

360-
// Completely empty messages (without even a newline character) should not add lines
361-
if (!msg) {
362-
return;
363-
}
364-
365-
if (options.limitBytes && cumulativeBytes >= options.limitBytes) {
366-
$scope.$evalAsync(function() {
367-
$scope.limitReached = true;
368-
$scope.loading = false;
333+
angular.extend($scope, {
334+
loading: true,
335+
autoScrollActive: true,
336+
largeLog: false,
337+
limitReached: false,
338+
showScrollLinks: false,
339+
state: ''
369340
});
370-
stopStreaming(true);
371-
}
372341

373-
addLine(msg);
342+
var options = angular.extend({
343+
follow: true,
344+
tailLines: 5000,
345+
// Limit log size to 10 MiB. Note: This can't be more than 500 MiB,
346+
// otherwise save log will break because we'll exceed the max Blob
347+
// size for some browsers.
348+
// https://github.com/eligrey/FileSaver.js#supported-browsers
349+
limitBytes: 10 * 1024 * 1024
350+
}, $scope.options);
351+
352+
streamer = DataService.createStream(logSubresource, name, $scope.context, options);
353+
354+
var lastLineNumber = 0;
355+
var addLine = function(text) {
356+
lastLineNumber++;
357+
// Append the line to the document fragment buffer.
358+
buffer.appendChild(buildLogLineNode(lastLineNumber, text));
359+
update();
360+
};
361+
362+
streamer.onMessage(function(msg, raw, cumulativeBytes) {
363+
// ensures the digest loop will catch the state change.
364+
$scope.$evalAsync(function() {
365+
$scope.empty = false;
366+
if($scope.state !== 'logs') {
367+
$scope.state = 'logs';
368+
resizeWhenVisible();
369+
}
370+
});
371+
372+
// Completely empty messages (without even a newline character) should not add lines
373+
if (!msg) {
374+
return;
375+
}
374376

375-
// Warn the user if we might be showing a partial log.
376-
if (!$scope.largeLog && lastLineNumber >= options.tailLines) {
377-
$scope.$evalAsync(function() {
378-
$scope.largeLog = true;
379-
});
380-
}
381-
});
377+
if (options.limitBytes && cumulativeBytes >= options.limitBytes) {
378+
$scope.$evalAsync(function() {
379+
$scope.limitReached = true;
380+
$scope.loading = false;
381+
});
382+
stopStreaming(true);
383+
}
382384

383-
streamer.onClose(function() {
384-
streamer = null;
385-
$scope.$evalAsync(function() {
386-
$scope.autoScrollActive = false;
387-
// - if no logs, they have already been archived.
388-
// - if emptyStateMessage has already been set, it means the onError
389-
// callback has already fired. onError message takes priority in severity.
390-
// - at present we are using the same error message in both onError and onClose
391-
// because we dont have enough information to give the user something better.
392-
if((lastLineNumber === 0) && (!$scope.emptyStateMessage)) {
393-
$scope.state = 'empty';
394-
$scope.emptyStateMessage = 'The logs are no longer available or could not be loaded.';
395-
}
396-
});
385+
addLine(msg);
397386

398-
// Wrap in a timeout so that content displays before we remove the loading ellipses.
399-
$timeout(function() {
400-
$scope.loading = false;
401-
}, 100);
402-
});
387+
// Warn the user if we might be showing a partial log.
388+
if (!$scope.largeLog && lastLineNumber >= options.tailLines) {
389+
$scope.$evalAsync(function() {
390+
$scope.largeLog = true;
391+
});
392+
}
393+
});
403394

404-
streamer.onError(function() {
405-
streamer = null;
406-
$scope.$evalAsync(function() {
407-
angular.extend($scope, {
408-
loading: false,
409-
autoScrollActive: false
395+
streamer.onClose(function() {
396+
streamer = null;
397+
$scope.$evalAsync(function() {
398+
$scope.loading = false;
399+
$scope.autoScrollActive = false;
400+
// - if no logs, they have already been archived.
401+
// - if emptyStateMessage has already been set, it means the onError
402+
// callback has already fired. onError message takes priority in severity.
403+
// - at present we are using the same error message in both onError and onClose
404+
// because we dont have enough information to give the user something better.
405+
if((lastLineNumber === 0) && (!$scope.emptyStateMessage)) {
406+
$scope.state = 'empty';
407+
$scope.emptyStateMessage = 'The logs are no longer available or could not be loaded.';
408+
}
409+
});
410410
});
411-
// if logs err before we get anything, will show an empty state message
412-
if(lastLineNumber === 0) {
413-
$scope.state = 'empty';
414-
$scope.emptyStateMessage = 'The logs are no longer available or could not be loaded.';
415-
} else {
416-
// if logs were running but something went wrong, will
417-
// show what we have & give option to retry
418-
$scope.errorWhileRunning = true;
419-
}
411+
412+
streamer.onError(function() {
413+
streamer = null;
414+
$scope.$evalAsync(function() {
415+
angular.extend($scope, {
416+
loading: false,
417+
autoScrollActive: false
418+
});
419+
// if logs err before we get anything, will show an empty state message
420+
if(lastLineNumber === 0) {
421+
$scope.state = 'empty';
422+
$scope.emptyStateMessage = 'The logs are no longer available or could not be loaded.';
423+
} else {
424+
// if logs were running but something went wrong, will
425+
// show what we have & give option to retry
426+
$scope.errorWhileRunning = true;
427+
}
428+
});
429+
});
430+
431+
streamer.start();
420432
});
421433
});
422-
423-
streamer.start();
424434
};
425435

426436
// Kibana archives -------------------------------------------------

0 commit comments

Comments
 (0)