Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

<!-- The .NET Version used in all projects -->
<BrighterTargetFrameworks>netstandard2.0;net8.0;net9.0;net10.0</BrighterTargetFrameworks>
<BrighterTargetFrameworksNot10>net8.0;net9.0</BrighterTargetFrameworksNot10>
<BrighterFrameworkAndCoreTargetFrameworks>net472;net8.0;net9.0;net10.0</BrighterFrameworkAndCoreTargetFrameworks>
<BrighterCoreTargetFrameworks>net8.0;net9.0;net10.0</BrighterCoreTargetFrameworks>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
Expand Down
5 changes: 3 additions & 2 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
<Project>
<PropertyGroup>
<BrighterVersion>[10.0.0, 11.0.0)</BrighterVersion>
<BrighterVersion>[10.4.0, 11.0.0)</BrighterVersion>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="GitHubActionsTestLogger" Version="2.4.1" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageVersion Include="MinVer" Version="6.0.0" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="Paramore.Brighter" Version="$(BrighterVersion)" />
<PackageVersion Include="Paramore.Brighter.Inbox.DynamoDB" Version="$(BrighterVersion)" />
<PackageVersion Include="Paramore.Brighter.Inbox.DynamoDB.V4" Version="$(BrighterVersion)" />
Expand Down Expand Up @@ -54,7 +53,9 @@
<PackageVersion Include="Paramore.Brighter.Transformers.AWS.V4" Version="$(BrighterVersion)" />
<PackageVersion Include="Paramore.Brighter.Transformers.Gcp" Version="$(BrighterVersion)" />
<PackageVersion Include="Paramore.Brighter.Transformers.MongoGridFS" Version="$(BrighterVersion)" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="Serilog.AspNetCore" Version="10.0.0" />
<PackageVersion Include="TUnit" Version="1.18.21" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.1">
<PrivateAssets>all</PrivateAssets>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ string connectionString
/// Configures the consumer to use Google Cloud Spanner as the inbox storage with a pre-configured inbox instance.
/// </summary>
/// <param name="builder">The consumer builder instance.</param>
/// <param name="inbox">The configured <see cref="SpannerInbox"/> instance.</param>
/// <param name="inbox">The configured <see cref="SpannerInboxAsync"/> instance.</param>
/// <returns>The consumer builder for method chaining.</returns>
public static ConsumerBuilder UseSpannerInbox(this ConsumerBuilder builder, SpannerInbox inbox)
public static ConsumerBuilder UseSpannerInbox(this ConsumerBuilder builder, SpannerInboxAsync inbox)
{
return builder.SetInbox(cfg => cfg.SetInbox(inbox));
}
Expand Down
12 changes: 6 additions & 6 deletions src/Fluent.Brighter.GoogleCloud/SpannerInboxBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace Fluent.Brighter.GoogleCloud;

/// <summary>
/// Builder class for creating instances of <see cref="SpannerInbox"/>.
/// Builder class for creating instances of <see cref="SpannerInboxAsync"/>.
/// Provides a fluent API for configuring Google Cloud Spanner inbox storage.
/// </summary>
public sealed class SpannerInboxBuilder
Expand Down Expand Up @@ -38,19 +38,19 @@ IAmARelationalDbConnectionProvider connectionProvider
}

/// <summary>
/// Builds a new instance of <see cref="SpannerInbox"/> using the configured settings.
/// Builds a new instance of <see cref="SpannerInboxAsync"/> using the configured settings.
/// </summary>
/// <returns>A configured <see cref="SpannerInbox"/> instance.</returns>
/// <returns>A configured <see cref="SpannerInboxAsync"/> instance.</returns>
/// <exception cref="ConfigurationException">Thrown when configuration is not set.</exception>
internal SpannerInbox Build()
internal SpannerInboxAsync Build()
{
if (_configuration == null)
{
throw new ConfigurationException("Configuration is null");
}

return _connectionProvider == null
? new SpannerInbox(_configuration)
: new SpannerInbox(_configuration, _connectionProvider);
? new SpannerInboxAsync(_configuration)
: new SpannerInboxAsync(_configuration, _connectionProvider);
}
}
2 changes: 1 addition & 1 deletion src/Fluent.Brighter.MySql/Fluent.Brighter.MySql.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>$(BrighterTargetFrameworks)</TargetFrameworks>
<TargetFrameworks>$(BrighterTargetFrameworksNot10)</TargetFrameworks>
<IsPackable>true</IsPackable>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
112 changes: 38 additions & 74 deletions src/Fluent.Brighter.Redis/RedisSubscriptionBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;

