2016-11-16 23:11:05 +01:00
|
|
|
|
using System;
|
|
|
|
|
using System.Threading.Tasks;
|
2016-12-11 15:08:58 +01:00
|
|
|
|
using Tapeti.Config;
|
2016-11-16 23:11:05 +01:00
|
|
|
|
using Tapeti.Connection;
|
|
|
|
|
|
2018-12-19 20:50:56 +01:00
|
|
|
|
// ReSharper disable UnusedMember.Global
|
|
|
|
|
|
2019-08-13 20:30:04 +02:00
|
|
|
|
// TODO more separation from the actual worker / RabbitMQ Client for unit testing purposes
|
|
|
|
|
|
2016-11-16 23:11:05 +01:00
|
|
|
|
namespace Tapeti
|
|
|
|
|
{
|
2019-08-13 20:30:04 +02:00
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a connection to RabbitMQ based on the provided Tapeti config.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class TapetiConnection : IConnection
|
2016-11-16 23:11:05 +01:00
|
|
|
|
{
|
2019-08-13 20:30:04 +02:00
|
|
|
|
private readonly ITapetiConfig config;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Specifies the hostname and credentials to use when connecting to RabbitMQ.
|
|
|
|
|
/// Defaults to guest on localhost.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// This property must be set before first subscribing or publishing, otherwise it
|
|
|
|
|
/// will use the default connection parameters.
|
|
|
|
|
/// </remarks>
|
2016-11-21 20:54:29 +01:00
|
|
|
|
public TapetiConnectionParams Params { get; set; }
|
|
|
|
|
|
2019-08-15 11:32:39 +02:00
|
|
|
|
private readonly Lazy<ITapetiClient> client;
|
2019-01-25 14:52:09 +01:00
|
|
|
|
private TapetiSubscriber subscriber;
|
2016-11-21 20:54:29 +01:00
|
|
|
|
|
2019-08-13 20:30:04 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a new instance of a TapetiConnection and registers a default IPublisher
|
|
|
|
|
/// in the IoC container as provided in the config.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="config"></param>
|
|
|
|
|
public TapetiConnection(ITapetiConfig config)
|
2016-11-21 20:54:29 +01:00
|
|
|
|
{
|
2016-12-11 15:08:58 +01:00
|
|
|
|
this.config = config;
|
2017-02-05 23:22:34 +01:00
|
|
|
|
(config.DependencyResolver as IDependencyContainer)?.RegisterDefault(GetPublisher);
|
2016-12-11 15:08:58 +01:00
|
|
|
|
|
2019-08-15 11:32:39 +02:00
|
|
|
|
client = new Lazy<ITapetiClient>(() => new TapetiClient(config, Params ?? new TapetiConnectionParams())
|
2016-11-21 20:54:29 +01:00
|
|
|
|
{
|
2017-07-14 12:33:09 +02:00
|
|
|
|
ConnectionEventListener = new ConnectionEventListener(this)
|
2016-11-21 20:54:29 +01:00
|
|
|
|
});
|
|
|
|
|
}
|
2016-11-16 23:11:05 +01:00
|
|
|
|
|
2019-08-13 20:30:04 +02:00
|
|
|
|
/// <inheritdoc />
|
2019-10-10 16:03:12 +02:00
|
|
|
|
public event ConnectedEventHandler Connected;
|
2019-08-13 20:30:04 +02:00
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
2019-02-13 12:00:34 +01:00
|
|
|
|
public event DisconnectedEventHandler Disconnected;
|
2019-08-13 20:30:04 +02:00
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
2019-10-10 16:03:12 +02:00
|
|
|
|
public event ConnectedEventHandler Reconnected;
|
2016-11-16 23:11:05 +01:00
|
|
|
|
|
2019-02-13 12:00:34 +01:00
|
|
|
|
|
2019-08-13 20:30:04 +02:00
|
|
|
|
/// <inheritdoc />
|
2017-02-12 15:18:12 +01:00
|
|
|
|
public async Task<ISubscriber> Subscribe(bool startConsuming = true)
|
2016-11-16 23:11:05 +01:00
|
|
|
|
{
|
2019-01-25 14:52:09 +01:00
|
|
|
|
if (subscriber == null)
|
|
|
|
|
{
|
2019-08-13 20:30:04 +02:00
|
|
|
|
subscriber = new TapetiSubscriber(() => client.Value, config);
|
|
|
|
|
await subscriber.ApplyBindings();
|
2019-01-25 14:52:09 +01:00
|
|
|
|
}
|
2017-02-12 15:18:12 +01:00
|
|
|
|
|
|
|
|
|
if (startConsuming)
|
|
|
|
|
await subscriber.Resume();
|
2016-11-20 14:34:50 +01:00
|
|
|
|
|
|
|
|
|
return subscriber;
|
2016-11-16 23:11:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-08-13 20:30:04 +02:00
|
|
|
|
/// <inheritdoc />
|
2019-01-25 14:52:09 +01:00
|
|
|
|
public ISubscriber SubscribeSync(bool startConsuming = true)
|
2017-02-11 21:32:03 +01:00
|
|
|
|
{
|
2019-01-25 14:52:09 +01:00
|
|
|
|
return Subscribe(startConsuming).Result;
|
2017-02-11 21:32:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-08-13 20:30:04 +02:00
|
|
|
|
/// <inheritdoc />
|
2016-11-16 23:11:05 +01:00
|
|
|
|
public IPublisher GetPublisher()
|
|
|
|
|
{
|
2019-08-13 20:30:04 +02:00
|
|
|
|
return new TapetiPublisher(config, () => client.Value);
|
2016-11-16 23:11:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-08-13 20:30:04 +02:00
|
|
|
|
/// <inheritdoc />
|
2016-11-16 23:11:05 +01:00
|
|
|
|
public async Task Close()
|
|
|
|
|
{
|
2019-08-13 20:30:04 +02:00
|
|
|
|
if (client.IsValueCreated)
|
|
|
|
|
await client.Value.Close();
|
2016-11-16 23:11:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2019-08-13 20:30:04 +02:00
|
|
|
|
/// <inheritdoc />
|
2016-11-16 23:11:05 +01:00
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
Close().Wait();
|
2019-10-10 16:03:12 +02:00
|
|
|
|
|
|
|
|
|
subscriber?.Dispose();
|
2016-11-16 23:11:05 +01:00
|
|
|
|
}
|
2017-07-14 12:33:09 +02:00
|
|
|
|
|
2019-08-13 20:30:04 +02:00
|
|
|
|
|
2017-07-14 12:33:09 +02:00
|
|
|
|
private class ConnectionEventListener: IConnectionEventListener
|
|
|
|
|
{
|
|
|
|
|
private readonly TapetiConnection owner;
|
|
|
|
|
|
|
|
|
|
internal ConnectionEventListener(TapetiConnection owner)
|
|
|
|
|
{
|
|
|
|
|
this.owner = owner;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-10 16:03:12 +02:00
|
|
|
|
public void Connected(ConnectedEventArgs e)
|
2017-07-14 12:33:09 +02:00
|
|
|
|
{
|
2019-10-10 16:03:12 +02:00
|
|
|
|
owner.OnConnected(e);
|
2017-07-14 12:33:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-02-13 12:00:34 +01:00
|
|
|
|
public void Disconnected(DisconnectedEventArgs e)
|
2017-07-14 12:33:09 +02:00
|
|
|
|
{
|
2019-02-13 12:00:34 +01:00
|
|
|
|
owner.OnDisconnected(e);
|
2017-07-14 12:33:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-10-10 16:03:12 +02:00
|
|
|
|
public void Reconnected(ConnectedEventArgs e)
|
2017-07-14 12:33:09 +02:00
|
|
|
|
{
|
2019-10-10 16:03:12 +02:00
|
|
|
|
owner.OnReconnected(e);
|
2017-07-14 12:33:09 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-13 20:30:04 +02:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Called when a connection to RabbitMQ has been established.
|
|
|
|
|
/// </summary>
|
2019-10-10 16:03:12 +02:00
|
|
|
|
protected virtual void OnConnected(ConnectedEventArgs e)
|
2017-07-14 12:33:09 +02:00
|
|
|
|
{
|
2019-08-13 20:30:04 +02:00
|
|
|
|
var connectedEvent = Connected;
|
|
|
|
|
if (connectedEvent == null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Task.Run(() => connectedEvent.Invoke(this, e));
|
2017-07-14 12:33:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-13 20:30:04 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Called when the connection to RabbitMQ has been lost.
|
|
|
|
|
/// </summary>
|
2019-10-10 16:03:12 +02:00
|
|
|
|
protected virtual void OnReconnected(ConnectedEventArgs e)
|
2017-07-14 12:33:09 +02:00
|
|
|
|
{
|
2019-08-13 20:30:04 +02:00
|
|
|
|
var reconnectedEvent = Reconnected;
|
2019-09-10 19:38:59 +02:00
|
|
|
|
if (reconnectedEvent == null && subscriber == null)
|
2019-08-13 20:30:04 +02:00
|
|
|
|
return;
|
|
|
|
|
|
2019-10-10 16:03:12 +02:00
|
|
|
|
subscriber?.Reconnect();
|
2019-09-10 19:38:59 +02:00
|
|
|
|
|
2019-10-10 16:03:12 +02:00
|
|
|
|
Task.Run(() => reconnectedEvent?.Invoke(this, e));
|
2017-07-14 12:33:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-08-13 20:30:04 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Called when the connection to RabbitMQ has been recovered after an unexpected disconnect.
|
|
|
|
|
/// </summary>
|
2019-02-13 12:00:34 +01:00
|
|
|
|
protected virtual void OnDisconnected(DisconnectedEventArgs e)
|
2017-07-14 12:33:09 +02:00
|
|
|
|
{
|
2019-08-13 20:30:04 +02:00
|
|
|
|
var disconnectedEvent = Disconnected;
|
|
|
|
|
if (disconnectedEvent == null)
|
|
|
|
|
return;
|
|
|
|
|
|
2019-10-10 16:03:12 +02:00
|
|
|
|
subscriber?.Disconnect();
|
|
|
|
|
|
2019-08-13 20:30:04 +02:00
|
|
|
|
Task.Run(() => disconnectedEvent.Invoke(this, e));
|
2017-07-14 12:33:09 +02:00
|
|
|
|
}
|
2016-11-16 23:11:05 +01:00
|
|
|
|
}
|
|
|
|
|
}
|