diff --git a/projects/RabbitMQ.Client/client/impl/AutorecoveringConnection.cs b/projects/RabbitMQ.Client/client/impl/AutorecoveringConnection.cs index c19f677ad0..98af92ca2a 100644 --- a/projects/RabbitMQ.Client/client/impl/AutorecoveringConnection.cs +++ b/projects/RabbitMQ.Client/client/impl/AutorecoveringConnection.cs @@ -451,6 +451,24 @@ private bool TryPerformAutomaticRecovery() catch (Exception e) { ESLog.Error("Exception when recovering connection. Will try again after retry interval.", e); + + try + { + /* + * To prevent connection leaks on the next recovery loop, + * we abort the delegated connection if it is still open. + * We do not want to block the abort forever (potentially deadlocking recovery), + * so we specify the same configured timeout used for connection. + */ + if (_delegate?.IsOpen == true) + { + _delegate.Abort(Constants.InternalError, "FailedAutoRecovery", ShutdownInitiator.Library, _factory.RequestedConnectionTimeout); + } + } + catch (Exception e2) + { + ESLog.Warn("Exception when aborting previous auto recovery connection.", e2); + } } return false; @@ -672,7 +690,6 @@ private void Init(IFrameHandler fh) lock (_eventLock) { ConnectionShutdown += recoveryListener; - _recordedShutdownEventHandlers += recoveryListener; } } diff --git a/projects/RabbitMQ.Client/client/impl/Connection.cs b/projects/RabbitMQ.Client/client/impl/Connection.cs index 40a79c97f0..9a1dc55da6 100644 --- a/projects/RabbitMQ.Client/client/impl/Connection.cs +++ b/projects/RabbitMQ.Client/client/impl/Connection.cs @@ -116,7 +116,15 @@ public Connection(IConnectionFactory factory, bool insist, IFrameHandler frameHa _model0 = (ModelBase)Protocol.CreateModel(_session0); StartMainLoop(factory.UseBackgroundThreadsForIO); - Open(insist); + try + { + Open(insist); + } + catch + { + TerminateMainloop(); + throw; + } } public Guid Id { get { return _id; } } diff --git a/projects/RabbitMQ.Client/client/impl/SocketFrameHandler.cs b/projects/RabbitMQ.Client/client/impl/SocketFrameHandler.cs index 158e2496f5..7ff75a9bf3 100644 --- a/projects/RabbitMQ.Client/client/impl/SocketFrameHandler.cs +++ b/projects/RabbitMQ.Client/client/impl/SocketFrameHandler.cs @@ -193,17 +193,18 @@ public void Close() try { _channelWriter.Complete(); - _writerTask.GetAwaiter().GetResult(); + _writerTask?.GetAwaiter().GetResult(); } - catch(Exception) + catch { + // ignore, we are closing anyway } try { _socket.Close(); } - catch (Exception) + catch { // ignore, we are closing anyway }