using Paramore.Brighter;
using Paramore.Brighter.MessagingGateway.Redis;

Expand All @@ -13,7 +12,7 @@ namespace Fluent.Brighter.Redis;
public sealed class RedisSubscriptionBuilder
{
private SubscriptionName _subscriptionName = new(Uuid.New().ToString("N"));

/// <summary>
/// Sets the subscription name that uniquely identifies this subscription.
/// The subscription name is used to track and manage the subscription within the Brighter framework.
Expand All @@ -25,10 +24,10 @@ public RedisSubscriptionBuilder SetSubscription(SubscriptionName subscriptionNam
_subscriptionName = subscriptionName;
return this;
}

private ChannelName? _channelName;
private RoutingKey? _routingKey;

/// <summary>
/// Sets the channel name and routing key for the subscription.
/// The channel represents the Redis queue/topic from which messages will be consumed.
Expand All @@ -41,7 +40,7 @@ public RedisSubscriptionBuilder SetQueue(ChannelName channelName)
_channelName = channelName;
return this;
}

/// <summary>
/// Sets the routing key (topic) for the subscription.
/// This determines which messages will be routed to this subscription based on the topic pattern.
Expand All @@ -53,9 +52,9 @@ public RedisSubscriptionBuilder SetTopic(RoutingKey routingKey)
_routingKey = routingKey;
return this;
}

private Type? _dataType;

/// <summary>
/// Sets the data type for messages in this subscription.
/// When provided, this method will automatically configure the subscription name, channel name,
Expand All @@ -66,20 +65,20 @@ public RedisSubscriptionBuilder SetTopic(RoutingKey routingKey)
public RedisSubscriptionBuilder SetDataType(Type? dataType)
{
_dataType = dataType;

if (dataType != null)
{
var typeName = dataType.FullName!;
_subscriptionName ??= new SubscriptionName(typeName);
_channelName ??= new ChannelName(typeName);
_routingKey ??= new RoutingKey(typeName);
}

return this;
}

private Func<Message, Type>? _getRequestType;

/// <summary>
/// Sets a function that determines the request type dynamically based on the message content.
/// This allows for polymorphic message handling where different message types can be processed by different handlers.
Expand All @@ -91,9 +90,9 @@ public RedisSubscriptionBuilder SetGetRequestType(Func<Message, Type>? getReques
_getRequestType = getRequestType;
return this;
}

private int _bufferSize = 1;

/// <summary>
/// Sets the buffer size for the message channel.
/// The buffer size determines how many messages can be queued in memory before processing,
Expand All @@ -106,9 +105,9 @@ public RedisSubscriptionBuilder SetBufferSize(int bufferSize)
_bufferSize = bufferSize;
return this;
}

private int _noOfPerformers = 1;

/// <summary>
/// Sets the number of performer threads that will process messages concurrently.
/// Multiple performers allow parallel message processing, improving throughput for I/O-bound operations.
Expand All @@ -120,9 +119,9 @@ public RedisSubscriptionBuilder SetNumberOfPerformers(int noOfPerformers)
_noOfPerformers = noOfPerformers;
return this;
}

private TimeSpan? _timeOut;

/// <summary>
/// Sets the timeout duration for message processing operations.
/// If a message handler takes longer than this timeout, the operation will be cancelled.
Expand All @@ -134,9 +133,9 @@ public RedisSubscriptionBuilder SetTimeout(TimeSpan? timeout)
_timeOut = timeout;
return this;
}

private int _requeueCount = -1;

/// <summary>
/// Sets the maximum number of times a failed message will be requeued for retry.
/// Messages that fail processing can be retried up to this limit before being moved to a dead letter queue or discarded.
Expand All @@ -148,9 +147,9 @@ public RedisSubscriptionBuilder SetRequeueCount(int requeueCount)
_requeueCount = requeueCount;
return this;
}

private TimeSpan? _requeueDelay;

/// <summary>
/// Sets the delay before a failed message is requeued for retry.
/// This provides a backoff period before attempting to process the message again, which can help with transient failures.
Expand All @@ -162,9 +161,9 @@ public RedisSubscriptionBuilder SetRequeueDelay(TimeSpan? requeueDelay)
_requeueDelay = requeueDelay;
return this;
}

private int _unacceptableMessageLimit;

/// <summary>
/// Sets the limit for the number of unacceptable messages that can be received before the channel stops processing.
/// Unacceptable messages are those that cannot be deserialized or are malformed. This limit prevents endless processing of bad messages.
Expand All @@ -176,9 +175,9 @@ public RedisSubscriptionBuilder SetUnacceptableMessageLimit(int unacceptableMess
_unacceptableMessageLimit = unacceptableMessageLimit;
return this;
}

