Periodically check item status if it in transition state

Several Angular based dashboards, such as images and snapshots,
not regenerated after some item on this page changes its status
from transition state.
For example, an image may be shown forever in the "Creating" state
with running progress bar. To improve UI this patch re-upload items
list until some item in transition state.
If status of item changed, then 'trackBy' field changed and
Angular will re-render row with this particular item with
ng-repeat-start directive and won't re-render all entire page.

Change-Id: I2308baebb65b11180d66bd69d834386022c2ad84
Closes-bug: #1797592
This commit is contained in:
BubaVV 2018-10-16 16:34:18 +03:00 committed by Vladislav Kuzmin
parent b65c9c0e57
commit ff4644261f
5 changed files with 34 additions and 9 deletions

View File

@ -27,7 +27,8 @@
'horizon.framework.widgets.magic-search.events',
'horizon.framework.widgets.magic-search.service',
'horizon.framework.util.actions.action-result.service',
'horizon.framework.conf.resource-type-registry.service'
'horizon.framework.conf.resource-type-registry.service',
'horizon.app.core.openstack-service-api.settings'
];
function controller(
@ -37,10 +38,13 @@
magicSearchEvents,
searchService,
actionResultService,
registry
registry,
settings
) {
var ctrl = this;
var lastSearchQuery = {};
var timerRunning = false;
// 'Public' Controller members
ctrl.actionResultHandler = actionResultHandler;
@ -50,6 +54,11 @@
ctrl.items = [];
ctrl.itemsSrc = [];
ctrl.itemInTransitionFunction = itemInTransitionFunction;
ctrl.ajaxPollInterval = 2500;
settings.getSetting('AJAX_POLL_INTERVAL').then(
function (response) {
ctrl.ajaxPollInterval = response;
});
// Watch for changes to search bar
$scope.$on(magicSearchEvents.SERVER_SEARCH_UPDATED, handleServerSearch);
@ -171,6 +180,7 @@
function onLoad(response) {
ctrl.itemsSrc = response.data.items;
timerRunning = false;
}
function actionResultHandler(returnValue) {
@ -236,7 +246,12 @@
}
function itemInTransitionFunction(item) {
return ctrl.resourceType.itemInTransitionFunction(item);
var itemInTransition = ctrl.resourceType.itemInTransitionFunction(item);
if (ctrl.ajaxPollInterval && itemInTransition && !timerRunning) {
timerRunning = true;
setTimeout(listResources, ctrl.ajaxPollInterval);
}
return itemInTransition;
}
}

View File

@ -18,7 +18,8 @@
'use strict';
describe('hz-generic-table controller', function() {
var ctrl, listFunctionDeferred, actionResultDeferred, needsFilterFirstFunctionDeferred, $scope;
var ctrl, listFunctionDeferred, actionResultDeferred,
needsFilterFirstFunctionDeferred, $scope, settingCall;
beforeEach(module('horizon.framework.util'));
beforeEach(module('horizon.framework.conf'));
@ -65,9 +66,16 @@
spyOn(resourceType, 'list').and.returnValue(listFunctionDeferred.promise);
spyOn(registry, 'getResourceType').and.returnValue(resourceType);
var settings = {
getSetting: function() {
settingCall = $q.defer();
return settingCall.promise;
}
};
ctrl = $controller('horizon.framework.widgets.table.ResourceTableController', {
$scope: $scope,
'horizon.framework.conf.resource-type-registry.service': registry},
'horizon.framework.conf.resource-type-registry.service': registry,
'horizon.app.core.openstack-service-api.settings': settings},
{resourceTypeName: 'OS::Test::Example'});
$scope.ctrl = ctrl;
$scope.$apply();

View File

@ -43,7 +43,9 @@ class Settings(generic.View):
'HORIZON_IMAGES_UPLOAD_MODE': api.glance.get_image_upload_mode(),
'HORIZON_ACTIVE_IMAGE_VERSION': str(api.glance.VERSIONS.active),
'IMAGES_ALLOW_LOCATION': getattr(settings, 'IMAGES_ALLOW_LOCATION',
False)
False),
'AJAX_POLL_INTERVAL': settings.HORIZON_CONFIG.get(
'ajax_poll_interval', 2500)
}
@rest_utils.ajax()

View File

@ -132,7 +132,7 @@
return {data: {items: response.data.items.map(modifyImage)}};
function modifyImage(image) {
image.trackBy = image.id + image.updated_at;
image.trackBy = image.id + image.updated_at + image.status;
image.apiVersion = version;
image.visibility = $filter('imageVisibility')(image, projectId);
image.name = image.name || image.id;

View File

@ -95,11 +95,11 @@
spyOn(glance, 'getVersion').and.returnValue(deferredVersion.promise);
spyOn(session, 'get').and.returnValue(deferredSession.promise);
var result = service.getImagesPromise({});
deferred.resolve({data: {items: [{id: 1, updated_at: 'jul1'}]}});
deferred.resolve({data: {items: [{id: 1, updated_at: 'jul1', status: 'active'}]}});
deferredVersion.resolve({data: {version: '2'}});
deferredSession.resolve({project_id: '12'});
$timeout.flush();
expect(result.$$state.value.data.items[0].trackBy).toBe('1jul1');
expect(result.$$state.value.data.items[0].trackBy).toBe('1jul1active');
}));
});