Merge pull request #3842 from ryanpetrello/instance-group-order

enforce a stable list order when attaching/detaching instance groups

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
This commit is contained in:
softwarefactory-project-zuul[bot]
2019-05-09 21:04:29 +00:00
committed by GitHub
13 changed files with 537 additions and 39 deletions

View File

@@ -1,5 +1,5 @@
export default
['Rest', function(Rest) {
['$q', 'Rest', function($q, Rest) {
return {
addInstanceGroups: function(url, instance_groups) {
let groups = (instance_groups || []);
@@ -9,33 +9,70 @@ export default
},
editInstanceGroups: function(url, instance_groups) {
Rest.setUrl(url);
let currentGroups = Rest.get()
.then(({data}) => {
return data.results.map((i) => i.id);
return Rest.get()
.then(res => {
const { data: { results = [] } } = res;
const updatedGroupIds = (instance_groups || []).map(({ id }) => id);
const currentGroupIds = results.map(({ id }) => id);
const groupIdsToAssociate = [];
const groupIdsToDisassociate = [];
// loop over the array of currently saved instance group ids - if we encounter
// a difference between the current array and the updated array at a particular
// position, mark it and all remaining currentIds in the array for disassociation.
let disassociateRemainingIds = false;
currentGroupIds.forEach((currentId, position) => {
if (!disassociateRemainingIds && updatedGroupIds[position] !== currentId) {
disassociateRemainingIds = true;
}
if (disassociateRemainingIds) {
groupIdsToDisassociate.push(currentId);
}
});
updatedGroupIds.forEach(updatedId => {
if (groupIdsToDisassociate.includes(updatedId)) {
// we get here if the id was marked for disassociation due to being
// out of order - we'll need to re-associate it.
groupIdsToAssociate.push(updatedId);
} else if (!currentGroupIds.includes(updatedId)) {
// we get here if the id is a new association
groupIdsToAssociate.push(updatedId);
}
});
// convert the id arrays into request data
const groupsToAssociate = groupIdsToAssociate.map(id => ({ id, associate: true}));
const groupsToDisassociate = groupIdsToDisassociate.map(id => ({ id, disassociate: true }));
// make the disassociate request sequence - we need to do these requests
// sequentially to make sure they get processed in the right order so we
// build a promise chain here instead of using .all()
let disassociationPromise = $q.resolve();
groupsToDisassociate.forEach(data => {
disassociationPromise = disassociationPromise.then(() => {
Rest.setUrl(url);
return Rest.post(data);
});
});
// make the disassociate-then-associate request sequence
return disassociationPromise
.then(() => {
// we need to do these requests sequentially to make sure they get
// processed in the right order so we build a promise chain here
// instead of using .all()
let associationPromise = $q.resolve();
groupsToAssociate.forEach(data => {
associationPromise = associationPromise.then(() => {
Rest.setUrl(url);
return Rest.post(data);
});
});
return associationPromise;
});
});
return currentGroups.then(function(current) {
let groupsToAdd = (instance_groups || [])
.map(val => val.id);
let groupsToDisassociate = current
.filter(val => groupsToAdd
.indexOf(val) === -1)
.map(val => ({id: val, disassociate: true}));
let groupsToAssociate = groupsToAdd
.filter(val => current
.indexOf(val) === -1)
.map(val => ({id: val, associate: true}));
let pass = groupsToDisassociate
.concat(groupsToAssociate);
Rest.setUrl(url);
let defers = pass.map((group) => Rest.post(group));
Promise.resolve(defers);
});
}
};
}];
}
};
}];

View File

@@ -532,7 +532,7 @@ export default
var credDefer = MultiCredentialService
.saveRelated(jobTemplateData, $scope.multiCredential.selectedCredentials);
InstanceGroupsService.editInstanceGroups(instance_group_url, $scope.instance_groups)
const instanceGroupDefer = InstanceGroupsService.editInstanceGroups(instance_group_url, $scope.instance_groups)
.catch(({data, status}) => {
ProcessErrors($scope, data, status, form, {
hdr: 'Error!',
@@ -609,7 +609,7 @@ export default
Rest.setUrl(data.related.labels);
var defers = [credDefer];
var defers = [credDefer, instanceGroupDefer];
for (var i = 0; i < toPost.length; i++) {
defers.push(Rest.post(toPost[i]));
}