Refactor job summary to a relationship
Now that blocking queries are going to be in play, We can no longer pretend the two requests are one, since they have independent nomad indices.
This commit is contained in:
parent
2228e1fd0c
commit
e7796ccaee
|
@ -1,5 +1,4 @@
|
|||
import { inject as service } from '@ember/service';
|
||||
import RSVP from 'rsvp';
|
||||
import { assign } from '@ember/polyfills';
|
||||
import ApplicationAdapter from './application';
|
||||
|
||||
|
@ -26,28 +25,17 @@ export default ApplicationAdapter.extend({
|
|||
});
|
||||
},
|
||||
|
||||
findRecord(store, { modelName }, id, snapshot) {
|
||||
// To make a findRecord response reflect the findMany response, the JobSummary
|
||||
// from /summary needs to be stitched into the response.
|
||||
findRecordSummary(modelName, name, snapshot, namespaceQuery) {
|
||||
return this.ajax(`${this.buildURL(modelName, name, snapshot, 'findRecord')}/summary`, 'GET', {
|
||||
data: assign(this.buildQuery() || {}, namespaceQuery),
|
||||
});
|
||||
},
|
||||
|
||||
// URL is the form of /job/:name?namespace=:namespace with arbitrary additional query params
|
||||
findRecord(store, type, id, snapshot) {
|
||||
const [name, namespace] = JSON.parse(id);
|
||||
const namespaceQuery = namespace && namespace !== 'default' ? { namespace } : {};
|
||||
return RSVP.hash({
|
||||
job: this.ajax(this.buildURL(modelName, name, snapshot, 'findRecord'), 'GET', {
|
||||
data: assign(this.buildQuery() || {}, namespaceQuery),
|
||||
}),
|
||||
summary: this.ajax(
|
||||
`${this.buildURL(modelName, name, snapshot, 'findRecord')}/summary`,
|
||||
'GET',
|
||||
{
|
||||
data: assign(this.buildQuery() || {}, namespaceQuery),
|
||||
}
|
||||
),
|
||||
}).then(({ job, summary }) => {
|
||||
job.JobSummary = summary;
|
||||
return job;
|
||||
});
|
||||
|
||||
return this._super(store, type, name, snapshot, namespaceQuery);
|
||||
},
|
||||
|
||||
findAllocations(job) {
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import { collect, sum } from '@ember/object/computed';
|
||||
import Model from 'ember-data/model';
|
||||
import attr from 'ember-data/attr';
|
||||
import { belongsTo } from 'ember-data/relationships';
|
||||
import { fragmentArray } from 'ember-data-model-fragments/attributes';
|
||||
import sumAggregation from '../utils/properties/sum-aggregation';
|
||||
|
||||
export default Model.extend({
|
||||
job: belongsTo('job'),
|
||||
|
||||
taskGroupSummaries: fragmentArray('task-group-summary'),
|
||||
|
||||
// Aggregate allocation counts across all summaries
|
||||
queuedAllocs: sumAggregation('taskGroupSummaries', 'queuedAllocs'),
|
||||
startingAllocs: sumAggregation('taskGroupSummaries', 'startingAllocs'),
|
||||
runningAllocs: sumAggregation('taskGroupSummaries', 'runningAllocs'),
|
||||
completeAllocs: sumAggregation('taskGroupSummaries', 'completeAllocs'),
|
||||
failedAllocs: sumAggregation('taskGroupSummaries', 'failedAllocs'),
|
||||
lostAllocs: sumAggregation('taskGroupSummaries', 'lostAllocs'),
|
||||
|
||||
allocsList: collect(
|
||||
'queuedAllocs',
|
||||
'startingAllocs',
|
||||
'runningAllocs',
|
||||
'completeAllocs',
|
||||
'failedAllocs',
|
||||
'lostAllocs'
|
||||
),
|
||||
|
||||
totalAllocs: sum('allocsList'),
|
||||
|
||||
pendingChildren: attr('number'),
|
||||
runningChildren: attr('number'),
|
||||
deadChildren: attr('number'),
|
||||
|
||||
childrenList: collect('pendingChildren', 'runningChildren', 'deadChildren'),
|
||||
|
||||
totalChildren: sum('childrenList'),
|
||||
});
|
|
@ -1,10 +1,9 @@
|
|||
import { collect, sum, bool, equal, or } from '@ember/object/computed';
|
||||
import { alias, bool, equal, or } from '@ember/object/computed';
|
||||
import { computed } from '@ember/object';
|
||||
import Model from 'ember-data/model';
|
||||
import attr from 'ember-data/attr';
|
||||
import { belongsTo, hasMany } from 'ember-data/relationships';
|
||||
import { fragmentArray } from 'ember-data-model-fragments/attributes';
|
||||
import sumAggregation from '../utils/properties/sum-aggregation';
|
||||
|
||||
const JOB_TYPES = ['service', 'batch', 'system'];
|
||||
|
||||
|
@ -83,34 +82,21 @@ export default Model.extend({
|
|||
|
||||
datacenters: attr(),
|
||||
taskGroups: fragmentArray('task-group', { defaultValue: () => [] }),
|
||||
taskGroupSummaries: fragmentArray('task-group-summary'),
|
||||
summary: belongsTo('job-summary'),
|
||||
|
||||
// Aggregate allocation counts across all summaries
|
||||
queuedAllocs: sumAggregation('taskGroupSummaries', 'queuedAllocs'),
|
||||
startingAllocs: sumAggregation('taskGroupSummaries', 'startingAllocs'),
|
||||
runningAllocs: sumAggregation('taskGroupSummaries', 'runningAllocs'),
|
||||
completeAllocs: sumAggregation('taskGroupSummaries', 'completeAllocs'),
|
||||
failedAllocs: sumAggregation('taskGroupSummaries', 'failedAllocs'),
|
||||
lostAllocs: sumAggregation('taskGroupSummaries', 'lostAllocs'),
|
||||
|
||||
allocsList: collect(
|
||||
'queuedAllocs',
|
||||
'startingAllocs',
|
||||
'runningAllocs',
|
||||
'completeAllocs',
|
||||
'failedAllocs',
|
||||
'lostAllocs'
|
||||
),
|
||||
|
||||
totalAllocs: sum('allocsList'),
|
||||
|
||||
pendingChildren: attr('number'),
|
||||
runningChildren: attr('number'),
|
||||
deadChildren: attr('number'),
|
||||
|
||||
childrenList: collect('pendingChildren', 'runningChildren', 'deadChildren'),
|
||||
|
||||
totalChildren: sum('childrenList'),
|
||||
// Alias through to the summary, as if there was no relationship
|
||||
taskGroupSummaries: alias('summary.taskGroupSummaries'),
|
||||
queuedAllocs: alias('summary.queuedAllocs'),
|
||||
startingAllocs: alias('summary.startingAllocs'),
|
||||
runningAllocs: alias('summary.runningAllocs'),
|
||||
completeAllocs: alias('summary.completeAllocs'),
|
||||
failedAllocs: alias('summary.failedAllocs'),
|
||||
lostAllocs: alias('summary.lostAllocs'),
|
||||
totalAllocs: alias('summary.totalAllocs'),
|
||||
pendingChildren: alias('summary.pendingChildren'),
|
||||
runningChildren: alias('summary.runningChildren'),
|
||||
deadChildren: alias('summary.deadChildren'),
|
||||
totalChildren: alias('summary.childrenList'),
|
||||
|
||||
version: attr('number'),
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@ import attr from 'ember-data/attr';
|
|||
import { fragmentOwner, fragmentArray } from 'ember-data-model-fragments/attributes';
|
||||
import sumAggregation from '../utils/properties/sum-aggregation';
|
||||
|
||||
const maybe = arr => arr || [];
|
||||
|
||||
export default Fragment.extend({
|
||||
job: fragmentOwner(),
|
||||
|
||||
|
@ -13,7 +15,7 @@ export default Fragment.extend({
|
|||
tasks: fragmentArray('task'),
|
||||
|
||||
allocations: computed('job.allocations.@each.taskGroup', function() {
|
||||
return this.get('job.allocations').filterBy('taskGroupName', this.get('name'));
|
||||
return maybe(this.get('job.allocations')).filterBy('taskGroupName', this.get('name'));
|
||||
}),
|
||||
|
||||
reservedCPU: sumAggregation('tasks', 'reservedCPU'),
|
||||
|
@ -32,6 +34,6 @@ export default Fragment.extend({
|
|||
}),
|
||||
|
||||
summary: computed('job.taskGroupSummaries.[]', function() {
|
||||
return this.get('job.taskGroupSummaries').findBy('name', this.get('name'));
|
||||
return maybe(this.get('job.taskGroupSummaries')).findBy('name', this.get('name'));
|
||||
}),
|
||||
});
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
import { get } from '@ember/object';
|
||||
import ApplicationSerializer from './application';
|
||||
|
||||
export default ApplicationSerializer.extend({
|
||||
normalize(modelClass, hash) {
|
||||
// Transform the map-based Summary object into an array-based
|
||||
// TaskGroupSummary fragment list
|
||||
hash.PlainJobId = hash.JobID;
|
||||
hash.ID = JSON.stringify([hash.JobID, hash.Namespace || 'default']);
|
||||
|
||||
hash.TaskGroupSummaries = Object.keys(get(hash, 'Summary') || {}).map(key => {
|
||||
const allocStats = get(hash, `Summary.${key}`) || {};
|
||||
const summary = { Name: key };
|
||||
|
||||
Object.keys(allocStats).forEach(
|
||||
allocKey => (summary[`${allocKey}Allocs`] = allocStats[allocKey])
|
||||
);
|
||||
|
||||
return summary;
|
||||
});
|
||||
|
||||
// Lift the children stats out of the Children object
|
||||
const childrenStats = get(hash, 'Children');
|
||||
if (childrenStats) {
|
||||
Object.keys(childrenStats).forEach(
|
||||
childrenKey => (hash[`${childrenKey}Children`] = childrenStats[childrenKey])
|
||||
);
|
||||
}
|
||||
|
||||
return this._super(modelClass, hash);
|
||||
},
|
||||
});
|
|
@ -34,27 +34,6 @@ export default ApplicationSerializer.extend({
|
|||
hash.ParameterizedJob = true;
|
||||
}
|
||||
|
||||
// Transform the map-based JobSummary object into an array-based
|
||||
// JobSummary fragment list
|
||||
hash.TaskGroupSummaries = Object.keys(get(hash, 'JobSummary.Summary') || {}).map(key => {
|
||||
const allocStats = get(hash, `JobSummary.Summary.${key}`) || {};
|
||||
const summary = { Name: key };
|
||||
|
||||
Object.keys(allocStats).forEach(
|
||||
allocKey => (summary[`${allocKey}Allocs`] = allocStats[allocKey])
|
||||
);
|
||||
|
||||
return summary;
|
||||
});
|
||||
|
||||
// Lift the children stats out of the JobSummary object
|
||||
const childrenStats = get(hash, 'JobSummary.Children');
|
||||
if (childrenStats) {
|
||||
Object.keys(childrenStats).forEach(
|
||||
childrenKey => (hash[`${childrenKey}Children`] = childrenStats[childrenKey])
|
||||
);
|
||||
}
|
||||
|
||||
return this._super(typeHash, hash);
|
||||
},
|
||||
|
||||
|
@ -68,6 +47,11 @@ export default ApplicationSerializer.extend({
|
|||
.buildURL(modelName, hash.PlainId, hash, 'findRecord');
|
||||
|
||||
return assign(this._super(...arguments), {
|
||||
summary: {
|
||||
links: {
|
||||
related: buildURL(`${jobURL}/summary`, { namespace: namespace }),
|
||||
},
|
||||
},
|
||||
allocations: {
|
||||
links: {
|
||||
related: buildURL(`${jobURL}/allocations`, { namespace: namespace }),
|
||||
|
|
Loading…
Reference in New Issue