Added support for delaying feature initialisation
This commit is contained in:
parent
d4ab9f87d1
commit
d4cc061955
9
.readthedocs.yaml
Normal file
9
.readthedocs.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
version 2
|
||||
|
||||
build
|
||||
os ubuntu-22.04
|
||||
tools
|
||||
python 3.12
|
||||
|
||||
sphinx
|
||||
configuration docs/conf.py
|
@ -17,7 +17,10 @@ namespace Tapeti.Config
|
||||
/// <summary>
|
||||
/// Various Tapeti features which can be turned on or off.
|
||||
/// </summary>
|
||||
ITapetiConfigFeatues Features { get; }
|
||||
/// <remarks>
|
||||
/// Calling this method will freeze the feature set if <see cref="ITapetiConfigBuilder.DelayFeatures"/> is used.
|
||||
/// </remarks>
|
||||
ITapetiConfigFeatures GetFeatures();
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to the different kinds of registered middleware.
|
||||
@ -34,7 +37,7 @@ namespace Tapeti.Config
|
||||
/// <summary>
|
||||
/// Various Tapeti features which can be turned on or off.
|
||||
/// </summary>
|
||||
public interface ITapetiConfigFeatues
|
||||
public interface ITapetiConfigFeatures
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines whether 'publisher confirms' are used. This RabbitMQ features allows Tapeti to
|
||||
|
@ -53,6 +53,40 @@ namespace Tapeti.Config
|
||||
void RegisterBinding(IBinding binding);
|
||||
|
||||
|
||||
/// <inheritdoc cref="ITapetiConfigFeaturesBuilder.DisablePublisherConfirms"/>
|
||||
ITapetiConfigBuilder DisablePublisherConfirms();
|
||||
|
||||
/// <inheritdoc cref="ITapetiConfigFeaturesBuilder.SetPublisherConfirms"/>
|
||||
ITapetiConfigBuilder SetPublisherConfirms(bool enabled);
|
||||
|
||||
/// <inheritdoc cref="ITapetiConfigFeaturesBuilder.EnableDeclareDurableQueues"/>
|
||||
ITapetiConfigBuilder EnableDeclareDurableQueues();
|
||||
|
||||
/// <inheritdoc cref="ITapetiConfigFeaturesBuilder.SetDeclareDurableQueues"/>
|
||||
ITapetiConfigBuilder SetDeclareDurableQueues(bool enabled);
|
||||
|
||||
/// <inheritdoc cref="ITapetiConfigFeaturesBuilder.DisableVerifyDurableQueues"/>
|
||||
ITapetiConfigBuilder DisableVerifyDurableQueues();
|
||||
|
||||
/// <inheritdoc cref="ITapetiConfigFeaturesBuilder.SetVerifyDurableQueues"/>
|
||||
ITapetiConfigBuilder SetVerifyDurableQueues(bool enabled);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Allows the core features to be determine on-demand when first required by the connection instead
|
||||
/// of before <see cref="TapetiConnection"/> is constructed.
|
||||
/// </summary>
|
||||
/// <param name="onBuild">Called when the feature set is required. From that moment on the feature set is frozen.</param>
|
||||
ITapetiConfigBuilder DelayFeatures(Action<ITapetiConfigFeaturesBuilder> onBuild);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Configures Tapeti core features. Every method returns the builder instance for method chaining.
|
||||
/// </summary>
|
||||
public interface ITapetiConfigFeaturesBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// Disables 'publisher confirms'. This RabbitMQ features allows Tapeti to be notified if a message
|
||||
/// has no route, and guarantees delivery for request-response style messages and those marked with
|
||||
@ -62,7 +96,7 @@ namespace Tapeti.Config
|
||||
/// and disables Tapeti.Flow from verifying if a request/response can be routed. This may
|
||||
/// result in never-ending flows. Only disable if you can accept those consequences.
|
||||
/// </summary>
|
||||
ITapetiConfigBuilder DisablePublisherConfirms();
|
||||
ITapetiConfigFeaturesBuilder DisablePublisherConfirms();
|
||||
|
||||
|
||||
/// <summary>
|
||||
@ -74,7 +108,7 @@ namespace Tapeti.Config
|
||||
/// and disables Tapeti.Flow from verifying if a request/response can be routed. This may
|
||||
/// result in never-ending flows. Only disable if you can accept those consequences.
|
||||
/// </summary>
|
||||
ITapetiConfigBuilder SetPublisherConfirms(bool enabled);
|
||||
ITapetiConfigFeaturesBuilder SetPublisherConfirms(bool enabled);
|
||||
|
||||
|
||||
/// <summary>
|
||||
@ -84,7 +118,7 @@ namespace Tapeti.Config
|
||||
/// Note that access to the RabbitMQ Management plugin's REST API is required for this
|
||||
/// feature to work, since AMQP does not provide a way to query existing bindings.
|
||||
/// </remarks>
|
||||
ITapetiConfigBuilder EnableDeclareDurableQueues();
|
||||
ITapetiConfigFeaturesBuilder EnableDeclareDurableQueues();
|
||||
|
||||
/// <summary>
|
||||
/// Configures the automatic creation of durable queues and updating of their bindings.
|
||||
@ -93,7 +127,7 @@ namespace Tapeti.Config
|
||||
/// Note that access to the RabbitMQ Management plugin's REST API is required for this
|
||||
/// feature to work, since AMQP does not provide a way to query existing bindings.
|
||||
/// </remarks>
|
||||
ITapetiConfigBuilder SetDeclareDurableQueues(bool enabled);
|
||||
ITapetiConfigFeaturesBuilder SetDeclareDurableQueues(bool enabled);
|
||||
|
||||
|
||||
/// <summary>
|
||||
@ -102,7 +136,7 @@ namespace Tapeti.Config
|
||||
/// exchange, which do not correspond to Tapeti's configuration, as these will cause an error
|
||||
/// while verifying.
|
||||
/// </summary>
|
||||
ITapetiConfigBuilder DisableVerifyDurableQueues();
|
||||
ITapetiConfigFeaturesBuilder DisableVerifyDurableQueues();
|
||||
|
||||
|
||||
/// <summary>
|
||||
@ -111,7 +145,7 @@ namespace Tapeti.Config
|
||||
/// exchange, which do not correspond to Tapeti's configuration, as these will cause an error
|
||||
/// while verifying.
|
||||
/// </summary>
|
||||
ITapetiConfigBuilder SetVerifyDurableQueues(bool enabled);
|
||||
ITapetiConfigFeaturesBuilder SetVerifyDurableQueues(bool enabled);
|
||||
}
|
||||
|
||||
|
||||
|
@ -135,7 +135,7 @@ namespace Tapeti.Connection
|
||||
DeclareExchange(channel, exchange);
|
||||
|
||||
// The delivery tag is lost after a reconnect, register under the new tag
|
||||
if (config.Features.PublisherConfirms)
|
||||
if (config.GetFeatures().PublisherConfirms)
|
||||
{
|
||||
lastDeliveryTag++;
|
||||
|
||||
@ -848,7 +848,7 @@ namespace Tapeti.Connection
|
||||
}
|
||||
|
||||
|
||||
if (config.Features.PublisherConfirms)
|
||||
if (config.GetFeatures().PublisherConfirms)
|
||||
{
|
||||
lastDeliveryTag = 0;
|
||||
|
||||
|
@ -125,9 +125,9 @@ namespace Tapeti.Connection
|
||||
|
||||
CustomBindingTarget bindingTarget;
|
||||
|
||||
if (config.Features.DeclareDurableQueues)
|
||||
if (config.GetFeatures().DeclareDurableQueues)
|
||||
bindingTarget = new DeclareDurableQueuesBindingTarget(clientFactory, routingKeyStrategy, exchangeStrategy, cancellationToken);
|
||||
else if (config.Features.VerifyDurableQueues)
|
||||
else if (config.GetFeatures().VerifyDurableQueues)
|
||||
bindingTarget = new PassiveDurableQueuesBindingTarget(clientFactory, routingKeyStrategy, exchangeStrategy, cancellationToken);
|
||||
else
|
||||
bindingTarget = new NoVerifyBindingTarget(clientFactory, routingKeyStrategy, exchangeStrategy, cancellationToken);
|
||||
|
@ -135,7 +135,7 @@ namespace Tapeti
|
||||
/// <inheritdoc />
|
||||
public ITapetiConfigBuilder DisablePublisherConfirms()
|
||||
{
|
||||
GetConfig().SetPublisherConfirms(false);
|
||||
GetConfig().GetFeaturesBuilder().DisablePublisherConfirms();
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -143,7 +143,7 @@ namespace Tapeti
|
||||
/// <inheritdoc />
|
||||
public ITapetiConfigBuilder SetPublisherConfirms(bool enabled)
|
||||
{
|
||||
GetConfig().SetPublisherConfirms(enabled);
|
||||
GetConfig().GetFeaturesBuilder().SetPublisherConfirms(enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ namespace Tapeti
|
||||
/// <inheritdoc />
|
||||
public ITapetiConfigBuilder EnableDeclareDurableQueues()
|
||||
{
|
||||
GetConfig().SetDeclareDurableQueues(true);
|
||||
GetConfig().GetFeaturesBuilder().EnableDeclareDurableQueues();
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ namespace Tapeti
|
||||
/// <inheritdoc />
|
||||
public ITapetiConfigBuilder SetDeclareDurableQueues(bool enabled)
|
||||
{
|
||||
GetConfig().SetDeclareDurableQueues(enabled);
|
||||
GetConfig().GetFeaturesBuilder().SetDeclareDurableQueues(enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -167,7 +167,7 @@ namespace Tapeti
|
||||
/// <inheritdoc />
|
||||
public ITapetiConfigBuilder DisableVerifyDurableQueues()
|
||||
{
|
||||
GetConfig().SetVerifyDurableQueues(false);
|
||||
GetConfig().GetFeaturesBuilder().DisablePublisherConfirms();
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -175,7 +175,15 @@ namespace Tapeti
|
||||
/// <inheritdoc />
|
||||
public ITapetiConfigBuilder SetVerifyDurableQueues(bool enabled)
|
||||
{
|
||||
GetConfig().SetVerifyDurableQueues(enabled);
|
||||
GetConfig().GetFeaturesBuilder().SetVerifyDurableQueues(enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public ITapetiConfigBuilder DelayFeatures(Action<ITapetiConfigFeaturesBuilder> onBuild)
|
||||
{
|
||||
GetConfig().GetFeaturesBuilder().DelayFeatures(onBuild);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -221,12 +229,13 @@ namespace Tapeti
|
||||
/// <inheritdoc />
|
||||
internal class Config : ITapetiConfig
|
||||
{
|
||||
private readonly ConfigFeatures features = new();
|
||||
private ConfigFeaturesBuilder? featuresBuilder = new();
|
||||
private ITapetiConfigFeatures? features;
|
||||
|
||||
private readonly ConfigMiddleware middleware = new();
|
||||
private readonly ConfigBindings bindings = new();
|
||||
|
||||
public IDependencyResolver DependencyResolver { get; }
|
||||
public ITapetiConfigFeatues Features => features;
|
||||
public ITapetiConfigMiddleware Middleware => middleware;
|
||||
public ITapetiConfigBindings Bindings => bindings;
|
||||
|
||||
@ -237,6 +246,17 @@ namespace Tapeti
|
||||
}
|
||||
|
||||
|
||||
public ITapetiConfigFeatures GetFeatures()
|
||||
{
|
||||
if (features != null)
|
||||
return features;
|
||||
|
||||
features = featuresBuilder!.Build();
|
||||
featuresBuilder = null;
|
||||
return features;
|
||||
}
|
||||
|
||||
|
||||
public void Lock()
|
||||
{
|
||||
bindings.Lock();
|
||||
@ -260,24 +280,17 @@ namespace Tapeti
|
||||
}
|
||||
|
||||
|
||||
public void SetPublisherConfirms(bool enabled)
|
||||
internal ConfigFeaturesBuilder GetFeaturesBuilder()
|
||||
{
|
||||
features.PublisherConfirms = enabled;
|
||||
}
|
||||
if (featuresBuilder == null)
|
||||
throw new InvalidOperationException("Tapeti features are already frozen");
|
||||
|
||||
public void SetDeclareDurableQueues(bool enabled)
|
||||
{
|
||||
features.DeclareDurableQueues = enabled;
|
||||
}
|
||||
|
||||
public void SetVerifyDurableQueues(bool enabled)
|
||||
{
|
||||
features.VerifyDurableQueues = enabled;
|
||||
return featuresBuilder;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal class ConfigFeatures : ITapetiConfigFeatues
|
||||
internal class ConfigFeatures : ITapetiConfigFeatures
|
||||
{
|
||||
public bool PublisherConfirms { get; internal set; } = true;
|
||||
public bool DeclareDurableQueues { get; internal set; }
|
||||
@ -285,6 +298,66 @@ namespace Tapeti
|
||||
}
|
||||
|
||||
|
||||
internal class ConfigFeaturesBuilder : ITapetiConfigFeaturesBuilder
|
||||
{
|
||||
private bool publisherConfirms = true;
|
||||
private bool declareDurableQueues;
|
||||
private bool verifyDurableQueues = true;
|
||||
private Action<ITapetiConfigFeaturesBuilder>? onBuild;
|
||||
|
||||
|
||||
public ITapetiConfigFeaturesBuilder DisablePublisherConfirms()
|
||||
{
|
||||
return SetPublisherConfirms(false);
|
||||
}
|
||||
|
||||
public ITapetiConfigFeaturesBuilder SetPublisherConfirms(bool enabled)
|
||||
{
|
||||
publisherConfirms = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ITapetiConfigFeaturesBuilder EnableDeclareDurableQueues()
|
||||
{
|
||||
return SetDeclareDurableQueues(true);
|
||||
}
|
||||
|
||||
public ITapetiConfigFeaturesBuilder SetDeclareDurableQueues(bool enabled)
|
||||
{
|
||||
declareDurableQueues = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ITapetiConfigFeaturesBuilder DisableVerifyDurableQueues()
|
||||
{
|
||||
return SetVerifyDurableQueues(false);
|
||||
}
|
||||
|
||||
public ITapetiConfigFeaturesBuilder SetVerifyDurableQueues(bool enabled)
|
||||
{
|
||||
verifyDurableQueues = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
// ReSharper disable once ParameterHidesMember
|
||||
public void DelayFeatures(Action<ITapetiConfigFeaturesBuilder> onBuild)
|
||||
{
|
||||
this.onBuild = onBuild;
|
||||
}
|
||||
|
||||
public ITapetiConfigFeatures Build()
|
||||
{
|
||||
onBuild?.Invoke(this);
|
||||
return new ConfigFeatures
|
||||
{
|
||||
DeclareDurableQueues = declareDurableQueues,
|
||||
PublisherConfirms = publisherConfirms,
|
||||
VerifyDurableQueues = verifyDurableQueues
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal class ConfigMiddleware : ITapetiConfigMiddleware
|
||||
{
|
||||
private readonly List<IMessageMiddleware> messageMiddleware = new();
|
||||
|
Loading…
Reference in New Issue
Block a user