mirror of
https://github.com/ansible/awx.git
synced 2026-03-07 19:51:08 -03:30
fix job details memory leaks
This commit is contained in:
@@ -15,7 +15,7 @@ export default [ 'templateUrl',
|
|||||||
link: function(scope) {
|
link: function(scope) {
|
||||||
// as count is changed by event data coming in,
|
// as count is changed by event data coming in,
|
||||||
// update the host status bar
|
// update the host status bar
|
||||||
scope.$watch('count', function(val) {
|
var toDestroy = scope.$watch('count', function(val) {
|
||||||
if (val) {
|
if (val) {
|
||||||
Object.keys(val).forEach(key => {
|
Object.keys(val).forEach(key => {
|
||||||
// reposition the hosts status bar by setting
|
// reposition the hosts status bar by setting
|
||||||
@@ -38,6 +38,10 @@ export default [ 'templateUrl',
|
|||||||
.filter(key => (val[key] > 0)).length > 0);
|
.filter(key => (val[key] > 0)).length > 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
scope.$on('$destroy', function(){
|
||||||
|
toDestroy();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}];
|
}];
|
||||||
|
|||||||
@@ -12,6 +12,18 @@ export default [ 'templateUrl', '$timeout', '$location', '$anchorScroll',
|
|||||||
templateUrl: templateUrl('job-results/job-results-stdout/job-results-stdout'),
|
templateUrl: templateUrl('job-results/job-results-stdout/job-results-stdout'),
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
link: function(scope, element) {
|
link: function(scope, element) {
|
||||||
|
var toDestroy = [],
|
||||||
|
resizer,
|
||||||
|
scrollWatcher;
|
||||||
|
|
||||||
|
scope.$on('$destroy', function(){
|
||||||
|
$(window).off("resize", resizer);
|
||||||
|
$(window).off("scroll", scrollWatcher);
|
||||||
|
$(".JobResultsStdOut-stdoutContainer").off('scroll',
|
||||||
|
scrollWatcher);
|
||||||
|
toDestroy.forEach(v => v());
|
||||||
|
});
|
||||||
|
|
||||||
scope.stdoutContainerAvailable.resolve("container available");
|
scope.stdoutContainerAvailable.resolve("container available");
|
||||||
// utility function used to find the top visible line and
|
// utility function used to find the top visible line and
|
||||||
// parent header in the pane
|
// parent header in the pane
|
||||||
@@ -115,9 +127,15 @@ export default [ 'templateUrl', '$timeout', '$location', '$anchorScroll',
|
|||||||
// stop iterating over the standard out
|
// stop iterating over the standard out
|
||||||
// lines once the first one has been
|
// lines once the first one has been
|
||||||
// found
|
// found
|
||||||
|
|
||||||
|
$this = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
$this = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
$container = null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
visLine: visItem,
|
visLine: visItem,
|
||||||
@@ -131,22 +149,24 @@ export default [ 'templateUrl', '$timeout', '$location', '$anchorScroll',
|
|||||||
} else {
|
} else {
|
||||||
scope.isMobile = false;
|
scope.isMobile = false;
|
||||||
}
|
}
|
||||||
// watch changes to the window size
|
|
||||||
$(window).resize(function() {
|
resizer = function() {
|
||||||
// and update the isMobile var accordingly
|
// and update the isMobile var accordingly
|
||||||
if (window.innerWidth <= 1200 && !scope.isMobile) {
|
if (window.innerWidth <= 1200 && !scope.isMobile) {
|
||||||
scope.isMobile = true;
|
scope.isMobile = true;
|
||||||
} else if (window.innerWidth > 1200 & scope.isMobile) {
|
} else if (window.innerWidth > 1200 & scope.isMobile) {
|
||||||
scope.isMobile = false;
|
scope.isMobile = false;
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
// watch changes to the window size
|
||||||
|
$(window).resize(resizer);
|
||||||
|
|
||||||
var lastScrollTop;
|
var lastScrollTop;
|
||||||
|
|
||||||
var initScrollTop = function() {
|
var initScrollTop = function() {
|
||||||
lastScrollTop = 0;
|
lastScrollTop = 0;
|
||||||
};
|
};
|
||||||
var scrollWatcher = function() {
|
scrollWatcher = function() {
|
||||||
var st = $(this).scrollTop();
|
var st = $(this).scrollTop();
|
||||||
var netScroll = st + $(this).innerHeight();
|
var netScroll = st + $(this).innerHeight();
|
||||||
var fullHeight;
|
var fullHeight;
|
||||||
@@ -178,11 +198,15 @@ export default [ 'templateUrl', '$timeout', '$location', '$anchorScroll',
|
|||||||
}
|
}
|
||||||
|
|
||||||
lastScrollTop = st;
|
lastScrollTop = st;
|
||||||
|
|
||||||
|
st = null;
|
||||||
|
netScroll = null;
|
||||||
|
fullHeight = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
// update scroll watchers when isMobile changes based on
|
// update scroll watchers when isMobile changes based on
|
||||||
// window resize
|
// window resize
|
||||||
scope.$watch('isMobile', function(val) {
|
toDestroy.push(scope.$watch('isMobile', function(val) {
|
||||||
if (val === true) {
|
if (val === true) {
|
||||||
// make sure ^ TOP always shown for mobile
|
// make sure ^ TOP always shown for mobile
|
||||||
scope.stdoutOverflowed = true;
|
scope.stdoutOverflowed = true;
|
||||||
@@ -204,7 +228,7 @@ export default [ 'templateUrl', '$timeout', '$location', '$anchorScroll',
|
|||||||
$(".JobResultsStdOut-stdoutContainer").on('scroll',
|
$(".JobResultsStdOut-stdoutContainer").on('scroll',
|
||||||
scrollWatcher);
|
scrollWatcher);
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
// called to scroll to follow anchor
|
// called to scroll to follow anchor
|
||||||
scope.followScroll = function() {
|
scope.followScroll = function() {
|
||||||
@@ -237,7 +261,7 @@ export default [ 'templateUrl', '$timeout', '$location', '$anchorScroll',
|
|||||||
|
|
||||||
// if following becomes active, go ahead and get to the bottom
|
// if following becomes active, go ahead and get to the bottom
|
||||||
// of the standard out pane
|
// of the standard out pane
|
||||||
scope.$watch('followEngaged', function(val) {
|
toDestroy.push(scope.$watch('followEngaged', function(val) {
|
||||||
// scroll to follow point if followEngaged is true
|
// scroll to follow point if followEngaged is true
|
||||||
if (val) {
|
if (val) {
|
||||||
scope.followScroll();
|
scope.followScroll();
|
||||||
@@ -251,7 +275,7 @@ export default [ 'templateUrl', '$timeout', '$location', '$anchorScroll',
|
|||||||
scope.followTooltip = "Click to follow standard out as it comes in.";
|
scope.followTooltip = "Click to follow standard out as it comes in.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
// follow button ng-click function
|
// follow button ng-click function
|
||||||
scope.followToggleClicked = function() {
|
scope.followToggleClicked = function() {
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count', '$scope', 'ParseTypeChange', 'ParseVariableString', 'jobResultsService', 'eventQueue', '$compile', '$log', 'Dataset', '$q', 'Rest', '$state', 'QuerySet', '$rootScope', 'moment',
|
export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count', '$scope', 'ParseTypeChange', 'ParseVariableString', 'jobResultsService', 'eventQueue', '$compile', '$log', 'Dataset', '$q', 'Rest', '$state', 'QuerySet', '$rootScope', 'moment',
|
||||||
function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, $log, Dataset, $q, Rest, $state, QuerySet, $rootScope, moment) {
|
function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, $log, Dataset, $q, Rest, $state, QuerySet, $rootScope, moment) {
|
||||||
|
var toDestroy = [];
|
||||||
|
var cancelRequests = false;
|
||||||
|
|
||||||
// used for tag search
|
// used for tag search
|
||||||
$scope.job_event_dataset = Dataset.data;
|
$scope.job_event_dataset = Dataset.data;
|
||||||
@@ -66,14 +68,14 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy
|
|||||||
|
|
||||||
// update label in left pane and tooltip in right pane when the job_status
|
// update label in left pane and tooltip in right pane when the job_status
|
||||||
// changes
|
// changes
|
||||||
$scope.$watch('job_status', function(status) {
|
toDestroy.push($scope.$watch('job_status', function(status) {
|
||||||
if (status) {
|
if (status) {
|
||||||
$scope.status_label = $scope.jobOptions.status.choices
|
$scope.status_label = $scope.jobOptions.status.choices
|
||||||
.filter(val => val[0] === status)
|
.filter(val => val[0] === status)
|
||||||
.map(val => val[1])[0];
|
.map(val => val[1])[0];
|
||||||
$scope.status_tooltip = "Job " + $scope.status_label;
|
$scope.status_tooltip = "Job " + $scope.status_label;
|
||||||
}
|
}
|
||||||
});
|
}));
|
||||||
|
|
||||||
// update the job_status value. Use the cached rootScope value if there
|
// update the job_status value. Use the cached rootScope value if there
|
||||||
// is one. This is a workaround when the rest call for the jobData is
|
// is one. This is a workaround when the rest call for the jobData is
|
||||||
@@ -278,6 +280,9 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy
|
|||||||
.stdout)($scope.events[mungedEvent
|
.stdout)($scope.events[mungedEvent
|
||||||
.counter]));
|
.counter]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
classList = null;
|
||||||
|
putIn = null;
|
||||||
} else {
|
} else {
|
||||||
// this is a header or recap line, so just
|
// this is a header or recap line, so just
|
||||||
// append to the bottom
|
// append to the bottom
|
||||||
@@ -368,7 +373,7 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy
|
|||||||
delete event.event;
|
delete event.event;
|
||||||
processEvent(event);
|
processEvent(event);
|
||||||
});
|
});
|
||||||
if (events.next) {
|
if (events.next && !cancelRequests) {
|
||||||
getEvents(events.next);
|
getEvents(events.next);
|
||||||
} else {
|
} else {
|
||||||
// put those paused events into the pane
|
// put those paused events into the pane
|
||||||
@@ -378,7 +383,7 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy
|
|||||||
};
|
};
|
||||||
|
|
||||||
// grab non-header recap lines
|
// grab non-header recap lines
|
||||||
$scope.$watch('job_event_dataset', function(val) {
|
toDestroy.push($scope.$watch('job_event_dataset', function(val) {
|
||||||
// pause websocket events from coming in to the pane
|
// pause websocket events from coming in to the pane
|
||||||
$scope.gotPreviouslyRanEvents = $q.defer();
|
$scope.gotPreviouslyRanEvents = $q.defer();
|
||||||
|
|
||||||
@@ -391,19 +396,19 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy
|
|||||||
delete event.event;
|
delete event.event;
|
||||||
processEvent(event);
|
processEvent(event);
|
||||||
});
|
});
|
||||||
if (val.next) {
|
if (val.next && !cancelRequests) {
|
||||||
getEvents(val.next);
|
getEvents(val.next);
|
||||||
} else {
|
} else {
|
||||||
// put those paused events into the pane
|
// put those paused events into the pane
|
||||||
$scope.gotPreviouslyRanEvents.resolve("");
|
$scope.gotPreviouslyRanEvents.resolve("");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Processing of job_events messages from the websocket
|
// Processing of job_events messages from the websocket
|
||||||
$scope.$on(`ws-job_events-${$scope.job.id}`, function(e, data) {
|
toDestroy.push($scope.$on(`ws-job_events-${$scope.job.id}`, function(e, data) {
|
||||||
$q.all([$scope.gotPreviouslyRanEvents.promise,
|
$q.all([$scope.gotPreviouslyRanEvents.promise,
|
||||||
$scope.hasSkeleton.promise]).then(() => {
|
$scope.hasSkeleton.promise]).then(() => {
|
||||||
var url = Dataset
|
var url = Dataset
|
||||||
@@ -446,10 +451,10 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
}));
|
||||||
|
|
||||||
// Processing of job-status messages from the websocket
|
// Processing of job-status messages from the websocket
|
||||||
$scope.$on(`ws-jobs`, function(e, data) {
|
toDestroy.push($scope.$on(`ws-jobs`, function(e, data) {
|
||||||
if (parseInt(data.unified_job_id, 10) ===
|
if (parseInt(data.unified_job_id, 10) ===
|
||||||
parseInt($scope.job.id,10)) {
|
parseInt($scope.job.id,10)) {
|
||||||
// controller is defined, so set the job_status
|
// controller is defined, so set the job_status
|
||||||
@@ -477,5 +482,18 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy
|
|||||||
// for this job. cache the socket status on root scope
|
// for this job. cache the socket status on root scope
|
||||||
$rootScope['lastSocketStatus' + data.unified_job_id] = data.status;
|
$rootScope['lastSocketStatus' + data.unified_job_id] = data.status;
|
||||||
}
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
$scope.$on('$destroy', function(){
|
||||||
|
cancelRequests = true;
|
||||||
|
eventQueue.initialize();
|
||||||
|
Object.keys($scope.events)
|
||||||
|
.forEach(v => {
|
||||||
|
$scope.events[v].$destroy();
|
||||||
|
$scope.events[v] = null;
|
||||||
|
});
|
||||||
|
$scope.events = {};
|
||||||
|
clearInterval(elapsedInterval);
|
||||||
|
toDestroy.forEach(v => v());
|
||||||
});
|
});
|
||||||
}];
|
}];
|
||||||
|
|||||||
@@ -185,7 +185,6 @@ export default ['$log', 'moment', function($log, moment){
|
|||||||
data-uuid="${clickClass}">
|
data-uuid="${clickClass}">
|
||||||
</i>
|
</i>
|
||||||
</span>`;
|
</span>`;
|
||||||
// console.log(expandDom);
|
|
||||||
return expandDom;
|
return expandDom;
|
||||||
} else {
|
} else {
|
||||||
// non-header lines don't get an expander
|
// non-header lines don't get an expander
|
||||||
|
|||||||
Reference in New Issue
Block a user