void startOtherMachines(MachineOperationToken token) { foreach (Machine m in _vbox.Machines.filterAutobooting().filterByState(MachineState.Off)) { operatMachine(() => m.StartAsync(), m, "Boot", token, Logging.MachineControllerEventIds.MachineStartup, Logging.MachineControllerEventIds.MachineStartup); } }
void startSessionSavedMachines(MachineOperationToken token) { foreach (Machine m in _vbox.Machines.filterByState(MachineState.SessionSaved)) { operatMachine(() => m.StartAsync(), m, "Start from saved session", token, Logging.MachineControllerEventIds.MachineStartup, Logging.MachineControllerEventIds.MachineStartupFailed); } }
void announceTimeOfLastOperationOrDefault(MachineOperationToken successfulOperations) { TimeSpan time = TimeSpan.FromSeconds(15); //Default if (successfulOperations.GetMostRecent() != null) { time = successfulOperations.GetMostRecent().TimeForOperation; } announceEstimatedTime(time); //In case, the progresstoken does not support estimation of remaining time, use duration of last operation or a default as reference }
IList <MachineProgressTokenTuple> beginShutdownOfACPIShutdownMachines(MachineOperationToken token) { IEnumerable <Machine> machinesToShutdown = _vbox.Machines.filterAutobooting().filterByShutdownType <ACPIShutdownMethod>().filterByState(MachineState.Running); List <MachineProgressTokenTuple> acpiShutdownTokens = new List <MachineProgressTokenTuple>(machinesToShutdown.Count()); int i = 0; foreach (Machine m in machinesToShutdown) { acpiShutdownTokens.Add(new MachineProgressTokenTuple(m.ShutdownAsync(), m)); i++; } return(acpiShutdownTokens); }
public override void Start() { _vbox.RefreshMachines(); try { MachineOperationToken t = new MachineOperationToken(); startSessionSavedMachines(t); startOtherMachines(t); _log.TraceEvent(TraceEventType.Information, (int)Logging.MachineControllerEventIds.MachineStartup, "The following machines were started:\n{0}", t); } finally { _vbox.DisposeMachines(); } }
void estimateAndAnnounceTimeForProgressToken(ProgressToken t, MachineOperationToken successfulOperations) { try { TimeSpan remainingTime = t.EstimateRemainingTime(); _log.TraceEvent(TraceEventType.Verbose, (int)Logging.MachineControllerEventIds.AnnounceRemainingTime, "Remaining time for current operation: {0}", remainingTime.ToString()); announceEstimatedTime(remainingTime); } catch (NotSupportedException) { announceTimeOfLastOperationOrDefault(successfulOperations); } catch (Exception e) { _log.TraceEvent(TraceEventType.Warning, (int)Logging.MachineControllerEventIds.TimeEstimationProblem, "Could not estimate remaining time for Operation: {0}", e.ToString()); announceTimeOfLastOperationOrDefault(successfulOperations); } }
/// <summary> /// Hard off remaining machines. /// </summary> void hardOffRemaining(MachineOperationToken successfulOperations) { IEnumerable <Machine> remainingMachines = _vbox.Machines.filterAutobooting().filterByState(MachineState.Running); foreach (Machine m in remainingMachines) { if (!(m.ShutdownMethod is HardOffMethod)) { m.ShutdownMethod = new HardOffMethod(); _log.TraceEvent(TraceEventType.Warning, (int)Logging.MachineControllerEventIds.MachineShutdown, "Machine {0} has to be powered off hard, because the original shutdown-method failed.", m.Name); } operatMachine(() => m.ShutdownAsync(), m, "Hard off", successfulOperations, Logging.MachineControllerEventIds.MachineShutdown, Logging.MachineControllerEventIds.MachineShutdownFailed); } }
public override void Shutdown() { _vbox.RefreshMachines(); try { MachineOperationToken t = new MachineOperationToken(); IEnumerable <MachineProgressTokenTuple> pendingShutdowns = beginShutdownOfACPIShutdownMachines(t); shutdownSaveStateShutdownMachines(t); awaitAcpiShutdowns(pendingShutdowns, t); hardOffRemaining(t); _log.TraceEvent(TraceEventType.Information, (int)Logging.MachineControllerEventIds.MachineStartup, "The following machines were shutdown:\n{0}", t); } finally { _vbox.DisposeMachines(); } }
void shutdownSaveStateShutdownMachines(MachineOperationToken token) { IEnumerable <Machine> saveStateMachines = _vbox.Machines.filterAutobooting().filterByShutdownType <SaveStateMethod>().filterByState(MachineState.Running); foreach (Machine m in saveStateMachines) { try { _log.TraceEvent(TraceEventType.Verbose, (int)Logging.MachineControllerEventIds.BeginMachineSaveState, "Beginning savestate of machine {0}", m.Name); operatMachine(() => m.ShutdownAsync(), m, "Save State", token, Logging.MachineControllerEventIds.MachineShutdown, Logging.MachineControllerEventIds.MachineShutdownFailed); _log.TraceEvent(TraceEventType.Verbose, (int)Logging.MachineControllerEventIds.EndMachineSaveState, "Finished savestate of machine {0}", m.Name); } catch (Exception ex) { _log.TraceEvent(TraceEventType.Warning, (int)Logging.MachineControllerEventIds.MachineShutdownFailed, "State of Machine {0} could not be saved", m.Name); _log.TraceData(TraceEventType.Warning, (int)Logging.MachineControllerEventIds.MachineShutdownFailed, ex); } } }
public void Execute(MachineOperationToken successfulOperatedMachines, Logging.MachineControllerEventIds onFailEventId) { _timer.Restart(); try { Token.Wait(); if (Token.WaitTimedOut) { _log.TraceEvent(TraceEventType.Warning, (int)EventId, "{0} on machine \"{1}\" timed out.", OperationName, Machine.Name); } else { successfulOperatedMachines.SuccessfullyOperatedMachine(this); } } catch (Exception ex) { _log.TraceEvent(TraceEventType.Error, (int)onFailEventId, "{0} on machine \"{1}\" failed because: {2}", OperationName, Machine.Name, ex.ToString()); } finally { _timer.Stop(); } }
void operatMachine(Func <ProgressToken> operation, Machine m, string operationDescription, MachineOperationToken successfulOperations, Logging.MachineControllerEventIds eventId, Logging.MachineControllerEventIds failEventId) { try { ProgressToken t = operation.Invoke(); estimateAndAnnounceTimeForProgressToken(t, successfulOperations); MachineOperation op = new MachineOperation(m, t, operationDescription, eventId); op.Execute(successfulOperations, Logging.MachineControllerEventIds.MachineStartupFailed); } catch (Exception ex) { _log.TraceEvent(TraceEventType.Error, (int)failEventId, "{0} on machine {1} resulted in an error: {2}", operationDescription, m.Name, ex.ToString()); //no rethrow, because we do not want to interrupt the other processes } }
/// <summary> /// Await ACPI-Shutdowns according to specified timeouts /// </summary> void awaitAcpiShutdowns(IEnumerable <MachineProgressTokenTuple> shutdownsInProgress, MachineOperationToken successfulOperations) { IEnumerable <MachineProgressTokenTuple> unfinishedAcpiShutdowns = shutdownsInProgress.Where(x => !x.Token.Finished); if (unfinishedAcpiShutdowns.Count() > 0) { foreach (var activeShutdown in unfinishedAcpiShutdowns) { estimateAndAnnounceTimeForProgressToken(activeShutdown.Token, successfulOperations); MachineOperation op = new MachineOperation(activeShutdown.Machine, activeShutdown.Token, "Await ACPI-Shutdown", Logging.MachineControllerEventIds.MachineShutdown); op.Execute(successfulOperations, Logging.MachineControllerEventIds.MachineShutdownFailed); } foreach (var activeShutdown in unfinishedAcpiShutdowns) { _log.TraceEvent(TraceEventType.Warning, (int)Logging.MachineControllerEventIds.MachineShutdownFailed, "Machine {0} took to long to properly shutdown after ACPI-Command", activeShutdown.Machine.Name); } } }