2017-12-15 21:39:18 +00:00
|
|
|
import { inject as service } from '@ember/service';
|
|
|
|
import { computed } from '@ember/object';
|
2018-12-07 01:11:01 +00:00
|
|
|
import { equal } from '@ember/object/computed';
|
2017-09-19 14:47:10 +00:00
|
|
|
import Model from 'ember-data/model';
|
|
|
|
import attr from 'ember-data/attr';
|
2019-04-16 19:11:43 +00:00
|
|
|
import { belongsTo, hasMany } from 'ember-data/relationships';
|
2017-09-19 14:47:10 +00:00
|
|
|
import { fragment, fragmentArray } from 'ember-data-model-fragments/attributes';
|
2018-07-06 20:38:57 +00:00
|
|
|
import intersection from 'lodash.intersection';
|
2017-09-19 14:47:10 +00:00
|
|
|
import shortUUIDProperty from '../utils/properties/short-uuid';
|
|
|
|
|
2017-10-18 00:48:52 +00:00
|
|
|
const STATUS_ORDER = {
|
|
|
|
pending: 1,
|
|
|
|
running: 2,
|
|
|
|
complete: 3,
|
|
|
|
failed: 4,
|
|
|
|
lost: 5,
|
|
|
|
};
|
|
|
|
|
2017-09-19 14:47:10 +00:00
|
|
|
export default Model.extend({
|
2017-12-15 21:39:18 +00:00
|
|
|
token: service(),
|
2017-10-19 02:04:19 +00:00
|
|
|
|
2017-09-19 14:47:10 +00:00
|
|
|
shortId: shortUUIDProperty('id'),
|
|
|
|
job: belongsTo('job'),
|
|
|
|
node: belongsTo('node'),
|
|
|
|
name: attr('string'),
|
|
|
|
taskGroupName: attr('string'),
|
|
|
|
resources: fragment('resources'),
|
2018-07-19 20:31:39 +00:00
|
|
|
jobVersion: attr('number'),
|
|
|
|
|
2017-09-19 14:47:10 +00:00
|
|
|
modifyIndex: attr('number'),
|
2017-11-30 23:08:31 +00:00
|
|
|
modifyTime: attr('date'),
|
2018-07-19 20:31:39 +00:00
|
|
|
|
|
|
|
createIndex: attr('number'),
|
|
|
|
createTime: attr('date'),
|
2017-09-19 14:47:10 +00:00
|
|
|
|
|
|
|
clientStatus: attr('string'),
|
|
|
|
desiredStatus: attr('string'),
|
2017-10-18 00:48:52 +00:00
|
|
|
statusIndex: computed('clientStatus', function() {
|
2019-03-26 07:46:44 +00:00
|
|
|
return STATUS_ORDER[this.clientStatus] || 100;
|
2017-10-18 00:48:52 +00:00
|
|
|
}),
|
2017-09-19 14:47:10 +00:00
|
|
|
|
2018-12-07 01:11:01 +00:00
|
|
|
isRunning: equal('clientStatus', 'running'),
|
|
|
|
|
2018-04-25 22:50:15 +00:00
|
|
|
// When allocations are server-side rescheduled, a paper trail
|
|
|
|
// is left linking all reschedule attempts.
|
|
|
|
previousAllocation: belongsTo('allocation', { inverse: 'nextAllocation' }),
|
|
|
|
nextAllocation: belongsTo('allocation', { inverse: 'previousAllocation' }),
|
2018-05-02 18:21:50 +00:00
|
|
|
|
2019-04-16 19:11:43 +00:00
|
|
|
preemptedAllocations: hasMany('allocation', { inverse: 'preemptedByAllocation' }),
|
|
|
|
preemptedByAllocation: belongsTo('allocation', { inverse: 'preemptedAllocations' }),
|
2019-04-16 20:23:16 +00:00
|
|
|
wasPreempted: attr('boolean'),
|
2019-04-16 19:11:43 +00:00
|
|
|
|
2018-05-02 18:21:50 +00:00
|
|
|
followUpEvaluation: belongsTo('evaluation'),
|
2018-04-25 22:50:15 +00:00
|
|
|
|
2017-10-30 21:16:08 +00:00
|
|
|
statusClass: computed('clientStatus', function() {
|
|
|
|
const classMap = {
|
|
|
|
pending: 'is-pending',
|
|
|
|
running: 'is-primary',
|
|
|
|
complete: 'is-complete',
|
|
|
|
failed: 'is-error',
|
|
|
|
lost: 'is-light',
|
|
|
|
};
|
|
|
|
|
2019-03-26 07:46:44 +00:00
|
|
|
return classMap[this.clientStatus] || 'is-dark';
|
2017-10-30 21:16:08 +00:00
|
|
|
}),
|
|
|
|
|
2017-09-19 14:47:10 +00:00
|
|
|
taskGroup: computed('taskGroupName', 'job.taskGroups.[]', function() {
|
|
|
|
const taskGroups = this.get('job.taskGroups');
|
2019-03-26 07:46:44 +00:00
|
|
|
return taskGroups && taskGroups.findBy('name', this.taskGroupName);
|
2017-09-19 14:47:10 +00:00
|
|
|
}),
|
|
|
|
|
2018-05-10 00:04:45 +00:00
|
|
|
unhealthyDrivers: computed('taskGroup.drivers.[]', 'node.unhealthyDriverNames.[]', function() {
|
|
|
|
const taskGroupUnhealthyDrivers = this.get('taskGroup.drivers');
|
|
|
|
const nodeUnhealthyDrivers = this.get('node.unhealthyDriverNames');
|
|
|
|
|
|
|
|
if (taskGroupUnhealthyDrivers && nodeUnhealthyDrivers) {
|
|
|
|
return intersection(taskGroupUnhealthyDrivers, nodeUnhealthyDrivers);
|
|
|
|
}
|
|
|
|
|
|
|
|
return [];
|
|
|
|
}),
|
|
|
|
|
2017-09-19 14:47:10 +00:00
|
|
|
states: fragmentArray('task-state'),
|
2018-04-25 22:50:15 +00:00
|
|
|
rescheduleEvents: fragmentArray('reschedule-event'),
|
2018-05-02 18:21:50 +00:00
|
|
|
|
|
|
|
hasRescheduleEvents: computed('rescheduleEvents.length', 'nextAllocation', function() {
|
2019-03-26 07:46:44 +00:00
|
|
|
return this.get('rescheduleEvents.length') > 0 || this.nextAllocation;
|
2018-05-02 18:21:50 +00:00
|
|
|
}),
|
2018-05-03 19:17:06 +00:00
|
|
|
|
|
|
|
hasStoppedRescheduling: computed(
|
|
|
|
'nextAllocation',
|
|
|
|
'clientStatus',
|
2019-03-25 22:54:48 +00:00
|
|
|
'followUpEvaluation.content',
|
2018-05-03 19:17:06 +00:00
|
|
|
function() {
|
2019-04-16 19:11:43 +00:00
|
|
|
return (
|
|
|
|
!this.get('nextAllocation.content') &&
|
|
|
|
!this.get('followUpEvaluation.content') &&
|
|
|
|
this.clientStatus === 'failed'
|
|
|
|
);
|
2018-05-03 19:17:06 +00:00
|
|
|
}
|
|
|
|
),
|
2019-05-17 00:43:00 +00:00
|
|
|
|
|
|
|
stop() {
|
|
|
|
return this.store.adapterFor('allocation').stop(this);
|
|
|
|
},
|
|
|
|
|
2019-05-20 22:27:20 +00:00
|
|
|
restart(taskName) {
|
|
|
|
return this.store.adapterFor('allocation').restart(this, taskName);
|
2019-05-17 00:43:00 +00:00
|
|
|
},
|
2017-09-19 14:47:10 +00:00
|
|
|
});
|