mirror of
https://github.com/ansible/awx.git
synced 2026-03-04 02:01:01 -03:30
Merge pull request #5497 from jlmitch5/fixJobResultsRaceCondition
Fix job results race condition
This commit is contained in:
@@ -2247,6 +2247,10 @@ html input[disabled] {
|
|||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.CodeMirror {
|
||||||
|
font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
|
||||||
|
}
|
||||||
|
|
||||||
.CodeMirror--disabled .CodeMirror.cm-s-default,
|
.CodeMirror--disabled .CodeMirror.cm-s-default,
|
||||||
.CodeMirror--disabled .CodeMirror-line {
|
.CodeMirror--disabled .CodeMirror-line {
|
||||||
background-color: #f6f6f6;
|
background-color: #f6f6f6;
|
||||||
|
|||||||
@@ -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', '$stateParams', 'i18n', 'fieldChoices', 'fieldLabels', 'workflowResultsService',
|
export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count', '$scope', 'ParseTypeChange', 'ParseVariableString', 'jobResultsService', 'eventQueue', '$compile', '$log', 'Dataset', '$q', 'Rest', '$state', 'QuerySet', '$rootScope', 'moment', '$stateParams', 'i18n', 'fieldChoices', 'fieldLabels', 'workflowResultsService', 'statusSocket',
|
||||||
function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, $log, Dataset, $q, Rest, $state, QuerySet, $rootScope, moment, $stateParams, i18n, fieldChoices, fieldLabels, workflowResultsService) {
|
function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, $log, Dataset, $q, Rest, $state, QuerySet, $rootScope, moment, $stateParams, i18n, fieldChoices, fieldLabels, workflowResultsService, statusSocket) {
|
||||||
var toDestroy = [];
|
var toDestroy = [];
|
||||||
var cancelRequests = false;
|
var cancelRequests = false;
|
||||||
var runTimeElapsedTimer = null;
|
var runTimeElapsedTimer = null;
|
||||||
@@ -671,6 +671,14 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy
|
|||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
// get previously set up socket messages from resolve
|
||||||
|
if (statusSocket && statusSocket[0] && statusSocket[0].job_status) {
|
||||||
|
$scope.job_status = statusSocket[0].job_status;
|
||||||
|
}
|
||||||
|
if ($scope.job_status === "running" && !$scope.job.elapsed) {
|
||||||
|
runTimeElapsedTimer = workflowResultsService.createOneSecondTimer(moment(), updateJobElapsedTimer);
|
||||||
|
}
|
||||||
|
|
||||||
// Processing of job-status messages from the websocket
|
// Processing of job-status messages from the websocket
|
||||||
toDestroy.push($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) ===
|
||||||
@@ -678,7 +686,9 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy
|
|||||||
// controller is defined, so set the job_status
|
// controller is defined, so set the job_status
|
||||||
$scope.job_status = data.status;
|
$scope.job_status = data.status;
|
||||||
if (data.status === "running") {
|
if (data.status === "running") {
|
||||||
runTimeElapsedTimer = workflowResultsService.createOneSecondTimer(moment(), updateJobElapsedTimer);
|
if (!runTimeElapsedTimer) {
|
||||||
|
runTimeElapsedTimer = workflowResultsService.createOneSecondTimer(moment(), updateJobElapsedTimer);
|
||||||
|
}
|
||||||
} else if (data.status === "successful" ||
|
} else if (data.status === "successful" ||
|
||||||
data.status === "failed" ||
|
data.status === "failed" ||
|
||||||
data.status === "error" ||
|
data.status === "error" ||
|
||||||
@@ -706,7 +716,14 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
if (statusSocket && statusSocket[1]) {
|
||||||
|
statusSocket[1]();
|
||||||
|
}
|
||||||
|
|
||||||
$scope.$on('$destroy', function(){
|
$scope.$on('$destroy', function(){
|
||||||
|
if (statusSocket && statusSocket[1]) {
|
||||||
|
statusSocket[1]();
|
||||||
|
}
|
||||||
$( ".JobResultsStdOut-aLineOfStdOut" ).remove();
|
$( ".JobResultsStdOut-aLineOfStdOut" ).remove();
|
||||||
cancelRequests = true;
|
cancelRequests = true;
|
||||||
eventQueue.initialize();
|
eventQueue.initialize();
|
||||||
|
|||||||
@@ -36,6 +36,16 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
|
statusSocket: ['$rootScope', '$stateParams', function($rootScope, $stateParams) {
|
||||||
|
var preScope = {};
|
||||||
|
var eventOn = $rootScope.$on(`ws-jobs`, function(e, data) {
|
||||||
|
if (parseInt(data.unified_job_id, 10) ===
|
||||||
|
parseInt($stateParams.id,10)) {
|
||||||
|
preScope.job_status = data.status;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return [preScope, eventOn];
|
||||||
|
}],
|
||||||
// the GET for the particular job
|
// the GET for the particular job
|
||||||
jobData: ['Rest', 'GetBasePath', '$stateParams', '$q', '$state', 'Alert', 'jobResultsService', function(Rest, GetBasePath, $stateParams, $q, $state, Alert, jobResultsService) {
|
jobData: ['Rest', 'GetBasePath', '$stateParams', '$q', '$state', 'Alert', 'jobResultsService', function(Rest, GetBasePath, $stateParams, $q, $state, Alert, jobResultsService) {
|
||||||
return jobResultsService.getJobData($stateParams.id);
|
return jobResultsService.getJobData($stateParams.id);
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ module.exports = function(config) {
|
|||||||
'./client/src/app.js',
|
'./client/src/app.js',
|
||||||
'./node_modules/angular-mocks/angular-mocks.js',
|
'./node_modules/angular-mocks/angular-mocks.js',
|
||||||
{ pattern: './tests/**/*-test.js' },
|
{ pattern: './tests/**/*-test.js' },
|
||||||
{ pattern: './tests/**/*.json', included: false},
|
|
||||||
'client/src/**/*.html'
|
'client/src/**/*.html'
|
||||||
],
|
],
|
||||||
preprocessors: {
|
preprocessors: {
|
||||||
|
|||||||
@@ -5,8 +5,12 @@ describe('Controller: jobResultsController', () => {
|
|||||||
// Setup
|
// Setup
|
||||||
let jobResultsController;
|
let jobResultsController;
|
||||||
|
|
||||||
let jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, eventResolve, populateResolve, $rScope, q, $log, Dataset, Rest, $state, QuerySet, i18n,fieldChoices, fieldLabels, $interval, workflowResultsService;
|
let jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, eventResolve, populateResolve, $rScope, q, $log, Dataset, Rest, $state, QuerySet, i18n,fieldChoices, fieldLabels, $interval, workflowResultsService, statusSocket;
|
||||||
|
|
||||||
|
statusSocket = function() {
|
||||||
|
var fn = function() {};
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
jobData = {
|
jobData = {
|
||||||
related: {}
|
related: {}
|
||||||
};
|
};
|
||||||
@@ -70,6 +74,8 @@ describe('Controller: jobResultsController', () => {
|
|||||||
return jasmine.createSpyObj('workflowResultsService', ['createOneSecondTimer', 'destroyTimer']);
|
return jasmine.createSpyObj('workflowResultsService', ['createOneSecondTimer', 'destroyTimer']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$provide.value('statusSocket', statusSocket);
|
||||||
|
|
||||||
$provide.value('jobData', jobData);
|
$provide.value('jobData', jobData);
|
||||||
$provide.value('jobDataOptions', jobDataOptions);
|
$provide.value('jobDataOptions', jobDataOptions);
|
||||||
$provide.value('jobLabels', jobLabels);
|
$provide.value('jobLabels', jobLabels);
|
||||||
@@ -90,7 +96,7 @@ describe('Controller: jobResultsController', () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let injectVals = () => {
|
let injectVals = () => {
|
||||||
angular.mock.inject((_jobData_, _jobDataOptions_, _jobLabels_, _jobFinished_, _count_, _ParseTypeChange_, _ParseVariableString_, _jobResultsService_, _eventQueue_, _$compile_, $rootScope, $controller, $q, $httpBackend, _$log_, _Dataset_, _Rest_, _$state_, _QuerySet_, _$interval_, _workflowResultsService_) => {
|
angular.mock.inject((_jobData_, _jobDataOptions_, _jobLabels_, _jobFinished_, _count_, _ParseTypeChange_, _ParseVariableString_, _jobResultsService_, _eventQueue_, _$compile_, $rootScope, $controller, $q, $httpBackend, _$log_, _Dataset_, _Rest_, _$state_, _QuerySet_, _$interval_, _workflowResultsService_, _statusSocket_) => {
|
||||||
// when you call $scope.$apply() (which you need to do to
|
// when you call $scope.$apply() (which you need to do to
|
||||||
// to get inside of .then blocks to test), something is
|
// to get inside of .then blocks to test), something is
|
||||||
// causing a request for all static files.
|
// causing a request for all static files.
|
||||||
@@ -127,6 +133,7 @@ describe('Controller: jobResultsController', () => {
|
|||||||
QuerySet = _QuerySet_;
|
QuerySet = _QuerySet_;
|
||||||
$interval = _$interval_;
|
$interval = _$interval_;
|
||||||
workflowResultsService = _workflowResultsService_;
|
workflowResultsService = _workflowResultsService_;
|
||||||
|
statusSocket = _statusSocket_;
|
||||||
|
|
||||||
jobResultsService.getEvents.and
|
jobResultsService.getEvents.and
|
||||||
.returnValue(eventResolve);
|
.returnValue(eventResolve);
|
||||||
@@ -157,7 +164,8 @@ describe('Controller: jobResultsController', () => {
|
|||||||
Dataset: Dataset,
|
Dataset: Dataset,
|
||||||
Rest: Rest,
|
Rest: Rest,
|
||||||
$state: $state,
|
$state: $state,
|
||||||
QuerySet: QuerySet
|
QuerySet: QuerySet,
|
||||||
|
statusSocket: statusSocket
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user