mirror of
https://github.com/ansible/awx.git
synced 2026-01-13 11:00:03 -03:30
updates to job results performance
This commit is contained in:
parent
037d8a1ee4
commit
55034f1a78
@ -2234,3 +2234,8 @@ a:hover {
|
||||
padding-left: 2px;
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
button[disabled],
|
||||
html input[disabled] {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
@ -35,11 +35,14 @@
|
||||
<div class="JobResultsStdOut-numberColumnPreload"></div>
|
||||
<div id='lineAnchor' class="JobResultsStdOut-lineAnchor"></div>
|
||||
<div class="JobResultsStdOut-aLineOfStdOut"
|
||||
ng-show="tooManyEvents">
|
||||
ng-show="tooManyEvents || tooManyPastEvents">
|
||||
<div class="JobResultsStdOut-lineNumberColumn">
|
||||
<span class="JobResultsStdOut-lineExpander"> </span>
|
||||
</div>
|
||||
<div class="JobResultsStdOut-stdoutColumn JobResultsStdOut-stdoutColumn--tooMany">The standard output is too large to display. Please specify additional filters to narrow the standard out.</div>
|
||||
<div class="JobResultsStdOut-stdoutColumn JobResultsStdOut-stdoutColumn--tooMany"
|
||||
ng-show="tooManyEvents">The standard output is too large to display. Please specify additional filters to narrow the standard out.</div>
|
||||
<div class="JobResultsStdOut-stdoutColumn JobResultsStdOut-stdoutColumn--tooMany"
|
||||
ng-show="tooManyPastEvents">Too much previous output to display. Showing running standard output.</div>
|
||||
</div>
|
||||
<div id="followAnchor"
|
||||
class="JobResultsStdOut-followAnchor">
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count', '$scope', 'ParseTypeChange', 'ParseVariableString', 'jobResultsService', 'eventQueue', '$compile', '$log', 'Dataset', '$q', 'Rest', '$state', 'QuerySet', '$rootScope', 'moment', 'i18n',
|
||||
function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, $log, Dataset, $q, Rest, $state, QuerySet, $rootScope, moment, i18n) {
|
||||
export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count', '$scope', 'ParseTypeChange', 'ParseVariableString', 'jobResultsService', 'eventQueue', '$compile', '$log', 'Dataset', '$q', 'Rest', '$state', 'QuerySet', '$rootScope', 'moment', '$stateParams', 'i18n',
|
||||
function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, $log, Dataset, $q, Rest, $state, QuerySet, $rootScope, moment, $stateParams, i18n) {
|
||||
var toDestroy = [];
|
||||
var cancelRequests = false;
|
||||
|
||||
@ -9,6 +9,25 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy
|
||||
// this allows you to manage the timing of rest-call based events as
|
||||
// filters are updated. see processPage for more info
|
||||
var currentContext = 1;
|
||||
$scope.firstCounterFromSocket = -1;
|
||||
|
||||
// if the user enters the page mid-run, reset the search to include a param
|
||||
// to only grab events less than the first counter from the websocket events
|
||||
toDestroy.push($scope.$watch('firstCounterFromSocket', function(counter) {
|
||||
if (counter > -1) {
|
||||
// make it so that the search include a counter less than the
|
||||
// first counter from the socket
|
||||
let params = _.cloneDeep($stateParams.job_event_search);
|
||||
params.counter__lte = "" + counter;
|
||||
|
||||
Dataset = QuerySet.search(jobData.related.job_events,
|
||||
params);
|
||||
|
||||
Dataset.then(function(actualDataset) {
|
||||
$scope.job_event_dataset = actualDataset.data;
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
// used for tag search
|
||||
$scope.job_event_dataset = Dataset.data;
|
||||
@ -424,57 +443,87 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy
|
||||
|
||||
// grab non-header recap lines
|
||||
toDestroy.push($scope.$watch('job_event_dataset', function(val) {
|
||||
eventQueue.initialize();
|
||||
if (val) {
|
||||
eventQueue.initialize();
|
||||
|
||||
Object.keys($scope.events)
|
||||
.forEach(v => {
|
||||
// dont destroy scope events for skeleton lines
|
||||
let name = $scope.events[v].event.name;
|
||||
Object.keys($scope.events)
|
||||
.forEach(v => {
|
||||
// dont destroy scope events for skeleton lines
|
||||
let name = $scope.events[v].event.name;
|
||||
|
||||
if (!(name === "playbook_on_play_start" ||
|
||||
name === "playbook_on_task_start" ||
|
||||
name === "playbook_on_stats")) {
|
||||
$scope.events[v].$destroy();
|
||||
$scope.events[v] = null;
|
||||
delete $scope.events[v];
|
||||
if (!(name === "playbook_on_play_start" ||
|
||||
name === "playbook_on_task_start" ||
|
||||
name === "playbook_on_stats")) {
|
||||
$scope.events[v].$destroy();
|
||||
$scope.events[v] = null;
|
||||
delete $scope.events[v];
|
||||
}
|
||||
});
|
||||
|
||||
// pause websocket events from coming in to the pane
|
||||
$scope.gotPreviouslyRanEvents = $q.defer();
|
||||
currentContext += 1;
|
||||
|
||||
let context = currentContext;
|
||||
|
||||
$( ".JobResultsStdOut-aLineOfStdOut.not_skeleton" ).remove();
|
||||
$scope.hasSkeleton.promise.then(() => {
|
||||
if (val.count > parseInt(val.maxEvents)) {
|
||||
$(".header_task").hide();
|
||||
$(".header_play").hide();
|
||||
$scope.standardOutTooltip = '<div class="JobResults-downloadTooLarge"><div>' +
|
||||
i18n._('The output is too large to display. Please download.') +
|
||||
'</div>' +
|
||||
'<div class="JobResults-downloadTooLarge--icon">' +
|
||||
'<span class="fa-stack fa-lg">' +
|
||||
'<i class="fa fa-circle fa-stack-1x"></i>' +
|
||||
'<i class="fa fa-stack-1x icon-job-stdout-download-tooltip"></i>' +
|
||||
'</span>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
|
||||
if ($scope.job_status === "successful" ||
|
||||
$scope.job_status === "failed" ||
|
||||
$scope.job_status === "error" ||
|
||||
$scope.job_status === "canceled") {
|
||||
$scope.tooManyEvents = true;
|
||||
$scope.tooManyPastEvents = false;
|
||||
} else {
|
||||
$scope.tooManyPastEvents = true;
|
||||
$scope.tooManyEvents = false;
|
||||
$scope.gotPreviouslyRanEvents.resolve("");
|
||||
}
|
||||
} else {
|
||||
$(".header_task").show();
|
||||
$(".header_play").show();
|
||||
$scope.tooManyEvents = false;
|
||||
$scope.tooManyPastEvents = false;
|
||||
processPage(val, context);
|
||||
}
|
||||
});
|
||||
|
||||
// pause websocket events from coming in to the pane
|
||||
$scope.gotPreviouslyRanEvents = $q.defer();
|
||||
currentContext += 1;
|
||||
|
||||
let context = currentContext;
|
||||
|
||||
$( ".JobResultsStdOut-aLineOfStdOut.not_skeleton" ).remove();
|
||||
$scope.hasSkeleton.promise.then(() => {
|
||||
if (val.count > parseInt(val.maxEvents)) {
|
||||
$(".header_task").hide();
|
||||
$(".header_play").hide();
|
||||
$scope.tooManyEvents = true;
|
||||
$scope.standardOutTooltip = '<div class="JobResults-downloadTooLarge"><div>' +
|
||||
i18n._('The output is too large to display. Please download.') +
|
||||
'</div>' +
|
||||
'<div class="JobResults-downloadTooLarge--icon">' +
|
||||
'<span class="fa-stack fa-lg">' +
|
||||
'<i class="fa fa-circle fa-stack-1x"></i>' +
|
||||
'<i class="fa fa-stack-1x icon-job-stdout-download-tooltip"></i>' +
|
||||
'</span>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
} else {
|
||||
$(".header_task").show();
|
||||
$(".header_play").show();
|
||||
$scope.tooManyEvents = false;
|
||||
processPage(val, context);
|
||||
}
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
|
||||
// Processing of job_events messages from the websocket
|
||||
toDestroy.push($scope.$on(`ws-job_events-${$scope.job.id}`, function(e, data) {
|
||||
|
||||
// use the lowest counter coming over the socket to retrigger pull data
|
||||
// to only be for stuff lower than that id
|
||||
//
|
||||
// only do this for entering the jobs page mid-run (thus the
|
||||
// data.counter is 1 conditional
|
||||
if (data.counter === 1) {
|
||||
$scope.firstCounterFromSocket = -2;
|
||||
}
|
||||
|
||||
if ($scope.firstCounterFromSocket !== -2 &&
|
||||
$scope.firstCounterFromSocket === -1 ||
|
||||
data.counter < $scope.firstCounterFromSocket) {
|
||||
$scope.firstCounterFromSocket = data.counter;
|
||||
}
|
||||
|
||||
$q.all([$scope.gotPreviouslyRanEvents.promise,
|
||||
$scope.hasSkeleton.promise]).then(() => {
|
||||
// put the line in the
|
||||
|
||||
@ -506,7 +506,9 @@
|
||||
list="list"
|
||||
collection="job_events"
|
||||
dataset="job_event_dataset"
|
||||
search-tags="searchTags">
|
||||
search-tags="searchTags"
|
||||
disable-search="job_status == 'running' ||
|
||||
job_status=='pending'">
|
||||
</smart-search>
|
||||
<job-results-standard-out></job-results-standard-out>
|
||||
</div>
|
||||
|
||||
@ -6,6 +6,12 @@
|
||||
|
||||
import {templateUrl} from '../shared/template-url/template-url.factory';
|
||||
|
||||
const defaultParams = {
|
||||
page_size: "200",
|
||||
order_by: 'start_line',
|
||||
not__event__in: 'playbook_on_start,playbook_on_play_start,playbook_on_task_start,playbook_on_stats'
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'jobDetail',
|
||||
url: '/jobs/{id: int}',
|
||||
@ -24,11 +30,7 @@ export default {
|
||||
},
|
||||
params: {
|
||||
job_event_search: {
|
||||
value: {
|
||||
page_size: 100,
|
||||
order_by: 'id',
|
||||
not__event__in: 'playbook_on_start,playbook_on_play_start,playbook_on_task_start,playbook_on_stats'
|
||||
},
|
||||
value: defaultParams,
|
||||
dynamic: true,
|
||||
squash: ''
|
||||
}
|
||||
@ -56,7 +58,7 @@ export default {
|
||||
// flashing as rest data comes in. If the job is finished and
|
||||
// there's a playbook_on_stats event, go ahead and resolve the count
|
||||
// so you don't get that flashing!
|
||||
count: ['jobData', 'jobResultsService', 'Rest', '$q', function(jobData, jobResultsService, Rest, $q) {
|
||||
count: ['jobData', 'jobResultsService', 'Rest', '$q', '$stateParams', '$state', function(jobData, jobResultsService, Rest, $q, $stateParams, $state) {
|
||||
var defer = $q.defer();
|
||||
if (jobData.finished) {
|
||||
// if the job is finished, grab the playbook_on_stats
|
||||
@ -92,6 +94,15 @@ export default {
|
||||
}, countFinished: false});
|
||||
});
|
||||
} else {
|
||||
// make sure to not include any extra
|
||||
// search params for a running job (because we can't filter
|
||||
// incoming job events)
|
||||
if (!_.isEqual($stateParams.job_event_search, defaultParams)) {
|
||||
let params = _.cloneDeep($stateParams);
|
||||
params.job_event_search = defaultParams;
|
||||
$state.go('.', params, { reload: true });
|
||||
}
|
||||
|
||||
// job isn't finished so just send an empty count and read
|
||||
// from events
|
||||
defer.resolve({val: {
|
||||
|
||||
@ -15,6 +15,7 @@ export default ['templateUrl',
|
||||
dataset: '=',
|
||||
collection: '=',
|
||||
searchTags: '=',
|
||||
disableSearch: '='
|
||||
},
|
||||
controller: 'SmartSearchController',
|
||||
templateUrl: templateUrl('shared/smart-search/smart-search')
|
||||
|
||||
@ -4,7 +4,8 @@
|
||||
<div class="SmartSearch-searchTermContainer">
|
||||
<!-- string search input -->
|
||||
<form name="smartSearch" class="SmartSearch-form" aw-enter-key="add(searchTerm)" novalidate>
|
||||
<input class="SmartSearch-input" ng-model="searchTerm" placeholder="Search">
|
||||
<input class="SmartSearch-input" ng-model="searchTerm" placeholder="{{disableSearch ? 'Cannot search running job' : 'Search'}}"
|
||||
ng-disabled="disableSearch">
|
||||
</form>
|
||||
<div type="submit" class="SmartSearch-searchButton" ng-disabled="!searchTerm" ng-click="add(searchTerm)">
|
||||
<i class="fa fa-search"></i>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user