CA-107917: XOP-373: When rolling out a XD desktop group, SR storage tab becomes unusuable in XC.

The logic to determine which rows have to be added/updated/removed has been moved to a separate thread. This improved the performance as the UI thread is blocked only to refresh rows in the dataGridView.

Signed-off-by: Adrian Jachacy <Adrian.Jachacy@citrix.com>
This commit is contained in:
Adrian Jachacy 2013-07-16 15:41:55 +01:00
parent 0927fd02c8
commit 71eea27965

View File

@ -34,6 +34,7 @@ using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Drawing; using System.Drawing;
using System.Linq; using System.Linq;
using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using XenAdmin.Controls; using XenAdmin.Controls;
@ -51,7 +52,7 @@ namespace XenAdmin.TabPages
private SR sr; private SR sr;
private readonly DataGridViewColumn sizeColumn; private readonly DataGridViewColumn sizeColumn;
private readonly DataGridViewColumn storageLinkVolumeColumn; private readonly DataGridViewColumn storageLinkVolumeColumn;
private bool rebuildRequired = false; private bool rebuildRequired;
public SrStoragePage() public SrStoragePage()
{ {
@ -127,41 +128,29 @@ namespace XenAdmin.TabPages
} }
} }
private void BuildList() private void RefreshDataGridView(VDIsData data)
{ {
dataGridViewVDIs.SuspendLayout(); dataGridViewVDIs.SuspendLayout();
try try
{ {
if (sr == null) storageLinkVolumeColumn.Visible = data.ShowStorageLink;
return;
List<VDI> vdis = // Update existing rows
sr.Connection.ResolveAll(sr.VDIs).Where( foreach (var vdiRow in data.VdiRowsToUpdate)
vdi => {
vdi.Show(Properties.Settings.Default.ShowHiddenVMs && !vdi.IsAnIntermediateStorageMotionSnapshot)) vdiRow.RefreshRowDetails(data.ShowStorageLink);
.ToList(); }
List<VDIRow> vdisToRemove = // Remove rows for deleted VDIs
dataGridViewVDIs.Rows.OfType<VDIRow>().Where(vdiRow => !vdis.Contains(vdiRow.VDI)).OrderByDescending(row => row.Index).ToList(); foreach (var vdiRow in data.VdiRowsToRemove)
foreach (var vdiRow in vdisToRemove)
{ {
dataGridViewVDIs.Rows.RemoveAt(vdiRow.Index); dataGridViewVDIs.Rows.RemoveAt(vdiRow.Index);
} }
storageLinkVolumeColumn.Visible = vdis.Find(v => v.sm_config.ContainsKey("SVID")) != null; // Add rows for new VDIs
foreach (var vdi in data.VdisToAdd)
foreach (VDI vdi in vdis)
{ {
VDI vdi1 = vdi; VDIRow newRow = new VDIRow(vdi, data.ShowStorageLink);
VDIRow vdiRow = dataGridViewVDIs.Rows.OfType<VDIRow>().FirstOrDefault(row => row.VDI.Equals(vdi1));
if (vdiRow != null)
{
vdiRow.UpdateRowDetails(vdi, storageLinkVolumeColumn.Visible);
continue;
}
VDIRow newRow = new VDIRow(vdi, storageLinkVolumeColumn.Visible);
dataGridViewVDIs.Rows.Add(newRow); dataGridViewVDIs.Rows.Add(newRow);
} }
} }
@ -169,7 +158,9 @@ namespace XenAdmin.TabPages
{ {
if (dataGridViewVDIs.SortedColumn != null && dataGridViewVDIs.SortOrder != SortOrder.None) if (dataGridViewVDIs.SortedColumn != null && dataGridViewVDIs.SortOrder != SortOrder.None)
dataGridViewVDIs.Sort(dataGridViewVDIs.SortedColumn, dataGridViewVDIs.Sort(dataGridViewVDIs.SortedColumn,
dataGridViewVDIs.SortOrder == SortOrder.Ascending ? ListSortDirection.Ascending : ListSortDirection.Descending); dataGridViewVDIs.SortOrder == SortOrder.Ascending
? ListSortDirection.Ascending
: ListSortDirection.Descending);
dataGridViewVDIs.ResumeLayout(); dataGridViewVDIs.ResumeLayout();
} }
@ -177,6 +168,32 @@ namespace XenAdmin.TabPages
RefreshButtons(); RefreshButtons();
} }
private readonly object _locker = new object();
private void _BuildList(object sender)
{
lock (_locker)
{
if (sr == null)
return;
Program.Invoke(this, RefreshButtons);
VDIsDataRetriever dataRetriever = new VDIsDataRetriever(sr, dataGridViewVDIs.Rows.OfType<VDIRow>());
VDIsData data = dataRetriever.CurrentData;
Program.Invoke(this, () => RefreshDataGridView(data));
}
}
private void BuildList()
{
if (sr == null)
return;
ThreadPool.QueueUserWorkItem(_BuildList);
}
private SelectedItemCollection SelectedVDIs private SelectedItemCollection SelectedVDIs
{ {
get get
@ -213,10 +230,7 @@ namespace XenAdmin.TabPages
void a_Completed(object sender, EventArgs e) void a_Completed(object sender, EventArgs e)
{ {
Program.Invoke(Program.MainWindow, delegate Program.Invoke(Program.MainWindow, RefreshButtons);
{
RefreshButtons();
});
} }
void Connection_XenObjectsUpdated(object sender, EventArgs e) void Connection_XenObjectsUpdated(object sender, EventArgs e)
@ -531,11 +545,9 @@ namespace XenAdmin.TabPages
} }
} }
public void UpdateRowDetails(VDI vdi, bool showSL) public void RefreshRowDetails(bool showSL)
{ {
VDI = vdi;
showStorageLink = showSL; showStorageLink = showSL;
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
Cells[i].Value = GetCellText(i); Cells[i].Value = GetCellText(i);
@ -543,6 +555,59 @@ namespace XenAdmin.TabPages
} }
} }
public struct VDIsData
{
public List<VDIRow> VdiRowsToUpdate { get; private set; }
public List<VDIRow> VdiRowsToRemove { get; private set; }
public List<VDI> VdisToAdd { get; private set; }
public bool ShowStorageLink { get; private set; }
public VDIsData(List<VDIRow> vdiRowsToUpdate, List<VDIRow> vdiRowsToRemove, List<VDI> vdisToAdd,
bool showStorageLink) : this()
{
VdiRowsToUpdate = vdiRowsToUpdate;
VdiRowsToRemove = vdiRowsToRemove;
VdisToAdd = vdisToAdd;
ShowStorageLink = showStorageLink;
}
}
public class VDIsDataRetriever
{
private SR sr;
private IEnumerable<VDIRow> currentVDIRows;
public VDIsDataRetriever(SR sr, IEnumerable<VDIRow> currentVDIRows)
{
this.sr = sr;
this.currentVDIRows = currentVDIRows;
}
public VDIsData CurrentData
{
get
{
List<VDI> vdis =
sr.Connection.ResolveAll(sr.VDIs).Where(
vdi =>
vdi.Show(Properties.Settings.Default.ShowHiddenVMs &&
!vdi.IsAnIntermediateStorageMotionSnapshot))
.ToList();
bool showStorageLink = vdis.Find(v => v.sm_config.ContainsKey("SVID")) != null;
var vdiRowsToRemove =
currentVDIRows.Where(vdiRow => !vdis.Contains(vdiRow.VDI)).OrderByDescending(row => row.Index).ToList();
var vdiRowsToUpdate = currentVDIRows.Except(vdiRowsToRemove).ToList();
var vdisToAdd = vdis.Except(vdiRowsToUpdate.ConvertAll(vdiRow => vdiRow.VDI)).ToList();
return new VDIsData(vdiRowsToUpdate, vdiRowsToRemove, vdisToAdd, showStorageLink);
}
}
}
private void dataGridViewVDIs_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e) private void dataGridViewVDIs_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e)
{ {
// Select the row that the user right clicked on if it's not already in the selection // Select the row that the user right clicked on if it's not already in the selection