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); }
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; } }
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}"); } } } }