public async Task CompleteSwitchingBrokerAsync(CancellationToken cancellationToken) { if (_lockToken == null) { throw new InvalidOperationException($"{nameof(AcquireLockAsync)} must be called before {nameof(CompleteSwitchingBrokerAsync)}"); } _session._disposeToken.ThrowIfDisposed(); if (_session._startupInfo == null) { // Session never started. No need to restart it. // Reset _initializationLock so that next awaiter can proceed. _lockToken.Reset(); return; } var brokerClient = _session.BrokerClient; var startupInfo = _session._startupInfo; var host = _session._host; var hostRunTask = _session._hostRunTask; // host may be null if previous attempts to start it have failed if (host != null) { // Detach RHost from RSession host.DetachCallback(); // Cancel all current requests await _session.CancelAllAsync(cancellationToken); } // Start new RHost await _session.StartHostAsyncBackground(_hostToSwitch, _lockToken, cancellationToken); // Shut down the old host, gracefully if possible, and wait for old hostRunTask to exit; if (hostRunTask != null) { await StopHostAsync(brokerClient, startupInfo?.Name, host, hostRunTask); } host?.Dispose(); if (hostRunTask != null && hostRunTask.Status == TaskStatus.Running) { await hostRunTask; } _hostToSwitch = null; }
private async Task StartHostAsyncBackground(RHostStartupInfo startupInfo, IRSessionCallback callback, IBinaryAsyncLockToken lockToken, int timeout) { await TaskUtilities.SwitchToBackgroundThread(); _callback = callback; _startupInfo = startupInfo; RHost host; try { host = await BrokerClient.ConnectAsync(startupInfo.Name, this, startupInfo.RHostCommandLineArguments, timeout); } catch (OperationCanceledException ex) { _initializationTcs.TrySetCanceled(ex); lockToken.Reset(); throw; } catch (Exception ex) { _initializationTcs.TrySetException(ex); lockToken.Reset(); throw; } await StartHostAsyncBackground(host, lockToken); }
private async Task RunHost(IBinaryAsyncLockToken lockToken, CancellationToken initializationCt) { try { ScheduleAfterHostStarted(_startupInfo); await _host.Run(initializationCt); } catch (OperationCanceledException oce) { _initializationTcs.TrySetCanceled(oce); } catch (MessageTransportException mte) { _initializationTcs.TrySetCanceled(new RHostDisconnectedException(string.Empty, mte)); } catch (Exception ex) { _initializationTcs.TrySetException(ex); } finally { lockToken.Reset(); } }
private bool VerifyTransactionState(string methodName) { if (_lockToken == null) { throw new InvalidOperationException($"{nameof(AcquireLockAsync)} must be called before {methodName}"); } if (_session._startupInfo == null) { // Session never started. No need to restart it or connect to the host. _lockToken.Reset(); return(false); } return(true); }
public void Dispose() { _lockToken?.Reset(); _hostToSwitch?.Dispose(); }