private Task<IConnection> GetConnectionAsync()
{
if (_connection == null)
{
_logger.LogDebug($"Creating a new connection for {_config.Hostnames.Count} hosts.");
_connection = _connectionFactory.CreateConnection(_config.Hostnames);
}
if (_connection.IsOpen)
{
_logger.LogDebug("Existing connection is open and will be used.");
return Task.FromResult(_connection);
}
_logger.LogInformation("The existing connection is not open.");
if (_connection.CloseReason.Initiator == ShutdownInitiator.Application)
{
_logger.LogInformation("Connection is closed with Application as initiator. It will not be recovered.");
_connection.Dispose();
throw new Exception("Application shutdown is initiated by the Application. A new connection will not be created.");
}
var recoverable = _connection as IRecoverable;
if (recoverable == null)
{
_logger.LogInformation("Connection is not recoverable, trying to create a new connection.");
_connection.Dispose();
throw new Exception("The non recoverable connection is closed. A channel can not be obtained.");
}
_logger.LogDebug("Connection is recoverable. Waiting for 'Recovery' event to be triggered. ");
var recoverTcs = new TaskCompletionSource<IConnection>();
EventHandler<EventArgs> completeTask = null;
completeTask = (sender, args) =>
{
_logger.LogDebug("Connection has been recovered!");
recoverTcs.TrySetResult(recoverable as IConnection);
recoverable.Recovery -= completeTask;
};
recoverable.Recovery += completeTask;
return recoverTcs.Task;
}
}