mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2025-01-20 07:19:18 +01:00
CA-272150: Optimize destination page of cross-pool-migrate wizard. (#1941)
* CA-272150: Optimize destination page of cross-pool-migrate wizard. Signed-off-by: Michael Zhao <michael.zhao@citrix.com>
This commit is contained in:
parent
34ec571fa1
commit
a4aaeb1165
@ -43,8 +43,12 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
|
||||
{
|
||||
private List<VM> selectedVMs;
|
||||
private WizardMode wizardMode;
|
||||
// A 2-level cache to store the result of CrossPoolMigrateCanMigrateFilter.
|
||||
// Cache structure is like: <vm-ref, <host-ref, fault-reason>>.
|
||||
private IDictionary<string, IDictionary<string, string>> migrateFilterCache =
|
||||
new Dictionary<string, IDictionary<string, string>>();
|
||||
|
||||
|
||||
|
||||
public CrossPoolMigrateDestinationPage()
|
||||
: this(null, null, WizardMode.Migrate, null)
|
||||
{
|
||||
@ -142,7 +146,7 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
|
||||
var filters = new List<ReasoningFilter>
|
||||
{
|
||||
new ResidentHostIsSameAsSelectionFilter(xenItem, selectedVMs),
|
||||
new CrossPoolMigrateCanMigrateFilter(xenItem, selectedVMs, wizardMode),
|
||||
new CrossPoolMigrateCanMigrateFilter(xenItem, selectedVMs, wizardMode, migrateFilterCache),
|
||||
new WlbEnabledFilter(xenItem, selectedVMs)
|
||||
};
|
||||
return new DelayLoadingOptionComboBoxItem(xenItem, filters);
|
||||
@ -159,7 +163,7 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard
|
||||
vmList.Add(selectedVMs.Find(vm => vm.opaque_ref == opaqueRef));
|
||||
|
||||
filters.Add(new ResidentHostIsSameAsSelectionFilter(selectedItem.Item, vmList));
|
||||
filters.Add(new CrossPoolMigrateCanMigrateFilter(selectedItem.Item, vmList, wizardMode));
|
||||
filters.Add(new CrossPoolMigrateCanMigrateFilter(selectedItem.Item, vmList, wizardMode, migrateFilterCache));
|
||||
filters.Add(new WlbEnabledFilter(selectedItem.Item, vmList));
|
||||
}
|
||||
|
||||
|
@ -45,17 +45,29 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard.Filters
|
||||
private readonly WizardMode _wizardMode;
|
||||
private string disableReason = string.Empty;
|
||||
private readonly List<VM> preSelectedVMs;
|
||||
private IDictionary<string, IDictionary<string, string>> cache;
|
||||
private bool canceled = false;
|
||||
private static readonly Object cacheLock = new Object();
|
||||
|
||||
public CrossPoolMigrateCanMigrateFilter(IXenObject itemAddedToComboBox, List<VM> preSelectedVMs, WizardMode wizardMode)
|
||||
public CrossPoolMigrateCanMigrateFilter(IXenObject itemAddedToComboBox, List<VM> preSelectedVMs, WizardMode wizardMode, IDictionary<string, IDictionary<string, string>> cache = null)
|
||||
: base(itemAddedToComboBox)
|
||||
{
|
||||
_wizardMode = wizardMode;
|
||||
if (cache == null)
|
||||
this.cache = new Dictionary<string, IDictionary<string, string>>();
|
||||
else
|
||||
this.cache = cache;
|
||||
|
||||
if (preSelectedVMs == null)
|
||||
throw new ArgumentNullException("Pre-selected VMs are null");
|
||||
this.preSelectedVMs = preSelectedVMs;
|
||||
}
|
||||
|
||||
public override void Cancel()
|
||||
{
|
||||
canceled = true;
|
||||
}
|
||||
|
||||
public override bool FailureFound
|
||||
{
|
||||
get
|
||||
@ -73,6 +85,20 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard.Filters
|
||||
|
||||
foreach (VM vm in preSelectedVMs)
|
||||
{
|
||||
if (canceled)
|
||||
return excludedHosts.Count == targets.Count;
|
||||
|
||||
// obtain the cache data for a vm
|
||||
IDictionary<string, string> vmCache;
|
||||
lock (cacheLock)
|
||||
{
|
||||
if (!cache.ContainsKey(vm.opaque_ref))
|
||||
{
|
||||
cache.Add(vm.opaque_ref, new Dictionary<string, string>());
|
||||
}
|
||||
vmCache = cache[vm.opaque_ref];
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//CA-220218: for intra-pool motion of halted VMs we do a move, so no need to assert we can migrate
|
||||
@ -91,6 +117,16 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard.Filters
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vmCache.ContainsKey(host.opaque_ref))
|
||||
{
|
||||
disableReason = vmCache[host.opaque_ref];
|
||||
if (!string.IsNullOrEmpty(disableReason) && !excludedHosts.Contains(host.opaque_ref))
|
||||
{
|
||||
excludedHosts.Add(host.opaque_ref);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
PIF managementPif = host.Connection.Cache.PIFs.First(p => p.management);
|
||||
XenAPI.Network network = host.Connection.Cache.Resolve(managementPif.network);
|
||||
|
||||
@ -103,6 +139,10 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard.Filters
|
||||
GetVdiMap(vm, targetSrs),
|
||||
vm.Connection == host.Connection ? new Dictionary<XenRef<VIF>, XenRef<XenAPI.Network>>() : GetVifMap(vm, targetNetwork),
|
||||
new Dictionary<string, string>());
|
||||
lock (cacheLock)
|
||||
{
|
||||
vmCache.Add(host.opaque_ref, string.Empty);
|
||||
}
|
||||
}
|
||||
catch (Failure failure)
|
||||
{
|
||||
@ -111,8 +151,13 @@ namespace XenAdmin.Wizards.CrossPoolMigrateWizard.Filters
|
||||
else
|
||||
disableReason = failure.Message;
|
||||
|
||||
log.ErrorFormat("VM: {0}, Host: {1} - Reason: {2};", vm.opaque_ref, host.opaque_ref, failure.Message);
|
||||
lock (cacheLock)
|
||||
{
|
||||
vmCache.Add(host.opaque_ref, disableReason.Clone().ToString());
|
||||
}
|
||||
|
||||
log.ErrorFormat("VM: {0}, Host: {1} - Reason: {2};", vm.opaque_ref, host.opaque_ref, failure.Message);
|
||||
|
||||
if (!excludedHosts.Contains(host.opaque_ref))
|
||||
excludedHosts.Add(host.opaque_ref);
|
||||
}
|
||||
|
@ -116,6 +116,12 @@ namespace XenAdmin.Wizards.GenericPages
|
||||
ThreadPool.QueueUserWorkItem(delegate { FetchFailureReasonWithRetry(defaultRetries, defaultTimeOut); });
|
||||
}
|
||||
|
||||
public void CancelFilters()
|
||||
{
|
||||
foreach (ReasoningFilter filter in _filters)
|
||||
filter.Cancel();
|
||||
}
|
||||
|
||||
private void FetchFailureReasonWithRetry(int retries, int timeOut)
|
||||
{
|
||||
string threadFailureReason = Messages.DELAY_LOADED_COMBO_BOX_ITEM_FAILURE_UNKOWN;
|
||||
|
@ -56,5 +56,7 @@ namespace XenAdmin.Wizards.GenericPages
|
||||
ItemToFilterOn = xenObject;
|
||||
return FailureFound;
|
||||
}
|
||||
|
||||
public virtual void Cancel() { }
|
||||
}
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ namespace XenAdmin.Wizards.GenericPages
|
||||
|
||||
public override void PageCancelled()
|
||||
{
|
||||
CancelFilters();
|
||||
Program.Invoke(Program.MainWindow, ClearComboBox);
|
||||
Program.Invoke(Program.MainWindow, ClearDataGridView);
|
||||
ChosenItem = null;
|
||||
@ -404,16 +405,21 @@ namespace XenAdmin.Wizards.GenericPages
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var host in Connection.Cache.Hosts)
|
||||
var sortedHosts = new List<Host>(Connection.Cache.Hosts);
|
||||
sortedHosts.Sort();
|
||||
|
||||
var items = new List<DelayLoadingOptionComboBoxItem>();
|
||||
|
||||
foreach (var host in sortedHosts)
|
||||
{
|
||||
var item = new DelayLoadingOptionComboBoxItem(host, homeserverFilters);
|
||||
item.LoadAndWait();
|
||||
cb.Items.Add(item);
|
||||
|
||||
if (item.Enabled && ((m_selectedObject != null && m_selectedObject.opaque_ref == host.opaque_ref) ||
|
||||
(target != null && target.Item.opaque_ref == host.opaque_ref)))
|
||||
(target != null && target.Item.opaque_ref == host.opaque_ref)))
|
||||
cb.Value = item;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SetComboBoxPreSelection(cb);
|
||||
@ -635,6 +641,17 @@ namespace XenAdmin.Wizards.GenericPages
|
||||
xenConnection.CachePopulated -= xenConnection_CachePopulated;
|
||||
xenConnection.Cache.DeregisterCollectionChanged<Host>(Host_CollectionChangedWithInvoke);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CancelFilters()
|
||||
{
|
||||
foreach (var item in m_comboBoxConnection.Items)
|
||||
{
|
||||
DelayLoadingOptionComboBoxItem comboBoxItem = item as DelayLoadingOptionComboBoxItem;
|
||||
if (comboBoxItem != null)
|
||||
comboBoxItem.CancelFilters();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user