예제 #1
0
        public async Task <bool> TrySwitchBrokerAsync(string name, BrokerConnectionInfo connectionInfo = default(BrokerConnectionInfo), CancellationToken cancellationToken = default(CancellationToken))
        {
            using (_disposeToken.Link(ref cancellationToken)) {
                await TaskUtilities.SwitchToBackgroundThread();

                var brokerClient = CreateBrokerClient(name, connectionInfo, cancellationToken);
                if (brokerClient == null)
                {
                    return(false);
                }

                // Broker switching shouldn't be concurrent
                IAsyncReaderWriterLockToken lockToken;
                try {
                    lockToken = await _connectArwl.WriterLockAsync(cancellationToken);
                } catch (OperationCanceledException) {
                    brokerClient.Dispose();
                    return(false);
                }

                if (brokerClient.ConnectionInfo.Equals(_brokerProxy.ConnectionInfo))
                {
                    brokerClient.Dispose();

                    try {
                        // Switching to the broker that is currently running and connected is always successful
                        if (IsConnected)
                        {
                            return(true);
                        }

                        await ReconnectAsync(cancellationToken);
                    } catch (Exception) {
                        return(false);
                    } finally {
                        lockToken.Dispose();
                    }

                    IsConnected = true;
                    return(true);
                }

                // First switch broker proxy so that all new sessions are created for the new broker
                var oldBroker = _brokerProxy.Set(brokerClient);
                if (_updateHostLoadLoopTask == null)
                {
                    _updateHostLoadLoopTask = UpdateHostLoadLoopAsync();
                }

                try {
                    BrokerChanging?.Invoke(this, EventArgs.Empty);
                    await SwitchBrokerAsync(cancellationToken);

                    oldBroker.Dispose();
                } catch (Exception ex) {
                    _brokerProxy.Set(oldBroker);
                    if (_disposeToken.IsDisposed)
                    {
                        oldBroker.Dispose();
                    }
                    brokerClient.Dispose();
                    BrokerChangeFailed?.Invoke(this, EventArgs.Empty);
                    if (ex is OperationCanceledException || ex is ComponentBinaryMissingException)
                    {
                        // RHostDisconnectedException is derived from OperationCanceledException
                        return(false);
                    }
                    throw;
                } finally {
                    lockToken.Dispose();
                }

                IsConnected = true;
                OnBrokerChanged();
                return(true);
            }
        }
예제 #2
0
        public async Task <bool> TrySwitchBrokerAsync(string name, string path = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            await TaskUtilities.SwitchToBackgroundThread();

            var brokerClient = CreateBrokerClient(name, path);

            if (brokerClient == null)
            {
                return(false);
            }

            // Broker switching shouldn't be concurrent
            IAsyncReaderWriterLockToken lockToken = null;

            try {
                lockToken = await _connectArwl.WriterLockAsync(cancellationToken);
            } catch (OperationCanceledException) {
                lockToken?.Dispose();
                brokerClient.Dispose();
                return(false);
            }

            if (brokerClient.Name.EqualsOrdinal(_brokerProxy.Name) &&
                brokerClient.Uri.AbsoluteUri.PathEquals(_brokerProxy.Uri.AbsoluteUri))
            {
                brokerClient.Dispose();

                try {
                    // Switching to the broker that is currently running and connected is always successful
                    if (IsConnected)
                    {
                        return(true);
                    }

                    await ReconnectAsync(cancellationToken, lockToken.Reentrancy);
                } catch (Exception) {
                    return(false);
                } finally {
                    lockToken.Dispose();
                }

                OnBrokerConnected();
                return(true);
            }

            // First switch broker proxy so that all new sessions are created for the new broker
            var oldBroker = _brokerProxy.Set(brokerClient);

            try {
                BrokerChanging?.Invoke(this, EventArgs.Empty);
                await SwitchBrokerAsync(oldBroker, cancellationToken, lockToken.Reentrancy);

                oldBroker.Dispose();

                if (brokerClient.IsRemote)
                {
                    _callback.Write(Environment.NewLine + Resources.Connected + Environment.NewLine);
                    PrintBrokerInformation();
                }
            } catch (Exception ex) {
                _brokerProxy.Set(oldBroker);
                brokerClient.Dispose();
                BrokerChangeFailed?.Invoke(this, EventArgs.Empty);
                if (ex is OperationCanceledException || ex is RHostBrokerBinaryMissingException)   // RHostDisconnectedException is derived from OperationCanceledException
                {
                    return(false);
                }
                throw;
            } finally {
                lockToken.Dispose();
            }

            OnBrokerConnected();
            BrokerChanged?.Invoke(this, new EventArgs());
            return(true);
        }