private MessagePumpType _messagePumpType = MessagePumpType.Proactor;

/// <summary>
/// Sets the message pump type that determines how messages are processed.
/// Proactor uses async/await patterns for non-blocking I/O, while Reactor uses synchronous processing.
Expand All @@ -190,9 +189,9 @@ public RedisSubscriptionBuilder SetMessagePumpType(MessagePumpType messagePumpTy
_messagePumpType = messagePumpType;
return this;
}

private IAmAChannelFactory? _channelFactory;

/// <summary>
/// Sets a custom channel factory for creating message channels.
/// Use this when you need to provide custom channel creation logic beyond the default Redis channel factory.
Expand All @@ -204,9 +203,9 @@ public RedisSubscriptionBuilder SetChannelFactory(IAmAChannelFactory? channelFac
_channelFactory = channelFactory;
return this;
}

private OnMissingChannel _onMissingChannel = OnMissingChannel.Create;

/// <summary>
/// Sets the behavior for handling missing channels/topics in Redis.
/// Determines whether to create, validate, or assume the existence of channels when they are not found.
Expand All @@ -218,9 +217,9 @@ public RedisSubscriptionBuilder SetMakeChannels(OnMissingChannel onMissingChanne
_onMissingChannel = onMissingChannel;
return this;
}

private TimeSpan? _emptyChannelDelay;

/// <summary>
/// Sets the delay before checking for messages again when the channel is empty.
/// This prevents tight polling loops and reduces load on Redis when no messages are available.
Expand All @@ -232,9 +231,9 @@ public RedisSubscriptionBuilder SetEmptyChannelDelay(TimeSpan? emptyChannelDelay
_emptyChannelDelay = emptyChannelDelay;
return this;
}

private TimeSpan? _channelFailureDelay;

/// <summary>
/// Sets the delay before retrying channel operations after a failure.
/// This provides a backoff period when channel errors occur, preventing rapid retry loops that could overwhelm the system.
Expand All @@ -246,7 +245,7 @@ public RedisSubscriptionBuilder SetChannelFailureDelay(TimeSpan? channelFailureD
_channelFailureDelay = channelFailureDelay;
return this;
}

/// <summary>
/// Builds and returns a configured <see cref="RedisSubscription"/> instance.
/// This method is called internally to create the subscription with all the configured settings
Expand All @@ -260,18 +259,18 @@ internal RedisSubscription Build()
{
throw new ConfigurationException("Subscription name is required");
}

if (_channelName == null)
{
throw new ConfigurationException("Channel name is required");
}

if (_routingKey == null)
{
throw new ConfigurationException("Routing key is required");
}
return new TmpRedisSubscription(

return new RedisSubscription(
subscriptionName: _subscriptionName,
channelName: _channelName,
routingKey: _routingKey,
Expand All @@ -290,39 +289,4 @@ internal RedisSubscription Build()
channelFailureDelay: _channelFailureDelay
);
}

private class TmpRedisSubscription(
SubscriptionName subscriptionName,
ChannelName channelName,
RoutingKey routingKey,
Type? requestType = null,
Func<Message, Type>? getRequestType = null,
int bufferSize = 1,
int noOfPerformers = 1,
TimeSpan? timeOut = null,
int requeueCount = -1,
TimeSpan? requeueDelay = null,
int unacceptableMessageLimit = 0,
MessagePumpType messagePumpType = MessagePumpType.Proactor,
IAmAChannelFactory? channelFactory = null,
OnMissingChannel makeChannels = OnMissingChannel.Create,
TimeSpan? emptyChannelDelay = null,
TimeSpan? channelFailureDelay = null) : RedisSubscription(
subscriptionName,
channelName,
routingKey,
requestType,
getRequestType,
bufferSize,
noOfPerformers,
timeOut,
requeueCount,
requeueDelay,
unacceptableMessageLimit,
messagePumpType,
channelFactory,
makeChannels,
emptyChannelDelay,
channelFailureDelay
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ internal RocketSubscription Build()
_requeueCount,
_requeueDelay,
_unacceptableMessageLimit,
null,
_messagePumpType,
_channelFactory,
_makeChannels,
Expand Down
1 change: 1 addition & 0 deletions src/Fluent.Brighter/ConsumerBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Microsoft.Extensions.DependencyInjection;

using Paramore.Brighter;
using Paramore.Brighter.Extensions;
using Paramore.Brighter.FeatureSwitch;
using Paramore.Brighter.Observability;
using Paramore.Brighter.ServiceActivator.Extensions.DependencyInjection;
Expand Down
Loading