List <string> ReadMountsContentOrDefault(Gamelet gamelet, ActionRecorder actionRecorder) { List <string> content = new List <string>(); ICancelableTask getMountsTask = _cancelableTaskFactory.Create(TaskMessages.CheckingMountInfo, async _ => { content = await _remoteCommand.RunWithSuccessCapturingOutputAsync( new SshTarget(gamelet), ReadMountsCmd) ?? new List <string>(); }); try { getMountsTask.RunAndRecord(actionRecorder, ActionType.GameletReadMounts); return(content); } catch (ProcessException e) { Trace.WriteLine($"Error reading /proc/mounts file: {e.Message}"); _dialogUtil.ShowError(ErrorStrings.FailedToStartRequiredProcess(e.Message), e.ToString()); return(content); } finally { string joinedContent = string.Join("\n\t", content); Trace.WriteLine($"Gamelet /proc/mounts:{Environment.NewLine}{joinedContent}"); } }
protected void RegisterCancelable(string key, ICancelableTask task) { lock (cancelableTasks) { cancelableTasks.Add(key, task); } }
public IVsiGameLaunch CreateLaunch(LaunchParams launchParams) { IAction action = _actionRecorder.CreateToolAction(ActionType.GameLaunchCreate); CreateLaunchResult launchRes = null; ICancelableTask launchTask = _cancelableTaskFactory.Create( TaskMessages.LaunchingGame, async task => { launchRes = await CreateLaunchAsync(launchParams, task, action); }); try { if (!launchTask.RunAndRecord(action)) { Trace.WriteLine("Launching a game has been canceled by user."); return(null); } } catch (ConfigurationException e) { _dialogUtil.ShowError(e.Message); return(null); } catch (CloudException e) { string message = $"{ErrorStrings.CouldNotStartTheGame}{Environment.NewLine}" + $"{e.Message}{Environment.NewLine}{Environment.NewLine}{ErrorStrings.SeeLogs}"; _dialogUtil.ShowError(message); return(null); } if (!string.IsNullOrWhiteSpace(launchRes.WarningMessage)) { _dialogUtil.ShowWarning(launchRes.WarningMessage); } if (!string.IsNullOrWhiteSpace(launchRes.SdkCompatibilityMessage)) { bool showAgain = _dialogUtil.ShowOkNoMoreDisplayWarning( launchRes.SdkCompatibilityMessage, new[] { "Tools", "Options", "Stadia SDK", "Game launch", "SDK incompatibility warning" }); if (!showAgain) { _vsiService.Options.AddSdkVersionsToHide(launchParams.GameletSdkVersion, launchParams.SdkVersion, launchParams.GameletName); } } return(launchRes.GameLaunch); }
/// <summary> /// Enable SSH for communication with the gamelet. /// </summary> bool EnableSsh(Gamelet gamelet) { try { IAction action = _actionRecorder.CreateToolAction(ActionType.GameletEnableSsh); ICancelableTask enableSshTask = _cancelableTaskFactory.Create(TaskMessages.EnablingSSH, async _ => { await _sshManager.EnableSshAsync(gamelet, action); }); return(enableSshTask.RunAndRecord(action)); } catch (Exception e) when(e is CloudException || e is SshKeyException) { Trace.Write($"Received exception while enabling ssh.\n{e}"); _dialogUtil.ShowError(ErrorStrings.FailedToEnableSsh(e.Message), e.ToString()); return(false); } }
/// <summary> /// Clear stdout/stderr so that we don't start to tail before guest_orc clears. /// </summary> bool ClearLogs(Gamelet gamelet) { ICancelableTask clearLogsTask = _cancelableTaskFactory.Create(TaskMessages.ClearingInstanceLogs, async _ => await _remoteCommand.RunWithSuccessAsync( new SshTarget(gamelet), ClearLogsCmd)); try { return(clearLogsTask.RunAndRecord(_actionRecorder, ActionType.GameletClearLogs)); } catch (ProcessException e) { Trace.WriteLine($"Error clearing instance logs: {e.Message}"); _dialogUtil.ShowError(ErrorStrings.FailedToStartRequiredProcess(e.Message), e.ToString()); return(false); } }
bool StopGameLaunchIfPresent(TestAccount testAccount, string devAccount, List <Gamelet> gamelets, Gamelet selectedGamelet) { IAction getExistingAction = _actionRecorder.CreateToolAction(ActionType.GameLaunchGetExisting); ICancelableTask <GgpGrpc.Models.GameLaunch> currentGameLaunchTask = _cancelableTaskFactory.Create(TaskMessages.LookingForTheCurrentLaunch, async task => await _gameLaunchBeHelper .GetCurrentGameLaunchAsync( testAccount?.Name, getExistingAction)); if (!currentGameLaunchTask.RunAndRecord(getExistingAction)) { return(false); } GgpGrpc.Models.GameLaunch currentGameLaunch = currentGameLaunchTask.Result; if (currentGameLaunch == null) { return(true); } if (!PromptToDeleteLaunch(currentGameLaunch, gamelets, selectedGamelet, _actionRecorder, testAccount?.GamerStadiaName, devAccount)) { return(false); } IAction deleteAction = _actionRecorder.CreateToolAction(ActionType.GameLaunchDeleteExisting); ICancelableTask <DeleteLaunchResult> stopTask = _cancelableTaskFactory.Create( TaskMessages.WaitingForGameStop, async task => await _gameLaunchBeHelper.DeleteLaunchAsync( currentGameLaunch.Name, task, deleteAction)); return(stopTask.RunAndRecord(deleteAction) && stopTask.Result.IsSuccessful); }
public int LoadSymbols() { IAction action = _actionRecorder.CreateToolAction(ActionType.DebugModuleLoadSymbols); ICancelableTask <int> loadSymbolsTask = _cancelableTaskFactory.Create( "Loading symbols...", task => _moduleFileLoader.LoadModuleFilesAsync(new[] { _lldbModule }, task, _moduleFileLoadRecorderFactory.Create( action))); if (!loadSymbolsTask.RunAndRecord(action)) { return(VSConstants.E_ABORT); } _engineHandler.OnSymbolsLoaded(Self, ModuleName, null, loadSymbolsTask.Result == VSConstants.S_OK, _program); // Returning E_FAIL causes Visual Studio to show a file dialog when attached // to a running program or crash dump. This dialog can only be used to select PDB // files. return(loadSymbolsTask.Result == VSConstants.E_FAIL ? VSConstants.S_OK : loadSymbolsTask.Result); }
/// <summary> /// This is an extension of the OutOfProcTaskAppDomainWrapper that is responsible /// for activating and executing the user task. /// This extension provides support for ICancellable Out-Of-Proc tasks. /// </summary> /// <returns>True if the task is ICancellable</returns> internal bool CancelTask() { // If the cancel was issued even before WrappedTask has been created then set a flag so that we can // skip execution CancelPending = true; // Store in a local to avoid a race var wrappedTask = WrappedTask; if (wrappedTask == null) { return(true); } ICancelableTask cancelableTask = wrappedTask as ICancelableTask; if (cancelableTask != null) { cancelableTask.Cancel(); return(true); } return(false); }
public bool WaitUntilGameLaunched() { IAction action = _actionRecorder.CreateToolAction(ActionType.GameLaunchWaitForStart); ICancelableTask pollForLaunchStatusTask = _cancelableTaskFactory.Create( TaskMessages.LaunchingGame, async task => await PollForLaunchStatusAsync(task, action)); try { if (!pollForLaunchStatusTask.RunAndRecord(action)) { Trace.WriteLine("Polling for the launch status has been canceled by user."); return(false); } } catch (Exception e) when(e is TimeoutException || e is GameLaunchFailError) { Trace.WriteLine(e.Message); _dialogUtil.ShowError(e.Message); return(false); } return(true); }
public void Setup() { _cancelable = Substitute.For <ICancelableTask>(); _action = Substitute.For <IAction>(); _gameletClient = Substitute.For <IGameletClient>(); _paramsConverter = Substitute.For <ILaunchGameParamsConverter>(); _cancelableTaskFactory = Substitute.For <CancelableTask.Factory>(); _yetiVsiService = Substitute.For <IYetiVSIService>(); _metrics = Substitute.For <IMetrics>(); _actionRecorder = Substitute.For <ActionRecorder>(_metrics); _devEvent = SetupCreateLaunchEvent(); _dialogUtil = Substitute.For <IDialogUtil>(); _vsiGameLaunchFactory = Substitute.For <IVsiGameLaunchFactory>(); _vsiGameLaunch = Substitute.For <IVsiGameLaunch>(); _vsiGameLaunchFactory.Create(_gameLaunchName, Arg.Any <bool>()).Returns(_vsiGameLaunch); _vsiGameLaunch.LaunchName.Returns(_gameLaunchName); _vsiGameLaunch.LaunchId.Returns(_gameLaunchId); _target = new GameLauncher(_gameletClient, _yetiVsiService, _paramsConverter, _cancelableTaskFactory, _actionRecorder, _dialogUtil, _vsiGameLaunchFactory); SetupCancelableTask(); }
/// <summary> /// Stop a gamelet and wait for it to return to the reserved state. /// </summary> Gamelet StopGamelet(Gamelet gamelet) { IAction action = _actionRecorder.CreateToolAction(ActionType.GameletStop); ICancelableTask stopTask = _cancelableTaskFactory.Create(TaskMessages.WaitingForGameStop, async(task) => { IGameletClient gameletClient = _gameletClientFactory.Create(_runner.Intercept(action)); try { await gameletClient.StopGameAsync(gamelet.Id); } catch (CloudException e) when((e.InnerException as RpcException) ?.StatusCode == StatusCode.FailedPrecondition) { // FailedPreconditions likely means there is no game session to stop. // For details see (internal). Trace.WriteLine("Potential race condition while stopping game; " + $"ignoring RPC error: {e.InnerException.Message}"); } while (!task.IsCanceled) { gamelet = await gameletClient.GetGameletByNameAsync(gamelet.Name); if (gamelet.State == GameletState.Reserved) { break; } await Task.Delay(1000); } }); if (stopTask.RunAndRecord(action)) { return(gamelet); } return(null); }
/// <summary> /// Registers a cancellable subtask. /// </summary> /// <param name="key"></param> /// <param name="task"></param> protected void RegisterCancelable(Guid key, ICancelableTask task) { RegisterCancelable(key.ToString(), task); }
protected void RegisterCancelable(Guid key, ICancelableTask task) { RegisterCancelable(key.ToString(), task); }
// Run the task and record its outcome plus duration. // See ActionRecorder.RecordCancelable for details. public static bool RunAndRecord(this ICancelableTask task, ActionRecorder recorder, ActionType type) { return(recorder.CreateToolAction(type).Record(() => task.Run())); }
/// <summary> /// Registers a task that have to be canceled when the activity is canceled. /// </summary> /// <param name="workflowInstanceGuid"></param> /// <param name="activityInstanceId"></param> /// <param name="cancelableTask"></param> protected void RegisterCancelable(Guid workflowInstanceGuid, string activityInstanceId, ICancelableTask cancelableTask) { if (cancelableTasks.ContainsKey(activityInstanceId)) { throw new InvalidOperationException(ExceptionMessages.OnlyOneCancelable); } cancelableTasks.Add(String.Format("{0}_{1}", workflowInstanceGuid.ToString(), activityInstanceId), cancelableTask); }
/// <summary> /// Unregisteres a task that no longer needs to be cancelable. /// </summary> /// <param name="workflowInstanceGuid"></param> /// <param name="activityInstanceId"></param> /// <param name="cancelableTask"></param> protected void UnregisterCancelable(Guid workflowInstanceGuid, string activityInstanceId, ICancelableTask cancelableTask) { string id = String.Format("{0}_{1}", workflowInstanceGuid.ToString(), activityInstanceId); if (cancelableTasks[id] != cancelableTask) { throw new ArgumentException(ExceptionMessages.ObjectsDoNotMatch, "cancelableObject"); } cancelableTasks.Remove(id); }
/// <summary> /// Registers a cancellable subtask. /// </summary> /// <param name="key"></param> /// <param name="task"></param> protected void RegisterCancelable(string key, ICancelableTask task) { lock (cancelableTasks) { cancelableTasks.Add(key, task); } }
// Run the task and record its outcome plus duration. // See ActionRecorder.RecordCancelable for details. public static bool RunAndRecord(this ICancelableTask task, IAction action) { return(action.Record(() => task.Run())); }