mirror of
https://github.com/xcp-ng/xenadmin.git
synced 2024-11-24 22:06:59 +01:00
Merge pull request #2978 from kc284/actions
Compacted ParallelAction and MultipleAction constructors.
This commit is contained in:
commit
ef86be5347
@ -63,7 +63,8 @@ namespace XenAdmin.Core
|
||||
}
|
||||
else if (actions.Count > 1)
|
||||
{
|
||||
var parallelAction = new ParallelAction(null, "", "", "", actions, true, true);
|
||||
var parallelAction = new ParallelAction(string.Empty, string.Empty, string.Empty, actions,
|
||||
suppressHistory: true, showSubActionsDetails: true);
|
||||
parallelAction.Completed += actionCompleted;
|
||||
parallelAction.RunAsync();
|
||||
}
|
||||
|
@ -764,7 +764,8 @@ namespace XenAdmin.Core
|
||||
foreach (IXenConnection connection in ConnectionsManager.XenConnectionsCopy)
|
||||
actions.Add(new RestoreDismissedUpdatesAction(connection));
|
||||
|
||||
var action = new ParallelAction(Messages.RESTORE_DISMISSED_UPDATES, Messages.RESTORING, Messages.COMPLETED, actions, true, false);
|
||||
var action = new ParallelAction(Messages.RESTORE_DISMISSED_UPDATES, Messages.RESTORING, Messages.COMPLETED,
|
||||
actions, suppressHistory: true, showSubActionsDetails: false);
|
||||
action.Completed += action_Completed;
|
||||
|
||||
RestoreDismissedUpdatesStarted?.Invoke();
|
||||
|
@ -109,11 +109,12 @@ namespace XenAdmin.Diagnostics.Problems.PoolProblem
|
||||
if (subActions.Count == 0)
|
||||
return null;
|
||||
|
||||
return subActions.Count == 1
|
||||
? subActions[0]
|
||||
: new ParallelAction(pool.Connection, Messages.ACTION_MULTIPLE_DR_TASK_CREATE_TITLE,
|
||||
Messages.ACTION_MULTIPLE_DR_TASK_CREATE_START,
|
||||
Messages.ACTION_MULTIPLE_DR_TASK_CREATE_END, subActions);
|
||||
if (subActions.Count == 1)
|
||||
return subActions[0];
|
||||
|
||||
return new ParallelAction(Messages.ACTION_MULTIPLE_DR_TASK_CREATE_TITLE,
|
||||
Messages.ACTION_MULTIPLE_DR_TASK_CREATE_START,
|
||||
Messages.ACTION_MULTIPLE_DR_TASK_CREATE_END, subActions, pool.Connection);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,8 +120,9 @@ namespace XenAdmin.Dialogs
|
||||
var batch = from VDI vdi in _vdis
|
||||
select (AsyncAction)new MoveVirtualDiskAction(connection, vdi, SelectedSR);
|
||||
|
||||
new ParallelAction(connection, title, Messages.ACTION_MOVING_X_VDIS_STARTED,
|
||||
Messages.ACTION_MOVING_X_VDIS_COMPLETED, batch.ToList(), BATCH_SIZE).RunAsync();
|
||||
new ParallelAction(title, Messages.ACTION_MOVING_X_VDIS_STARTED,
|
||||
Messages.ACTION_MOVING_X_VDIS_COMPLETED, batch.ToList(),
|
||||
connection, maxNumberOfParallelActions: BATCH_SIZE).RunAsync();
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,8 +161,9 @@ namespace XenAdmin.Dialogs
|
||||
var batch = from VDI vdi in _vdis
|
||||
select (AsyncAction)new MigrateVirtualDiskAction(connection, vdi, SelectedSR);
|
||||
|
||||
new ParallelAction(connection, title, Messages.ACTION_MIGRATING_X_VDIS_STARTED,
|
||||
Messages.ACTION_MIGRATING_X_VDIS_COMPLETED, batch.ToList(), BATCH_SIZE).RunAsync();
|
||||
new ParallelAction(title, Messages.ACTION_MIGRATING_X_VDIS_STARTED,
|
||||
Messages.ACTION_MIGRATING_X_VDIS_COMPLETED, batch.ToList(),
|
||||
connection, maxNumberOfParallelActions: BATCH_SIZE).RunAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -536,9 +536,9 @@ namespace XenAdmin.Wizards
|
||||
if (actionList.Count == 1)
|
||||
FinalAction = actionList[0];
|
||||
else
|
||||
FinalAction = new ParallelAction(xenConnection, Messages.NEW_SR_WIZARD_FINAL_ACTION_TITLE,
|
||||
Messages.NEW_SR_WIZARD_FINAL_ACTION_START,
|
||||
Messages.NEW_SR_WIZARD_FINAL_ACTION_END, actionList);
|
||||
FinalAction = new ParallelAction(Messages.NEW_SR_WIZARD_FINAL_ACTION_TITLE,
|
||||
Messages.NEW_SR_WIZARD_FINAL_ACTION_START,
|
||||
Messages.NEW_SR_WIZARD_FINAL_ACTION_END, actionList, xenConnection);
|
||||
|
||||
// if this is a Disaster Recovery Task, it could be either a "Find existing SRs" or an "Attach SR needed for DR" case
|
||||
if (m_srWizardType.DisasterRecoveryTask)
|
||||
|
@ -815,7 +815,10 @@ namespace XenAdmin.Wizards.PatchingWizard
|
||||
}
|
||||
}
|
||||
}
|
||||
resolvePrechecksAction = new ParallelAction(Messages.PATCHINGWIZARD_PRECHECKPAGE_RESOLVING_ALL, Messages.PATCHINGWIZARD_PRECHECKPAGE_RESOLVING_ALL, Messages.COMPLETED, actions, true, false);
|
||||
|
||||
resolvePrechecksAction = new ParallelAction(Messages.PATCHINGWIZARD_PRECHECKPAGE_RESOLVING_ALL,
|
||||
Messages.PATCHINGWIZARD_PRECHECKPAGE_RESOLVING_ALL, Messages.COMPLETED,
|
||||
actions, suppressHistory: true, showSubActionsDetails: false);
|
||||
StartResolvePrechecksAction();
|
||||
}
|
||||
|
||||
|
@ -39,58 +39,49 @@ using System.Linq;
|
||||
|
||||
namespace XenAdmin.Actions
|
||||
{
|
||||
// Run several actions. The outer action is asynchronous, but the subactions are run synchronously within that.
|
||||
/// <summary>
|
||||
/// Run several actions. The outer action is asynchronous, but the sub-actions are run synchronously within it.
|
||||
/// </summary>
|
||||
public class MultipleAction : AsyncAction, IDisposable
|
||||
{
|
||||
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
private static readonly log4net.ILog _log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected readonly List<AsyncAction> subActions;
|
||||
private readonly string endDescription;
|
||||
public bool ShowSubActionsDetails { get; private set; }
|
||||
private readonly List<AsyncAction> _subActions;
|
||||
private readonly string _endDescription;
|
||||
private readonly bool _stopOnFirstException;
|
||||
|
||||
public bool ShowSubActionsDetails { get; }
|
||||
public string SubActionTitle { get; private set; }
|
||||
public string SubActionDescription { get; private set; }
|
||||
public bool StopOnFirstException { get; private set; }
|
||||
|
||||
public MultipleAction(IXenConnection connection, string title, string startDescription, string endDescription, List<AsyncAction> subActions, bool suppressHistory)
|
||||
public MultipleAction(IXenConnection connection, string title, string startDescription,
|
||||
string endDescription, List<AsyncAction> subActions, bool suppressHistory = false,
|
||||
bool showSubActionsDetails = false, bool stopOnFirstException = false)
|
||||
: base(connection, title, startDescription, suppressHistory)
|
||||
{
|
||||
this.endDescription = endDescription;
|
||||
this.subActions = subActions;
|
||||
this.Completed += MultipleAction_Completed;
|
||||
_endDescription = endDescription;
|
||||
_subActions = subActions;
|
||||
ShowSubActionsDetails = showSubActionsDetails;
|
||||
_stopOnFirstException = stopOnFirstException;
|
||||
Completed += MultipleAction_Completed;
|
||||
RegisterEvents();
|
||||
}
|
||||
|
||||
public MultipleAction(IXenConnection connection, string title, string startDescription, string endDescription, List<AsyncAction> subActions)
|
||||
: this(connection, title, startDescription, endDescription, subActions, false)
|
||||
{}
|
||||
|
||||
public MultipleAction(IXenConnection connection, string title, string startDescription, string endDescription,
|
||||
List<AsyncAction> subActions, bool suppressHistory, bool showSubActionsDetails)
|
||||
: this(connection, title, startDescription, endDescription, subActions, suppressHistory)
|
||||
{
|
||||
ShowSubActionsDetails = showSubActionsDetails;
|
||||
}
|
||||
|
||||
public MultipleAction(IXenConnection connection, string title, string startDescription, string endDescription,
|
||||
List<AsyncAction> subActions, bool suppressHistory, bool showSubActionsDetails, bool stopOnFirstException)
|
||||
: this(connection, title, startDescription, endDescription, subActions, suppressHistory, showSubActionsDetails)
|
||||
{
|
||||
StopOnFirstException = stopOnFirstException;
|
||||
}
|
||||
|
||||
// The multiple action gets its ApiMethodsToRoleCheck by accumulating the lists from each of the subactions
|
||||
/// <summary>
|
||||
/// The multiple action gets its ApiMethodsToRoleCheck by accumulating the lists from each of the sub-actions
|
||||
/// </summary>
|
||||
public override RbacMethodList GetApiMethodsToRoleCheck
|
||||
{
|
||||
get
|
||||
{
|
||||
RbacMethodList list = new RbacMethodList();
|
||||
foreach (AsyncAction subAction in subActions)
|
||||
var list = new RbacMethodList();
|
||||
foreach (var subAction in _subActions)
|
||||
list.AddRange(subAction.GetApiMethodsToRoleCheck);
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Run()
|
||||
protected sealed override void Run()
|
||||
{
|
||||
PercentComplete = 0;
|
||||
var exceptions = new List<Exception>();
|
||||
@ -98,12 +89,12 @@ namespace XenAdmin.Actions
|
||||
|
||||
RunSubActions(exceptions);
|
||||
|
||||
Tick(100, endDescription);
|
||||
Tick(100, _endDescription);
|
||||
|
||||
if (exceptions.Count > 1)
|
||||
{
|
||||
foreach (Exception e in exceptions)
|
||||
log.Error(e);
|
||||
foreach (var e in exceptions)
|
||||
_log.Error(e);
|
||||
|
||||
Exception = new Exception(Messages.SOME_ERRORS_ENCOUNTERED);
|
||||
}
|
||||
@ -113,12 +104,12 @@ namespace XenAdmin.Actions
|
||||
|
||||
public override void RecomputeCanCancel()
|
||||
{
|
||||
CanCancel = !this.IsCompleted && subActions.Any(a => !a.IsCompleted);
|
||||
CanCancel = !IsCompleted && _subActions.Any(a => !a.IsCompleted);
|
||||
}
|
||||
|
||||
protected override void CancelRelatedTask()
|
||||
{
|
||||
foreach (AsyncAction subAction in subActions.Where(a => !a.IsCompleted))
|
||||
foreach (var subAction in _subActions.Where(a => !a.IsCompleted))
|
||||
{
|
||||
subAction.Cancel();
|
||||
}
|
||||
@ -126,20 +117,19 @@ namespace XenAdmin.Actions
|
||||
|
||||
private void RegisterEvents()
|
||||
{
|
||||
foreach (AsyncAction subAction in subActions)
|
||||
foreach (var subAction in _subActions)
|
||||
subAction.Changed += SubActionChanged;
|
||||
}
|
||||
|
||||
private void DeregisterEvents()
|
||||
private void DeRegisterEvents()
|
||||
{
|
||||
foreach (AsyncAction subAction in subActions)
|
||||
foreach (var subAction in _subActions)
|
||||
subAction.Changed -= SubActionChanged;
|
||||
}
|
||||
|
||||
private void SubActionChanged(ActionBase sender)
|
||||
{
|
||||
AsyncAction subAction = sender as AsyncAction;
|
||||
if (subAction != null)
|
||||
if (sender is AsyncAction subAction)
|
||||
{
|
||||
SubActionTitle = subAction.Title;
|
||||
SubActionDescription = subAction.Description;
|
||||
@ -151,15 +141,15 @@ namespace XenAdmin.Actions
|
||||
protected virtual void RecalculatePercentComplete()
|
||||
{
|
||||
int total = 0;
|
||||
int n = subActions.Count;
|
||||
foreach (var action in subActions)
|
||||
int n = _subActions.Count;
|
||||
foreach (var action in _subActions)
|
||||
total += action.PercentComplete;
|
||||
PercentComplete = (int)(total / n);
|
||||
PercentComplete = total / n;
|
||||
}
|
||||
|
||||
protected virtual void RunSubActions(List<Exception> exceptions)
|
||||
{
|
||||
foreach (AsyncAction subAction in subActions)
|
||||
foreach (var subAction in _subActions)
|
||||
{
|
||||
if (Cancelling) // don't start any more actions
|
||||
break;
|
||||
@ -170,16 +160,14 @@ namespace XenAdmin.Actions
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Failure f = e as Failure;
|
||||
if (f != null && Connection != null && f.ErrorDescription[0] == Failure.RBAC_PERMISSION_DENIED)
|
||||
{
|
||||
if (e is Failure f && Connection != null && f.ErrorDescription[0] == Failure.RBAC_PERMISSION_DENIED)
|
||||
Failure.ParseRBACFailure(f, Connection, Session ?? Connection.Session);
|
||||
}
|
||||
|
||||
exceptions.Add(e);
|
||||
// Record the first exception we come to. Though later if there are more than one we will replace this with non specific one.
|
||||
if (Exception == null)
|
||||
Exception = e;
|
||||
if (StopOnFirstException)
|
||||
if (_stopOnFirstException)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -189,9 +177,9 @@ namespace XenAdmin.Actions
|
||||
{
|
||||
// The MultipleAction can sometimes complete prematurely, for example
|
||||
// if the sudo dialog is cancelled, of (less likely) if one of the
|
||||
// subactions throws an exception in its GetApiMethodsToRoleCheck.
|
||||
// In this case, we need to cancel this action's subactions.
|
||||
foreach (AsyncAction subAction in subActions)
|
||||
// sub-actions throws an exception in its GetApiMethodsToRoleCheck.
|
||||
// In this case, we need to cancel this action's sub-actions.
|
||||
foreach (var subAction in _subActions)
|
||||
{
|
||||
if (!subAction.IsCompleted)
|
||||
subAction.Cancel();
|
||||
@ -202,7 +190,7 @@ namespace XenAdmin.Actions
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DeregisterEvents();
|
||||
DeRegisterEvents();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -91,7 +91,7 @@ namespace XenAdmin.Actions
|
||||
else
|
||||
{
|
||||
if (_runActionInParallel)
|
||||
new ParallelAction(connection, _title, _startDescription, _endDescription, actionsByConnection[connection]).RunAsync();
|
||||
new ParallelAction(_title, _startDescription, _endDescription, actionsByConnection[connection], connection).RunAsync();
|
||||
else
|
||||
new MultipleAction(connection, _title, _startDescription, _endDescription, actionsByConnection[connection]).RunAsync();
|
||||
}
|
||||
@ -104,7 +104,7 @@ namespace XenAdmin.Actions
|
||||
else if (actionsWithNoConnection.Count > 1)
|
||||
{
|
||||
if (_runActionInParallel)
|
||||
new ParallelAction(null, _title, _startDescription, _endDescription, actionsWithNoConnection).RunAsync();
|
||||
new ParallelAction(_title, _startDescription, _endDescription, actionsWithNoConnection).RunAsync();
|
||||
else
|
||||
new MultipleAction(null, _title, _startDescription, _endDescription, actionsWithNoConnection).RunAsync();
|
||||
}
|
||||
|
@ -44,99 +44,83 @@ namespace XenAdmin.Actions
|
||||
/// </summary>
|
||||
public class ParallelAction : MultipleAction
|
||||
{
|
||||
//Change parameter to increase the number of concurrent actions running
|
||||
/// <summary>
|
||||
/// Change this to increase the number of concurrent actions running
|
||||
/// </summary>
|
||||
private const int DEFAULT_MAX_NUMBER_OF_PARALLEL_ACTIONS = 25;
|
||||
|
||||
private Dictionary<IXenConnection, List<AsyncAction>> actionsByConnection = new Dictionary<IXenConnection, List<AsyncAction>>();
|
||||
private Dictionary<IXenConnection, ProduceConsumerQueue> queuesByConnection = new Dictionary<IXenConnection, ProduceConsumerQueue>();
|
||||
private readonly Dictionary<IXenConnection, List<AsyncAction>> _actionsByConnection = new Dictionary<IXenConnection, List<AsyncAction>>();
|
||||
private readonly Dictionary<IXenConnection, ProduceConsumerQueue> _queuesByConnection = new Dictionary<IXenConnection, ProduceConsumerQueue>();
|
||||
|
||||
private List<AsyncAction> actionsWithNoConnection = new List<AsyncAction>();
|
||||
private ProduceConsumerQueue queueWithNoConnection;
|
||||
private readonly List<AsyncAction> _actionsWithNoConnection = new List<AsyncAction>();
|
||||
private ProduceConsumerQueue _queueWithNoConnection;
|
||||
|
||||
private readonly int maxNumberOfParallelActions;
|
||||
private int actionsCount;
|
||||
private readonly int _maxNumberOfParallelActions;
|
||||
private readonly int _actionsCount;
|
||||
private readonly object _lock = new object();
|
||||
private volatile int _completedActionsCount ;
|
||||
|
||||
public ParallelAction(IXenConnection connection, string title, string startDescription, string endDescription, List<AsyncAction> subActions, bool suppressHistory, bool showSubActionsDetails, int maxNumberOfParallelActions = DEFAULT_MAX_NUMBER_OF_PARALLEL_ACTIONS)
|
||||
: base(connection, title, startDescription, endDescription, subActions, suppressHistory, showSubActionsDetails)
|
||||
{
|
||||
if (Connection != null)
|
||||
{
|
||||
actionsByConnection.Add(Connection, subActions);
|
||||
actionsCount = subActions.Count;
|
||||
}
|
||||
else
|
||||
GroupActionsByConnection();
|
||||
this.maxNumberOfParallelActions = maxNumberOfParallelActions;
|
||||
}
|
||||
|
||||
public ParallelAction(IXenConnection connection, string title, string startDescription, string endDescription, List<AsyncAction> subActions, int maxNumberOfParallelActions = DEFAULT_MAX_NUMBER_OF_PARALLEL_ACTIONS)
|
||||
: this(connection, title, startDescription, endDescription, subActions, false, false, maxNumberOfParallelActions)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Use this constructor to create a cross connection ParallelAction.
|
||||
/// It takes a list of any number of actions, separates them by connections
|
||||
/// and runs a certain number of them simultaneously on each connection, all connections in parallel.
|
||||
/// Once one simultaneous action is finished the next one in the queue is started until all are complete.
|
||||
/// Once a simultaneous action is finished the next one in the queue is started until all are complete.
|
||||
/// </summary>
|
||||
public ParallelAction(string title, string startDescription, string endDescription, List<AsyncAction> subActions, bool suppressHistory, bool showSubActionsDetails, int maxNumberOfParallelActions = DEFAULT_MAX_NUMBER_OF_PARALLEL_ACTIONS)
|
||||
: base(null, title, startDescription, endDescription, subActions, suppressHistory, showSubActionsDetails)
|
||||
public ParallelAction(string title, string startDescription, string endDescription,
|
||||
List<AsyncAction> subActions, IXenConnection connection = null,
|
||||
bool suppressHistory = false, bool showSubActionsDetails = false,
|
||||
int maxNumberOfParallelActions = DEFAULT_MAX_NUMBER_OF_PARALLEL_ACTIONS)
|
||||
: base(connection, title, startDescription, endDescription, subActions, suppressHistory, showSubActionsDetails)
|
||||
{
|
||||
GroupActionsByConnection();
|
||||
this.maxNumberOfParallelActions = maxNumberOfParallelActions;
|
||||
}
|
||||
|
||||
public ParallelAction(string title, string startDescription, string endDescription, List<AsyncAction> subActions, int maxNumberOfParallelActions = DEFAULT_MAX_NUMBER_OF_PARALLEL_ACTIONS)
|
||||
: this(title, startDescription, endDescription, subActions, false, false, maxNumberOfParallelActions)
|
||||
{ }
|
||||
|
||||
private void GroupActionsByConnection()
|
||||
{
|
||||
actionsCount = 0;
|
||||
foreach (AsyncAction action in subActions)
|
||||
if (Connection == null)
|
||||
{
|
||||
if (action.Connection != null)
|
||||
foreach (var action in subActions)
|
||||
{
|
||||
if (action.Connection.IsConnected)
|
||||
if (action.Connection == null)
|
||||
{
|
||||
if (!actionsByConnection.ContainsKey(action.Connection))
|
||||
{
|
||||
actionsByConnection.Add(action.Connection, new List<AsyncAction>());
|
||||
}
|
||||
_actionsWithNoConnection.Add(action);
|
||||
_actionsCount++;
|
||||
}
|
||||
else if (action.Connection.IsConnected)
|
||||
{
|
||||
if (!_actionsByConnection.ContainsKey(action.Connection))
|
||||
_actionsByConnection.Add(action.Connection, new List<AsyncAction>());
|
||||
|
||||
actionsByConnection[action.Connection].Add(action);
|
||||
actionsCount++;
|
||||
_actionsByConnection[action.Connection].Add(action);
|
||||
_actionsCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
actionsWithNoConnection.Add(action);
|
||||
actionsCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_actionsByConnection.Add(Connection, subActions);
|
||||
_actionsCount = subActions.Count;
|
||||
}
|
||||
|
||||
_maxNumberOfParallelActions = maxNumberOfParallelActions;
|
||||
}
|
||||
|
||||
|
||||
protected override void RunSubActions(List<Exception> exceptions)
|
||||
{
|
||||
if (actionsCount == 0)
|
||||
if (_actionsCount == 0)
|
||||
return;
|
||||
|
||||
foreach (IXenConnection connection in actionsByConnection.Keys)
|
||||
foreach (var connection in _actionsByConnection.Keys)
|
||||
{
|
||||
queuesByConnection[connection] = new ProduceConsumerQueue(Math.Min(maxNumberOfParallelActions, actionsByConnection[connection].Count));
|
||||
foreach (AsyncAction subAction in actionsByConnection[connection])
|
||||
_queuesByConnection[connection] = new ProduceConsumerQueue(Math.Min(_maxNumberOfParallelActions, _actionsByConnection[connection].Count));
|
||||
foreach (AsyncAction subAction in _actionsByConnection[connection])
|
||||
{
|
||||
EnqueueAction(subAction, queuesByConnection[connection], exceptions);
|
||||
EnqueueAction(subAction, _queuesByConnection[connection], exceptions);
|
||||
}
|
||||
}
|
||||
|
||||
if (actionsWithNoConnection.Count > 0)
|
||||
queueWithNoConnection = new ProduceConsumerQueue(Math.Min(maxNumberOfParallelActions, actionsWithNoConnection.Count));
|
||||
if (_actionsWithNoConnection.Count > 0)
|
||||
_queueWithNoConnection = new ProduceConsumerQueue(Math.Min(_maxNumberOfParallelActions, _actionsWithNoConnection.Count));
|
||||
|
||||
foreach (AsyncAction subAction in actionsWithNoConnection)
|
||||
foreach (var subAction in _actionsWithNoConnection)
|
||||
{
|
||||
EnqueueAction(subAction, queueWithNoConnection, exceptions);
|
||||
EnqueueAction(subAction, _queueWithNoConnection, exceptions);
|
||||
}
|
||||
|
||||
lock (_lock)
|
||||
@ -145,7 +129,7 @@ namespace XenAdmin.Actions
|
||||
}
|
||||
}
|
||||
|
||||
void EnqueueAction(AsyncAction action, ProduceConsumerQueue queue, List<Exception> exceptions)
|
||||
private void EnqueueAction(AsyncAction action, ProduceConsumerQueue queue, List<Exception> exceptions)
|
||||
{
|
||||
action.Completed += action_Completed;
|
||||
queue.EnqueueItem(
|
||||
@ -159,12 +143,12 @@ namespace XenAdmin.Actions
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Failure f = e as Failure;
|
||||
if (f != null && Connection != null &&
|
||||
if (e is Failure f && Connection != null &&
|
||||
f.ErrorDescription[0] == Failure.RBAC_PERMISSION_DENIED)
|
||||
{
|
||||
Failure.ParseRBACFailure(f, action.Connection, action.Session ?? action.Connection.Session);
|
||||
}
|
||||
|
||||
exceptions.Add(e);
|
||||
// Record the first exception we come to. Though later if there are more than one we will replace this with non specific one.
|
||||
if (Exception == null)
|
||||
@ -175,30 +159,30 @@ namespace XenAdmin.Actions
|
||||
|
||||
protected override void RecalculatePercentComplete()
|
||||
{
|
||||
if (actionsCount == 0)
|
||||
if (_actionsCount == 0)
|
||||
return;
|
||||
|
||||
int total = 0;
|
||||
foreach (IXenConnection connection in actionsByConnection.Keys)
|
||||
|
||||
foreach (var connection in _actionsByConnection.Keys)
|
||||
{
|
||||
foreach (var action in actionsByConnection[connection])
|
||||
foreach (var action in _actionsByConnection[connection])
|
||||
total += action.PercentComplete;
|
||||
}
|
||||
foreach (var action in actionsWithNoConnection)
|
||||
|
||||
foreach (var action in _actionsWithNoConnection)
|
||||
total += action.PercentComplete;
|
||||
PercentComplete = (int)(total / actionsCount);
|
||||
|
||||
PercentComplete = total / _actionsCount;
|
||||
}
|
||||
|
||||
private readonly object _lock = new object();
|
||||
private volatile int i = 0;
|
||||
|
||||
void action_Completed(ActionBase sender)
|
||||
private void action_Completed(ActionBase sender)
|
||||
{
|
||||
sender.Completed -= action_Completed;
|
||||
lock (_lock)
|
||||
{
|
||||
i++;
|
||||
if (i == actionsCount)
|
||||
_completedActionsCount++;
|
||||
if (_completedActionsCount == _actionsCount)
|
||||
{
|
||||
Monitor.Pulse(_lock);
|
||||
PercentComplete = 100;
|
||||
@ -210,13 +194,11 @@ namespace XenAdmin.Actions
|
||||
{
|
||||
base.MultipleAction_Completed(sender);
|
||||
|
||||
foreach (IXenConnection connection in queuesByConnection.Keys)
|
||||
{
|
||||
queuesByConnection[connection].StopWorkers(false);
|
||||
}
|
||||
foreach (var connection in _queuesByConnection.Keys)
|
||||
_queuesByConnection[connection].StopWorkers(false);
|
||||
|
||||
if (queueWithNoConnection != null)
|
||||
queueWithNoConnection.StopWorkers(false);
|
||||
|
||||
_queueWithNoConnection?.StopWorkers(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user