Пример #1
0
            internal async ValueTask NextConnectorAsync()
            {
                System.Exception?lastException = null;
                for (int i = 0; i < _connectors.Count; ++i)
                {
                    ConnectorInfo connector = _connectors[i];
                    try
                    {
                        ICommunicatorObserver?obsv = _factory._communicator.Observer;
                        if (obsv != null)
                        {
                            _observer = obsv.GetConnectionEstablishmentObserver(connector.Endpoint,
                                                                                connector.Connector.ToString() !);
                            if (_observer != null)
                            {
                                _observer.Attach();
                            }
                        }

                        if (_factory._communicator.TraceLevels.Network >= 2)
                        {
                            _factory._communicator.Logger.Trace(_factory._communicator.TraceLevels.NetworkCat,
                                                                $"trying to establish {connector.Endpoint.Name} connection to " +
                                                                $"{connector.Connector}");
                        }

                        // TODO: Connection establishement code needs to be re-factored to use async/await
                        Connection connection = _factory.CreateConnection(connector.Connector.Connect(), connector);
                        await connection.StartAsync().ConfigureAwait(false);

                        if (_observer != null)
                        {
                            _observer.Detach();
                        }

                        _factory.FinishGetConnection(_connectors, connector, connection, this);
                        return;
                    }
                    catch (CommunicatorDestroyedException ex)
                    {
                        lastException = ex;
                        break; // No need to continue
                    }
                    catch (System.Exception ex)
                    {
                        if (_factory._communicator.TraceLevels.Network >= 2)
                        {
                            Debug.Assert(connector != null);
                            _factory._communicator.Logger.Trace(_factory._communicator.TraceLevels.NetworkCat,
                                                                $"failed to establish {connector.Endpoint.Name} connection to " +
                                                                $"{connector.Connector}\n{ex}");
                        }
                        if (_observer != null)
                        {
                            _observer.Failed(ex.GetType().FullName ?? "System.Exception");
                            _observer.Detach();
                        }
                        _factory.HandleConnectionException(ex, _hasMore || (i + 1) < _connectors.Count);
                        lastException = ex;
                    }
                }

                _factory.FinishGetConnection(_connectors, lastException !, this);
            }
Пример #2
0
        public IncomingConnectionFactory(ObjectAdapter adapter, Endpoint endpoint, Endpoint?publish,
                                         ACMConfig acmConfig)
        {
            _communicator      = adapter.Communicator;
            _endpoint          = endpoint;
            _publishedEndpoint = publish;
            _adapter           = adapter;
            _warn    = _communicator.GetPropertyAsBool("Ice.Warn.Connections") ?? false;
            _monitor = new FactoryACMMonitor(_communicator, acmConfig);

            if (_communicator.OverrideTimeout != null)
            {
                _endpoint = _endpoint.NewTimeout(_communicator.OverrideTimeout.Value);
            }

            if (_communicator.OverrideCompress != null)
            {
                _endpoint = _endpoint.NewCompressionFlag(_communicator.OverrideCompress.Value);
            }

            try
            {
                _transceiver = _endpoint.GetTransceiver();
                if (_transceiver != null)
                {
                    if (_communicator.TraceLevels.Network >= 2)
                    {
                        _communicator.Logger.Trace(_communicator.TraceLevels.NetworkCat,
                                                   $"attempting to bind to {_endpoint.Name} socket\n{_transceiver}");
                    }
                    _endpoint = _transceiver.Bind();

                    var connection = new Connection(_communicator, null, _transceiver, null, _endpoint, _adapter);
                    _ = connection.StartAsync();
                    _connections.Add(connection);
                }
                else
                {
                    _acceptor = _endpoint.GetAcceptor(_adapter !.Name);

                    if (_communicator.TraceLevels.Network >= 2)
                    {
                        _communicator.Logger.Trace(_communicator.TraceLevels.NetworkCat,
                                                   $"attempting to bind to {_endpoint.Name} socket {_acceptor}");
                    }
                    _endpoint = _acceptor !.Listen();

                    if (_communicator.TraceLevels.Network >= 1)
                    {
                        _communicator.Logger.Trace(_communicator.TraceLevels.NetworkCat,
                                                   $"listening for {_endpoint.Name} connections\n{_acceptor!.ToDetailedString()}");
                    }
                }
            }
            catch (System.Exception)
            {
                //
                // Clean up.
                //
                try
                {
                    _transceiver?.Close();
                    _acceptor?.Close();
                }
                catch (System.Exception)
                {
                    // Ignore
                }

                _monitor.Destroy();
                _connections.Clear();

                throw;
            }
        }
Пример #3
0
        private async ValueTask AcceptAsync()
        {
            while (true)
            {
                ITransceiver transceiver;
                try
                {
                    transceiver = await _acceptor !.AcceptAsync().ConfigureAwait(false);
                }
                catch (System.Exception ex)
                {
                    // If Accept failed because the acceptor has been closed, just return, we're done. Otherwise
                    // we print an error and wait for one second to avoid running in a tight loop in case the
                    // failures occurs immediately again. Failures here are unexpected and could be considered
                    // fatal.
                    lock (this)
                    {
                        if (_destroyed)
                        {
                            return;
                        }
                    }
                    _communicator.Logger.Error($"failed to accept connection:\n{ex}\n{_acceptor}");
                    await Task.Delay(1000).ConfigureAwait(false); // Retry in 1 second

                    continue;
                }

                Connection connection;
                lock (this)
                {
                    Debug.Assert(transceiver != null);
                    if (_destroyed)
                    {
                        try
                        {
                            transceiver.Close();
                        }
                        catch (System.Exception)
                        {
                        }
                        return;
                    }

                    // Reap closed connections
                    foreach (Connection c in _monitor.SwapReapedConnections())
                    {
                        _connections.Remove(c);
                    }

                    if (_communicator.TraceLevels.Network >= 2)
                    {
                        _communicator.Logger.Trace(_communicator.TraceLevels.NetworkCat,
                                                   $"trying to accept {_endpoint.Name} connection\n{transceiver}");
                    }

                    try
                    {
                        connection = new Connection(_communicator, _monitor, transceiver, null, _endpoint, _adapter);
                    }
                    catch (System.Exception ex)
                    {
                        try
                        {
                            transceiver.Close();
                        }
                        catch (System.Exception)
                        {
                            // Ignore
                        }

                        if (_warn)
                        {
                            _communicator.Logger.Warning($"connection exception:\n{ex}\n{_acceptor}");
                        }
                        continue;
                    }

                    _connections.Add(connection);
                }

                Debug.Assert(connection != null);
                try
                {
                    // We don't wait for the connection to be activated. This could take a while for some tranports
                    // such as TLS based transports where the handshake requires few round trips between the client
                    // and server.
                    _ = connection.StartAsync();
                }
                catch (ObjectAdapterDeactivatedException)
                {
                    // Ignore
                }
                catch (System.Exception ex)
                {
                    if (_communicator.TraceLevels.Network >= 2)
                    {
                        _communicator.Logger.Trace(_communicator.TraceLevels.NetworkCat,
                                                   $"failed to accept {_endpoint.Name} connection\n{connection}\n{ex}");
                    }
                }
            }
        }