Moving to .NET 6, C# 10 and file-scoped namespaces
diff --git a/samples/Consuming/Consuming.csproj b/samples/Consuming/Consuming.csproj
index 6e05a4d..e2bb331 100644
--- a/samples/Consuming/Consuming.csproj
+++ b/samples/Consuming/Consuming.csproj
@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
- <TargetFramework>net5.0</TargetFramework>
+ <TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
diff --git a/samples/Consuming/Program.cs b/samples/Consuming/Program.cs
index d77b178..ed2bb74 100644
--- a/samples/Consuming/Program.cs
+++ b/samples/Consuming/Program.cs
@@ -12,70 +12,69 @@
* limitations under the License.
*/
-namespace Consuming
+namespace Consuming;
+
+using DotPulsar;
+using DotPulsar.Abstractions;
+using DotPulsar.Extensions;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+internal static class Program
{
- using DotPulsar;
- using DotPulsar.Abstractions;
- using DotPulsar.Extensions;
- using System;
- using System.Threading;
- using System.Threading.Tasks;
-
- internal static class Program
+ private static async Task Main()
{
- private static async Task Main()
+ const string myTopic = "persistent://public/default/mytopic";
+
+ var cts = new CancellationTokenSource();
+
+ Console.CancelKeyPress += (sender, args) =>
{
- const string myTopic = "persistent://public/default/mytopic";
+ cts.Cancel();
+ args.Cancel = true;
+ };
- var cts = new CancellationTokenSource();
+ await using var client = PulsarClient.Builder().Build(); //Connecting to pulsar://localhost:6650
- Console.CancelKeyPress += (sender, args) =>
- {
- cts.Cancel();
- args.Cancel = true;
- };
+ await using var consumer = client.NewConsumer(Schema.String)
+ .StateChangedHandler(Monitor)
+ .SubscriptionName("MySubscription")
+ .Topic(myTopic)
+ .Create();
- await using var client = PulsarClient.Builder().Build(); //Connecting to pulsar://localhost:6650
+ Console.WriteLine("Press Ctrl+C to exit");
- await using var consumer = client.NewConsumer(Schema.String)
- .StateChangedHandler(Monitor)
- .SubscriptionName("MySubscription")
- .Topic(myTopic)
- .Create();
+ await ConsumeMessages(consumer, cts.Token);
+ }
- Console.WriteLine("Press Ctrl+C to exit");
-
- await ConsumeMessages(consumer, cts.Token);
- }
-
- private static async Task ConsumeMessages(IConsumer<string> consumer, CancellationToken cancellationToken)
+ private static async Task ConsumeMessages(IConsumer<string> consumer, CancellationToken cancellationToken)
+ {
+ try
{
- try
+ await foreach (var message in consumer.Messages(cancellationToken))
{
- await foreach (var message in consumer.Messages(cancellationToken))
- {
- Console.WriteLine("Received: " + message.Value());
- await consumer.Acknowledge(message, cancellationToken);
- }
+ Console.WriteLine("Received: " + message.Value());
+ await consumer.Acknowledge(message, cancellationToken);
}
- catch (OperationCanceledException) { }
}
+ catch (OperationCanceledException) { }
+ }
- private static void Monitor(ConsumerStateChanged stateChanged, CancellationToken cancellationToken)
+ private static void Monitor(ConsumerStateChanged stateChanged, CancellationToken cancellationToken)
+ {
+ var stateMessage = stateChanged.ConsumerState switch
{
- var stateMessage = stateChanged.ConsumerState switch
- {
- ConsumerState.Active => "is active",
- ConsumerState.Inactive => "is inactive",
- ConsumerState.Disconnected => "is disconnected",
- ConsumerState.Closed => "has closed",
- ConsumerState.ReachedEndOfTopic => "has reached end of topic",
- ConsumerState.Faulted => "has faulted",
- _ => $"has an unknown state '{stateChanged.ConsumerState}'"
- };
+ ConsumerState.Active => "is active",
+ ConsumerState.Inactive => "is inactive",
+ ConsumerState.Disconnected => "is disconnected",
+ ConsumerState.Closed => "has closed",
+ ConsumerState.ReachedEndOfTopic => "has reached end of topic",
+ ConsumerState.Faulted => "has faulted",
+ _ => $"has an unknown state '{stateChanged.ConsumerState}'"
+ };
- var topic = stateChanged.Consumer.Topic;
- Console.WriteLine($"The consumer for topic '{topic}' " + stateMessage);
- }
+ var topic = stateChanged.Consumer.Topic;
+ Console.WriteLine($"The consumer for topic '{topic}' " + stateMessage);
}
}
diff --git a/samples/Producing/Producing.csproj b/samples/Producing/Producing.csproj
index 6e05a4d..e2bb331 100644
--- a/samples/Producing/Producing.csproj
+++ b/samples/Producing/Producing.csproj
@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
- <TargetFramework>net5.0</TargetFramework>
+ <TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
diff --git a/samples/Producing/Program.cs b/samples/Producing/Program.cs
index 42a706b..14749b7 100644
--- a/samples/Producing/Program.cs
+++ b/samples/Producing/Program.cs
@@ -12,73 +12,72 @@
* limitations under the License.
*/
-namespace Producing
+namespace Producing;
+
+using DotPulsar;
+using DotPulsar.Abstractions;
+using DotPulsar.Extensions;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+internal static class Program
{
- using DotPulsar;
- using DotPulsar.Abstractions;
- using DotPulsar.Extensions;
- using System;
- using System.Threading;
- using System.Threading.Tasks;
-
- internal static class Program
+ private static async Task Main()
{
- private static async Task Main()
+ const string myTopic = "persistent://public/default/mytopic";
+
+ var cts = new CancellationTokenSource();
+
+ Console.CancelKeyPress += (sender, args) =>
{
- const string myTopic = "persistent://public/default/mytopic";
+ cts.Cancel();
+ args.Cancel = true;
+ };
- var cts = new CancellationTokenSource();
+ await using var client = PulsarClient.Builder().Build(); //Connecting to pulsar://localhost:6650
- Console.CancelKeyPress += (sender, args) =>
- {
- cts.Cancel();
- args.Cancel = true;
- };
+ await using var producer = client.NewProducer(Schema.String)
+ .StateChangedHandler(Monitor)
+ .Topic(myTopic)
+ .Create();
- await using var client = PulsarClient.Builder().Build(); //Connecting to pulsar://localhost:6650
+ Console.WriteLine("Press Ctrl+C to exit");
- await using var producer = client.NewProducer(Schema.String)
- .StateChangedHandler(Monitor)
- .Topic(myTopic)
- .Create();
+ await ProduceMessages(producer, cts.Token);
+ }
- Console.WriteLine("Press Ctrl+C to exit");
+ private static async Task ProduceMessages(IProducer<string> producer, CancellationToken cancellationToken)
+ {
+ var delay = TimeSpan.FromSeconds(5);
- await ProduceMessages(producer, cts.Token);
- }
-
- private static async Task ProduceMessages(IProducer<string> producer, CancellationToken cancellationToken)
+ try
{
- var delay = TimeSpan.FromSeconds(5);
-
- try
+ while (!cancellationToken.IsCancellationRequested)
{
- while (!cancellationToken.IsCancellationRequested)
- {
- var data = DateTime.UtcNow.ToLongTimeString();
- _ = await producer.Send(data, cancellationToken);
- Console.WriteLine("Sent: " + data);
- await Task.Delay(delay, cancellationToken);
- }
+ var data = DateTime.UtcNow.ToLongTimeString();
+ _ = await producer.Send(data, cancellationToken);
+ Console.WriteLine("Sent: " + data);
+ await Task.Delay(delay, cancellationToken);
}
- catch (OperationCanceledException) // If not using the cancellationToken, then just dispose the producer and catch ObjectDisposedException instead
- { }
}
+ catch (OperationCanceledException) // If not using the cancellationToken, then just dispose the producer and catch ObjectDisposedException instead
+ { }
+ }
- private static void Monitor(ProducerStateChanged stateChanged, CancellationToken cancellationToken)
+ private static void Monitor(ProducerStateChanged stateChanged, CancellationToken cancellationToken)
+ {
+ var stateMessage = stateChanged.ProducerState switch
{
- var stateMessage = stateChanged.ProducerState switch
- {
- ProducerState.Connected => "is connected",
- ProducerState.Disconnected => "is disconnected",
- ProducerState.PartiallyConnected => "is partially connected",
- ProducerState.Closed => "has closed",
- ProducerState.Faulted => "has faulted",
- _ => $"has an unknown state '{stateChanged.ProducerState}'"
- };
+ ProducerState.Connected => "is connected",
+ ProducerState.Disconnected => "is disconnected",
+ ProducerState.PartiallyConnected => "is partially connected",
+ ProducerState.Closed => "has closed",
+ ProducerState.Faulted => "has faulted",
+ _ => $"has an unknown state '{stateChanged.ProducerState}'"
+ };
- var topic = stateChanged.Producer.Topic;
- Console.WriteLine($"The producer for topic '{topic}' " + stateMessage);
- }
+ var topic = stateChanged.Producer.Topic;
+ Console.WriteLine($"The producer for topic '{topic}' " + stateMessage);
}
}
diff --git a/samples/Reading/Program.cs b/samples/Reading/Program.cs
index 627b3e5..b76b1b8 100644
--- a/samples/Reading/Program.cs
+++ b/samples/Reading/Program.cs
@@ -12,68 +12,67 @@
* limitations under the License.
*/
-namespace Reading
+namespace Reading;
+
+using DotPulsar;
+using DotPulsar.Abstractions;
+using DotPulsar.Extensions;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+internal static class Program
{
- using DotPulsar;
- using DotPulsar.Abstractions;
- using DotPulsar.Extensions;
- using System;
- using System.Threading;
- using System.Threading.Tasks;
-
- internal static class Program
+ private static async Task Main()
{
- private static async Task Main()
+ const string myTopic = "persistent://public/default/mytopic";
+
+ var cts = new CancellationTokenSource();
+
+ Console.CancelKeyPress += (sender, args) =>
{
- const string myTopic = "persistent://public/default/mytopic";
+ cts.Cancel();
+ args.Cancel = true;
+ };
- var cts = new CancellationTokenSource();
+ await using var client = PulsarClient.Builder().Build(); //Connecting to pulsar://localhost:6650
- Console.CancelKeyPress += (sender, args) =>
- {
- cts.Cancel();
- args.Cancel = true;
- };
+ await using var reader = client.NewReader(Schema.String)
+ .StartMessageId(MessageId.Earliest)
+ .StateChangedHandler(Monitor)
+ .Topic(myTopic)
+ .Create();
- await using var client = PulsarClient.Builder().Build(); //Connecting to pulsar://localhost:6650
+ Console.WriteLine("Press Ctrl+C to exit");
- await using var reader = client.NewReader(Schema.String)
- .StartMessageId(MessageId.Earliest)
- .StateChangedHandler(Monitor)
- .Topic(myTopic)
- .Create();
+ await ReadMessages(reader, cts.Token);
+ }
- Console.WriteLine("Press Ctrl+C to exit");
-
- await ReadMessages(reader, cts.Token);
- }
-
- private static async Task ReadMessages(IReader<string> reader, CancellationToken cancellationToken)
+ private static async Task ReadMessages(IReader<string> reader, CancellationToken cancellationToken)
+ {
+ try
{
- try
+ await foreach (var message in reader.Messages(cancellationToken))
{
- await foreach (var message in reader.Messages(cancellationToken))
- {
- Console.WriteLine("Received: " + message.Value());
- }
+ Console.WriteLine("Received: " + message.Value());
}
- catch (OperationCanceledException) { }
}
+ catch (OperationCanceledException) { }
+ }
- private static void Monitor(ReaderStateChanged stateChanged, CancellationToken cancellationToken)
+ private static void Monitor(ReaderStateChanged stateChanged, CancellationToken cancellationToken)
+ {
+ var stateMessage = stateChanged.ReaderState switch
{
- var stateMessage = stateChanged.ReaderState switch
- {
- ReaderState.Connected => "is connected",
- ReaderState.Disconnected => "is disconnected",
- ReaderState.Closed => "has closed",
- ReaderState.ReachedEndOfTopic => "has reached end of topic",
- ReaderState.Faulted => "has faulted",
- _ => $"has an unknown state '{stateChanged.ReaderState}'"
- };
+ ReaderState.Connected => "is connected",
+ ReaderState.Disconnected => "is disconnected",
+ ReaderState.Closed => "has closed",
+ ReaderState.ReachedEndOfTopic => "has reached end of topic",
+ ReaderState.Faulted => "has faulted",
+ _ => $"has an unknown state '{stateChanged.ReaderState}'"
+ };
- var topic = stateChanged.Reader.Topic;
- Console.WriteLine($"The reader for topic '{topic}' " + stateMessage);
- }
+ var topic = stateChanged.Reader.Topic;
+ Console.WriteLine($"The reader for topic '{topic}' " + stateMessage);
}
}
diff --git a/samples/Reading/Reading.csproj b/samples/Reading/Reading.csproj
index 6e05a4d..e2bb331 100644
--- a/samples/Reading/Reading.csproj
+++ b/samples/Reading/Reading.csproj
@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
- <TargetFramework>net5.0</TargetFramework>
+ <TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 7254a3d..be011ab 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
- <LangVersion>9.0</LangVersion>
+ <LangVersion>10.0</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
diff --git a/src/DotPulsar/Abstractions/IConsumer.cs b/src/DotPulsar/Abstractions/IConsumer.cs
index 6996825..6628359 100644
--- a/src/DotPulsar/Abstractions/IConsumer.cs
+++ b/src/DotPulsar/Abstractions/IConsumer.cs
@@ -12,56 +12,55 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// A consumer abstraction.
+/// </summary>
+public interface IConsumer : IGetLastMessageId, ISeek, IState<ConsumerState>, IAsyncDisposable
{
- using System;
- using System.Collections.Generic;
- using System.Threading;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Acknowledge the consumption of a single message using the MessageId.
+ /// </summary>
+ ValueTask Acknowledge(MessageId messageId, CancellationToken cancellationToken = default);
/// <summary>
- /// A consumer abstraction.
+ /// Acknowledge the consumption of all the messages in the topic up to and including the provided MessageId.
/// </summary>
- public interface IConsumer : IGetLastMessageId, ISeek, IState<ConsumerState>, IAsyncDisposable
- {
- /// <summary>
- /// Acknowledge the consumption of a single message using the MessageId.
- /// </summary>
- ValueTask Acknowledge(MessageId messageId, CancellationToken cancellationToken = default);
+ ValueTask AcknowledgeCumulative(MessageId messageId, CancellationToken cancellationToken = default);
- /// <summary>
- /// Acknowledge the consumption of all the messages in the topic up to and including the provided MessageId.
- /// </summary>
- ValueTask AcknowledgeCumulative(MessageId messageId, CancellationToken cancellationToken = default);
+ /// <summary>
+ /// The consumer's service url.
+ /// </summary>
+ public Uri ServiceUrl { get; }
- /// <summary>
- /// The consumer's service url.
- /// </summary>
- public Uri ServiceUrl { get; }
+ /// <summary>
+ /// The consumer's subscription name.
+ /// </summary>
+ public string SubscriptionName { get; }
- /// <summary>
- /// The consumer's subscription name.
- /// </summary>
- public string SubscriptionName { get; }
+ /// <summary>
+ /// The consumer's topic.
+ /// </summary>
+ string Topic { get; }
- /// <summary>
- /// The consumer's topic.
- /// </summary>
- string Topic { get; }
+ /// <summary>
+ /// Unsubscribe the consumer.
+ /// </summary>
+ ValueTask Unsubscribe(CancellationToken cancellationToken = default);
- /// <summary>
- /// Unsubscribe the consumer.
- /// </summary>
- ValueTask Unsubscribe(CancellationToken cancellationToken = default);
+ /// <summary>
+ /// Redeliver the pending messages that were pushed to this consumer that are not yet acknowledged.
+ /// </summary>
+ ValueTask RedeliverUnacknowledgedMessages(IEnumerable<MessageId> messageIds, CancellationToken cancellationToken = default);
- /// <summary>
- /// Redeliver the pending messages that were pushed to this consumer that are not yet acknowledged.
- /// </summary>
- ValueTask RedeliverUnacknowledgedMessages(IEnumerable<MessageId> messageIds, CancellationToken cancellationToken = default);
-
- /// <summary>
- /// Redeliver all pending messages that were pushed to this consumer that are not yet acknowledged.
- /// </summary>
- ValueTask RedeliverUnacknowledgedMessages(CancellationToken cancellationToken = default);
- }
+ /// <summary>
+ /// Redeliver all pending messages that were pushed to this consumer that are not yet acknowledged.
+ /// </summary>
+ ValueTask RedeliverUnacknowledgedMessages(CancellationToken cancellationToken = default);
}
diff --git a/src/DotPulsar/Abstractions/IConsumerBuilder.cs b/src/DotPulsar/Abstractions/IConsumerBuilder.cs
index 8134eca..54d1fbd 100644
--- a/src/DotPulsar/Abstractions/IConsumerBuilder.cs
+++ b/src/DotPulsar/Abstractions/IConsumerBuilder.cs
@@ -12,61 +12,60 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+/// <summary>
+/// A consumer building abstraction.
+/// </summary>
+public interface IConsumerBuilder<TMessage>
{
/// <summary>
- /// A consumer building abstraction.
+ /// Set the consumer name. This is optional.
/// </summary>
- public interface IConsumerBuilder<TMessage>
- {
- /// <summary>
- /// Set the consumer name. This is optional.
- /// </summary>
- IConsumerBuilder<TMessage> ConsumerName(string name);
+ IConsumerBuilder<TMessage> ConsumerName(string name);
- /// <summary>
- /// Set initial position for the subscription. The default is 'Latest'.
- /// </summary>
- IConsumerBuilder<TMessage> InitialPosition(SubscriptionInitialPosition initialPosition);
+ /// <summary>
+ /// Set initial position for the subscription. The default is 'Latest'.
+ /// </summary>
+ IConsumerBuilder<TMessage> InitialPosition(SubscriptionInitialPosition initialPosition);
- /// <summary>
- /// Number of messages that will be prefetched. The default is 1000.
- /// </summary>
- IConsumerBuilder<TMessage> MessagePrefetchCount(uint count);
+ /// <summary>
+ /// Number of messages that will be prefetched. The default is 1000.
+ /// </summary>
+ IConsumerBuilder<TMessage> MessagePrefetchCount(uint count);
- /// <summary>
- /// Set the priority level for the shared subscription consumer. The default is 0.
- /// </summary>
- IConsumerBuilder<TMessage> PriorityLevel(int priorityLevel);
+ /// <summary>
+ /// Set the priority level for the shared subscription consumer. The default is 0.
+ /// </summary>
+ IConsumerBuilder<TMessage> PriorityLevel(int priorityLevel);
- /// <summary>
- /// Whether to read from the compacted topic. The default is 'false'.
- /// </summary>
- IConsumerBuilder<TMessage> ReadCompacted(bool readCompacted);
+ /// <summary>
+ /// Whether to read from the compacted topic. The default is 'false'.
+ /// </summary>
+ IConsumerBuilder<TMessage> ReadCompacted(bool readCompacted);
- /// <summary>
- /// Register a state changed handler.
- /// </summary>
- IConsumerBuilder<TMessage> StateChangedHandler(IHandleStateChanged<ConsumerStateChanged> handler);
+ /// <summary>
+ /// Register a state changed handler.
+ /// </summary>
+ IConsumerBuilder<TMessage> StateChangedHandler(IHandleStateChanged<ConsumerStateChanged> handler);
- /// <summary>
- /// Set the subscription name for this consumer. This is required.
- /// </summary>
- IConsumerBuilder<TMessage> SubscriptionName(string name);
+ /// <summary>
+ /// Set the subscription name for this consumer. This is required.
+ /// </summary>
+ IConsumerBuilder<TMessage> SubscriptionName(string name);
- /// <summary>
- /// Set the subscription type for this consumer. The default is 'Exclusive'.
- /// </summary>
- IConsumerBuilder<TMessage> SubscriptionType(SubscriptionType type);
+ /// <summary>
+ /// Set the subscription type for this consumer. The default is 'Exclusive'.
+ /// </summary>
+ IConsumerBuilder<TMessage> SubscriptionType(SubscriptionType type);
- /// <summary>
- /// Set the topic for this consumer. This is required.
- /// </summary>
- IConsumerBuilder<TMessage> Topic(string topic);
+ /// <summary>
+ /// Set the topic for this consumer. This is required.
+ /// </summary>
+ IConsumerBuilder<TMessage> Topic(string topic);
- /// <summary>
- /// Create the consumer.
- /// </summary>
- IConsumer<TMessage> Create();
- }
+ /// <summary>
+ /// Create the consumer.
+ /// </summary>
+ IConsumer<TMessage> Create();
}
diff --git a/src/DotPulsar/Abstractions/IConsumerOfT.cs b/src/DotPulsar/Abstractions/IConsumerOfT.cs
index 0affa98..613a154 100644
--- a/src/DotPulsar/Abstractions/IConsumerOfT.cs
+++ b/src/DotPulsar/Abstractions/IConsumerOfT.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
-{
- /// <summary>
- /// A generic consumer abstraction.
- /// </summary>
- public interface IConsumer<TMessage> : IConsumer, IReceive<IMessage<TMessage>> { }
-}
+namespace DotPulsar.Abstractions;
+
+/// <summary>
+/// A generic consumer abstraction.
+/// </summary>
+public interface IConsumer<TMessage> : IConsumer, IReceive<IMessage<TMessage>> { }
diff --git a/src/DotPulsar/Abstractions/IGetLastMessageId.cs b/src/DotPulsar/Abstractions/IGetLastMessageId.cs
index 0c3059a..5e68735 100644
--- a/src/DotPulsar/Abstractions/IGetLastMessageId.cs
+++ b/src/DotPulsar/Abstractions/IGetLastMessageId.cs
@@ -12,19 +12,18 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
-{
- using System.Threading;
- using System.Threading.Tasks;
+namespace DotPulsar.Abstractions;
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// An abstraction for getting the last message id.
+/// </summary>
+public interface IGetLastMessageId
+{
/// <summary>
- /// An abstraction for getting the last message id.
+ /// Get the MessageId of the last message on the topic.
/// </summary>
- public interface IGetLastMessageId
- {
- /// <summary>
- /// Get the MessageId of the last message on the topic.
- /// </summary>
- ValueTask<MessageId> GetLastMessageId(CancellationToken cancellationToken = default);
- }
+ ValueTask<MessageId> GetLastMessageId(CancellationToken cancellationToken = default);
}
diff --git a/src/DotPulsar/Abstractions/IHandleException.cs b/src/DotPulsar/Abstractions/IHandleException.cs
index f4acbcf..caa9941 100644
--- a/src/DotPulsar/Abstractions/IHandleException.cs
+++ b/src/DotPulsar/Abstractions/IHandleException.cs
@@ -12,18 +12,17 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
-{
- using System.Threading.Tasks;
+namespace DotPulsar.Abstractions;
+using System.Threading.Tasks;
+
+/// <summary>
+/// An exception handling abstraction.
+/// </summary>
+public interface IHandleException
+{
/// <summary>
- /// An exception handling abstraction.
+ /// Called after an action has thrown an Exception.
/// </summary>
- public interface IHandleException
- {
- /// <summary>
- /// Called after an action has thrown an Exception.
- /// </summary>
- ValueTask OnException(ExceptionContext exceptionContext);
- }
+ ValueTask OnException(ExceptionContext exceptionContext);
}
diff --git a/src/DotPulsar/Abstractions/IHandleStateChanged.cs b/src/DotPulsar/Abstractions/IHandleStateChanged.cs
index 8be3a99..0e016ab 100644
--- a/src/DotPulsar/Abstractions/IHandleStateChanged.cs
+++ b/src/DotPulsar/Abstractions/IHandleStateChanged.cs
@@ -12,24 +12,23 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// An state change handling abstraction.
+/// </summary>
+public interface IHandleStateChanged<TStateChanged>
{
- using System.Threading;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Called after a state has changed.
+ /// </summary>
+ ValueTask OnStateChanged(TStateChanged stateChanged, CancellationToken cancellationToken = default);
/// <summary>
- /// An state change handling abstraction.
+ /// The cancellation token to use when waiting for and handling state changes.
/// </summary>
- public interface IHandleStateChanged<TStateChanged>
- {
- /// <summary>
- /// Called after a state has changed.
- /// </summary>
- ValueTask OnStateChanged(TStateChanged stateChanged, CancellationToken cancellationToken = default);
-
- /// <summary>
- /// The cancellation token to use when waiting for and handling state changes.
- /// </summary>
- CancellationToken CancellationToken { get; }
- }
+ CancellationToken CancellationToken { get; }
}
diff --git a/src/DotPulsar/Abstractions/IMessage.cs b/src/DotPulsar/Abstractions/IMessage.cs
index c10204c..607e612 100644
--- a/src/DotPulsar/Abstractions/IMessage.cs
+++ b/src/DotPulsar/Abstractions/IMessage.cs
@@ -12,115 +12,114 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+using System;
+using System.Buffers;
+using System.Collections.Generic;
+
+/// <summary>
+/// A message abstraction.
+/// </summary>
+public interface IMessage
{
- using System;
- using System.Buffers;
- using System.Collections.Generic;
+ /// <summary>
+ /// The id of the message.
+ /// </summary>
+ MessageId MessageId { get; }
/// <summary>
- /// A message abstraction.
+ /// The raw payload of the message.
/// </summary>
- public interface IMessage
- {
- /// <summary>
- /// The id of the message.
- /// </summary>
- MessageId MessageId { get; }
+ ReadOnlySequence<byte> Data { get; }
- /// <summary>
- /// The raw payload of the message.
- /// </summary>
- ReadOnlySequence<byte> Data { get; }
+ /// <summary>
+ /// The name of the producer who produced the message.
+ /// </summary>
+ string ProducerName { get; }
- /// <summary>
- /// The name of the producer who produced the message.
- /// </summary>
- string ProducerName { get; }
+ /// <summary>
+ /// The schema version of the message.
+ /// </summary>
+ byte[]? SchemaVersion { get; }
- /// <summary>
- /// The schema version of the message.
- /// </summary>
- byte[]? SchemaVersion { get; }
+ /// <summary>
+ /// The sequence id of the message.
+ /// </summary>
+ ulong SequenceId { get; }
- /// <summary>
- /// The sequence id of the message.
- /// </summary>
- ulong SequenceId { get; }
+ /// <summary>
+ /// The redelivery count (maintained by the broker) of the message.
+ /// </summary>
+ uint RedeliveryCount { get; }
- /// <summary>
- /// The redelivery count (maintained by the broker) of the message.
- /// </summary>
- uint RedeliveryCount { get; }
+ /// <summary>
+ /// Check whether the message has an event time.
+ /// </summary>
+ bool HasEventTime { get; }
- /// <summary>
- /// Check whether the message has an event time.
- /// </summary>
- bool HasEventTime { get; }
+ /// <summary>
+ /// The event time of the message as unix time in milliseconds.
+ /// </summary>
+ ulong EventTime { get; }
- /// <summary>
- /// The event time of the message as unix time in milliseconds.
- /// </summary>
- ulong EventTime { get; }
+ /// <summary>
+ /// The event time of the message as an UTC DateTime.
+ /// </summary>
+ public DateTime EventTimeAsDateTime { get; }
- /// <summary>
- /// The event time of the message as an UTC DateTime.
- /// </summary>
- public DateTime EventTimeAsDateTime { get; }
+ /// <summary>
+ /// The event time of the message as a DateTimeOffset with an offset of 0.
+ /// </summary>
+ public DateTimeOffset EventTimeAsDateTimeOffset { get; }
- /// <summary>
- /// The event time of the message as a DateTimeOffset with an offset of 0.
- /// </summary>
- public DateTimeOffset EventTimeAsDateTimeOffset { get; }
+ /// <summary>
+ /// Check whether the key been base64 encoded.
+ /// </summary>
+ bool HasBase64EncodedKey { get; }
- /// <summary>
- /// Check whether the key been base64 encoded.
- /// </summary>
- bool HasBase64EncodedKey { get; }
+ /// <summary>
+ /// Check whether the message has a key.
+ /// </summary>
+ bool HasKey { get; }
- /// <summary>
- /// Check whether the message has a key.
- /// </summary>
- bool HasKey { get; }
+ /// <summary>
+ /// The key as a string.
+ /// </summary>
+ string? Key { get; }
- /// <summary>
- /// The key as a string.
- /// </summary>
- string? Key { get; }
+ /// <summary>
+ /// The key as bytes.
+ /// </summary>
+ byte[]? KeyBytes { get; }
- /// <summary>
- /// The key as bytes.
- /// </summary>
- byte[]? KeyBytes { get; }
+ /// <summary>
+ /// Check whether the message has an ordering key.
+ /// </summary>
+ bool HasOrderingKey { get; }
- /// <summary>
- /// Check whether the message has an ordering key.
- /// </summary>
- bool HasOrderingKey { get; }
+ /// <summary>
+ /// The ordering key of the message.
+ /// </summary>
+ byte[]? OrderingKey { get; }
- /// <summary>
- /// The ordering key of the message.
- /// </summary>
- byte[]? OrderingKey { get; }
+ /// <summary>
+ /// The publish time of the message as unix time in milliseconds.
+ /// </summary>
+ ulong PublishTime { get; }
- /// <summary>
- /// The publish time of the message as unix time in milliseconds.
- /// </summary>
- ulong PublishTime { get; }
+ /// <summary>
+ /// The publish time of the message as an UTC DateTime.
+ /// </summary>
+ public DateTime PublishTimeAsDateTime { get; }
- /// <summary>
- /// The publish time of the message as an UTC DateTime.
- /// </summary>
- public DateTime PublishTimeAsDateTime { get; }
+ /// <summary>
+ /// The publish time of the message as a DateTimeOffset with an offset of 0.
+ /// </summary>
+ public DateTimeOffset PublishTimeAsDateTimeOffset { get; }
- /// <summary>
- /// The publish time of the message as a DateTimeOffset with an offset of 0.
- /// </summary>
- public DateTimeOffset PublishTimeAsDateTimeOffset { get; }
-
- /// <summary>
- /// The properties of the message.
- /// </summary>
- public IReadOnlyDictionary<string, string> Properties { get; }
- }
+ /// <summary>
+ /// The properties of the message.
+ /// </summary>
+ public IReadOnlyDictionary<string, string> Properties { get; }
}
diff --git a/src/DotPulsar/Abstractions/IMessageBuilder.cs b/src/DotPulsar/Abstractions/IMessageBuilder.cs
index 32c9d94..d59e8be 100644
--- a/src/DotPulsar/Abstractions/IMessageBuilder.cs
+++ b/src/DotPulsar/Abstractions/IMessageBuilder.cs
@@ -12,81 +12,80 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// A message building abstraction.
+/// </summary>
+public interface IMessageBuilder<TMessage>
{
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Timestamp as unix time in milliseconds indicating when the message should be delivered to consumers.
+ /// </summary>
+ IMessageBuilder<TMessage> DeliverAt(long timestamp);
/// <summary>
- /// A message building abstraction.
+ /// Timestamp as UTC DateTime indicating when the message should be delivered to consumers.
/// </summary>
- public interface IMessageBuilder<TMessage>
- {
- /// <summary>
- /// Timestamp as unix time in milliseconds indicating when the message should be delivered to consumers.
- /// </summary>
- IMessageBuilder<TMessage> DeliverAt(long timestamp);
+ IMessageBuilder<TMessage> DeliverAt(DateTime timestamp);
- /// <summary>
- /// Timestamp as UTC DateTime indicating when the message should be delivered to consumers.
- /// </summary>
- IMessageBuilder<TMessage> DeliverAt(DateTime timestamp);
+ /// <summary>
+ /// Timestamp as DateTimeOffset indicating when the message should be delivered to consumers.
+ /// </summary>
+ IMessageBuilder<TMessage> DeliverAt(DateTimeOffset timestamp);
- /// <summary>
- /// Timestamp as DateTimeOffset indicating when the message should be delivered to consumers.
- /// </summary>
- IMessageBuilder<TMessage> DeliverAt(DateTimeOffset timestamp);
+ /// <summary>
+ /// The event time of the message as unix time in milliseconds.
+ /// </summary>
+ IMessageBuilder<TMessage> EventTime(ulong eventTime);
- /// <summary>
- /// The event time of the message as unix time in milliseconds.
- /// </summary>
- IMessageBuilder<TMessage> EventTime(ulong eventTime);
+ /// <summary>
+ /// The event time of the message as an UTC DateTime.
+ /// </summary>
+ IMessageBuilder<TMessage> EventTime(DateTime eventTime);
- /// <summary>
- /// The event time of the message as an UTC DateTime.
- /// </summary>
- IMessageBuilder<TMessage> EventTime(DateTime eventTime);
+ /// <summary>
+ /// The event time of the message as a DateTimeOffset.
+ /// </summary>
+ IMessageBuilder<TMessage> EventTime(DateTimeOffset eventTime);
- /// <summary>
- /// The event time of the message as a DateTimeOffset.
- /// </summary>
- IMessageBuilder<TMessage> EventTime(DateTimeOffset eventTime);
+ /// <summary>
+ /// Set the key of the message for routing policy.
+ /// </summary>
+ IMessageBuilder<TMessage> Key(string key);
- /// <summary>
- /// Set the key of the message for routing policy.
- /// </summary>
- IMessageBuilder<TMessage> Key(string key);
+ /// <summary>
+ /// Set the key of the message for routing policy.
+ /// </summary>
+ IMessageBuilder<TMessage> KeyBytes(byte[] key);
- /// <summary>
- /// Set the key of the message for routing policy.
- /// </summary>
- IMessageBuilder<TMessage> KeyBytes(byte[] key);
+ /// <summary>
+ /// Set the ordering key of the message for message dispatch in SubscriptionType.KeyShared mode.
+ /// The partition key will be used if the ordering key is not specified.
+ /// </summary>
+ IMessageBuilder<TMessage> OrderingKey(byte[] key);
- /// <summary>
- /// Set the ordering key of the message for message dispatch in SubscriptionType.KeyShared mode.
- /// The partition key will be used if the ordering key is not specified.
- /// </summary>
- IMessageBuilder<TMessage> OrderingKey(byte[] key);
+ /// <summary>
+ /// Add/Set a property key/value on the message.
+ /// </summary>
+ IMessageBuilder<TMessage> Property(string key, string value);
- /// <summary>
- /// Add/Set a property key/value on the message.
- /// </summary>
- IMessageBuilder<TMessage> Property(string key, string value);
+ /// <summary>
+ /// Set the schema version of the message.
+ /// </summary>
+ IMessageBuilder<TMessage> SchemaVersion(byte[] schemaVersion);
- /// <summary>
- /// Set the schema version of the message.
- /// </summary>
- IMessageBuilder<TMessage> SchemaVersion(byte[] schemaVersion);
+ /// <summary>
+ /// Set the sequence id of the message.
+ /// </summary>
+ IMessageBuilder<TMessage> SequenceId(ulong sequenceId);
- /// <summary>
- /// Set the sequence id of the message.
- /// </summary>
- IMessageBuilder<TMessage> SequenceId(ulong sequenceId);
-
- /// <summary>
- /// Sends a message.
- /// </summary>
- ValueTask<MessageId> Send(TMessage message, CancellationToken cancellationToken = default);
- }
+ /// <summary>
+ /// Sends a message.
+ /// </summary>
+ ValueTask<MessageId> Send(TMessage message, CancellationToken cancellationToken = default);
}
diff --git a/src/DotPulsar/Abstractions/IMessageOfT.cs b/src/DotPulsar/Abstractions/IMessageOfT.cs
index 792791f..8d4303e 100644
--- a/src/DotPulsar/Abstractions/IMessageOfT.cs
+++ b/src/DotPulsar/Abstractions/IMessageOfT.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+/// <summary>
+/// A generic message abstraction.
+/// </summary>
+public interface IMessage<TValue> : IMessage
{
/// <summary>
- /// A generic message abstraction.
+ /// The value of the message.
/// </summary>
- public interface IMessage<TValue> : IMessage
- {
- /// <summary>
- /// The value of the message.
- /// </summary>
- public TValue Value();
- }
+ public TValue Value();
}
diff --git a/src/DotPulsar/Abstractions/IMessageRouter.cs b/src/DotPulsar/Abstractions/IMessageRouter.cs
index d0d873c..d701c8b 100644
--- a/src/DotPulsar/Abstractions/IMessageRouter.cs
+++ b/src/DotPulsar/Abstractions/IMessageRouter.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+/// <summary>
+/// A message routing abstraction
+/// </summary>
+public interface IMessageRouter
{
/// <summary>
- /// A message routing abstraction
+ /// Choose a partition.
/// </summary>
- public interface IMessageRouter
- {
- /// <summary>
- /// Choose a partition.
- /// </summary>
- int ChoosePartition(MessageMetadata messageMetadata, int numberOfPartitions);
- }
+ int ChoosePartition(MessageMetadata messageMetadata, int numberOfPartitions);
}
diff --git a/src/DotPulsar/Abstractions/IProducer.cs b/src/DotPulsar/Abstractions/IProducer.cs
index ac13630..e492f06 100644
--- a/src/DotPulsar/Abstractions/IProducer.cs
+++ b/src/DotPulsar/Abstractions/IProducer.cs
@@ -12,23 +12,22 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+using System;
+
+/// <summary>
+/// A producer abstraction.
+/// </summary>
+public interface IProducer : IState<ProducerState>, IAsyncDisposable
{
- using System;
+ /// <summary>
+ /// The producer's service url.
+ /// </summary>
+ public Uri ServiceUrl { get; }
/// <summary>
- /// A producer abstraction.
+ /// The producer's topic.
/// </summary>
- public interface IProducer : IState<ProducerState>, IAsyncDisposable
- {
- /// <summary>
- /// The producer's service url.
- /// </summary>
- public Uri ServiceUrl { get; }
-
- /// <summary>
- /// The producer's topic.
- /// </summary>
- string Topic { get; }
- }
+ string Topic { get; }
}
diff --git a/src/DotPulsar/Abstractions/IProducerBuilder.cs b/src/DotPulsar/Abstractions/IProducerBuilder.cs
index 9650efa..6c27c80 100644
--- a/src/DotPulsar/Abstractions/IProducerBuilder.cs
+++ b/src/DotPulsar/Abstractions/IProducerBuilder.cs
@@ -12,46 +12,45 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+/// <summary>
+/// A producer building abstraction.
+/// </summary>
+public interface IProducerBuilder<TMessage>
{
/// <summary>
- /// A producer building abstraction.
+ /// Set the compression type. The default is 'None'.
/// </summary>
- public interface IProducerBuilder<TMessage>
- {
- /// <summary>
- /// Set the compression type. The default is 'None'.
- /// </summary>
- IProducerBuilder<TMessage> CompressionType(CompressionType compressionType);
+ IProducerBuilder<TMessage> CompressionType(CompressionType compressionType);
- /// <summary>
- /// Set the initial sequence id. The default is 0.
- /// </summary>
- IProducerBuilder<TMessage> InitialSequenceId(ulong initialSequenceId);
+ /// <summary>
+ /// Set the initial sequence id. The default is 0.
+ /// </summary>
+ IProducerBuilder<TMessage> InitialSequenceId(ulong initialSequenceId);
- /// <summary>
- /// Set the producer name. This is optional.
- /// </summary>
- IProducerBuilder<TMessage> ProducerName(string name);
+ /// <summary>
+ /// Set the producer name. This is optional.
+ /// </summary>
+ IProducerBuilder<TMessage> ProducerName(string name);
- /// <summary>
- /// Register a state changed handler.
- /// </summary>
- IProducerBuilder<TMessage> StateChangedHandler(IHandleStateChanged<ProducerStateChanged> handler);
+ /// <summary>
+ /// Register a state changed handler.
+ /// </summary>
+ IProducerBuilder<TMessage> StateChangedHandler(IHandleStateChanged<ProducerStateChanged> handler);
- /// <summary>
- /// Set the topic for this producer. This is required.
- /// </summary>
- IProducerBuilder<TMessage> Topic(string topic);
+ /// <summary>
+ /// Set the topic for this producer. This is required.
+ /// </summary>
+ IProducerBuilder<TMessage> Topic(string topic);
- /// <summary>
- /// Set the message router for this producer. The default is RoundRobinPartitionRouter.
- /// </summary>
- IProducerBuilder<TMessage> MessageRouter(IMessageRouter messageRouter);
+ /// <summary>
+ /// Set the message router for this producer. The default is RoundRobinPartitionRouter.
+ /// </summary>
+ IProducerBuilder<TMessage> MessageRouter(IMessageRouter messageRouter);
- /// <summary>
- /// Create the producer.
- /// </summary>
- IProducer<TMessage> Create();
- }
+ /// <summary>
+ /// Create the producer.
+ /// </summary>
+ IProducer<TMessage> Create();
}
diff --git a/src/DotPulsar/Abstractions/IProducerOfT.cs b/src/DotPulsar/Abstractions/IProducerOfT.cs
index da42458..811c066 100644
--- a/src/DotPulsar/Abstractions/IProducerOfT.cs
+++ b/src/DotPulsar/Abstractions/IProducerOfT.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
-{
- /// <summary>
- /// A generic producer abstraction.
- /// </summary>
- public interface IProducer<TMessage> : IProducer, ISend<TMessage> { }
-}
+namespace DotPulsar.Abstractions;
+
+/// <summary>
+/// A generic producer abstraction.
+/// </summary>
+public interface IProducer<TMessage> : IProducer, ISend<TMessage> { }
diff --git a/src/DotPulsar/Abstractions/IPulsarClient.cs b/src/DotPulsar/Abstractions/IPulsarClient.cs
index 64f6add..4a11f65 100644
--- a/src/DotPulsar/Abstractions/IPulsarClient.cs
+++ b/src/DotPulsar/Abstractions/IPulsarClient.cs
@@ -12,33 +12,32 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+using System;
+
+/// <summary>
+/// A pulsar client abstraction.
+/// </summary>
+public interface IPulsarClient : IAsyncDisposable
{
- using System;
+ /// <summary>
+ /// Create a producer.
+ /// </summary>
+ IProducer<TMessage> CreateProducer<TMessage>(ProducerOptions<TMessage> options);
/// <summary>
- /// A pulsar client abstraction.
+ /// Create a consumer.
/// </summary>
- public interface IPulsarClient : IAsyncDisposable
- {
- /// <summary>
- /// Create a producer.
- /// </summary>
- IProducer<TMessage> CreateProducer<TMessage>(ProducerOptions<TMessage> options);
+ IConsumer<TMessage> CreateConsumer<TMessage>(ConsumerOptions<TMessage> options);
- /// <summary>
- /// Create a consumer.
- /// </summary>
- IConsumer<TMessage> CreateConsumer<TMessage>(ConsumerOptions<TMessage> options);
+ /// <summary>
+ /// Create a reader.
+ /// </summary>
+ IReader<TMessage> CreateReader<TMessage>(ReaderOptions<TMessage> options);
- /// <summary>
- /// Create a reader.
- /// </summary>
- IReader<TMessage> CreateReader<TMessage>(ReaderOptions<TMessage> options);
-
- /// <summary>
- /// The client's service url.
- /// </summary>
- public Uri ServiceUrl { get; }
- }
+ /// <summary>
+ /// The client's service url.
+ /// </summary>
+ public Uri ServiceUrl { get; }
}
diff --git a/src/DotPulsar/Abstractions/IPulsarClientBuilder.cs b/src/DotPulsar/Abstractions/IPulsarClientBuilder.cs
index cc0db11..7ef079e 100644
--- a/src/DotPulsar/Abstractions/IPulsarClientBuilder.cs
+++ b/src/DotPulsar/Abstractions/IPulsarClientBuilder.cs
@@ -12,79 +12,78 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+using System;
+using System.Security.Cryptography.X509Certificates;
+
+/// <summary>
+/// A pulsar client building abstraction.
+/// </summary>
+public interface IPulsarClientBuilder
{
- using System;
- using System.Security.Cryptography.X509Certificates;
+ /// <summary>
+ /// Authenticate using a client certificate. This is optional.
+ /// </summary>
+ IPulsarClientBuilder AuthenticateUsingClientCertificate(X509Certificate2 clientCertificate);
/// <summary>
- /// A pulsar client building abstraction.
+ /// Authenticate using a (JSON Web) token. This is optional.
/// </summary>
- public interface IPulsarClientBuilder
- {
- /// <summary>
- /// Authenticate using a client certificate. This is optional.
- /// </summary>
- IPulsarClientBuilder AuthenticateUsingClientCertificate(X509Certificate2 clientCertificate);
+ IPulsarClientBuilder AuthenticateUsingToken(string token);
- /// <summary>
- /// Authenticate using a (JSON Web) token. This is optional.
- /// </summary>
- IPulsarClientBuilder AuthenticateUsingToken(string token);
+ /// <summary>
+ /// Set connection encryption policy. The default is 'EnforceUnencrypted' if the ServiceUrl scheme is 'pulsar' and 'EnforceEncrypted' if it's 'pulsar+ssl'.
+ /// </summary>
+ IPulsarClientBuilder ConnectionSecurity(EncryptionPolicy encryptionPolicy);
- /// <summary>
- /// Set connection encryption policy. The default is 'EnforceUnencrypted' if the ServiceUrl scheme is 'pulsar' and 'EnforceEncrypted' if it's 'pulsar+ssl'.
- /// </summary>
- IPulsarClientBuilder ConnectionSecurity(EncryptionPolicy encryptionPolicy);
+ /// <summary>
+ /// Register a custom exception handler that will be invoked before the default exception handler.
+ /// </summary>
+ IPulsarClientBuilder ExceptionHandler(IHandleException exceptionHandler);
- /// <summary>
- /// Register a custom exception handler that will be invoked before the default exception handler.
- /// </summary>
- IPulsarClientBuilder ExceptionHandler(IHandleException exceptionHandler);
+ /// <summary>
+ /// The time to wait before sending a 'ping' if there has been no activity on the connection. The default is 30 seconds.
+ /// </summary>
+ IPulsarClientBuilder KeepAliveInterval(TimeSpan interval);
- /// <summary>
- /// The time to wait before sending a 'ping' if there has been no activity on the connection. The default is 30 seconds.
- /// </summary>
- IPulsarClientBuilder KeepAliveInterval(TimeSpan interval);
+ /// <summary>
+ /// Set the listener name. This is optional.
+ /// </summary>
+ IPulsarClientBuilder ListenerName(string listenerName);
- /// <summary>
- /// Set the listener name. This is optional.
- /// </summary>
- IPulsarClientBuilder ListenerName(string listenerName);
+ /// <summary>
+ /// The time to wait before retrying an operation or a reconnect. The default is 3 seconds.
+ /// </summary>
+ IPulsarClientBuilder RetryInterval(TimeSpan interval);
- /// <summary>
- /// The time to wait before retrying an operation or a reconnect. The default is 3 seconds.
- /// </summary>
- IPulsarClientBuilder RetryInterval(TimeSpan interval);
+ /// <summary>
+ /// The service URL for the Pulsar cluster. The default is "pulsar://localhost:6650".
+ /// </summary>
+ IPulsarClientBuilder ServiceUrl(Uri uri);
- /// <summary>
- /// The service URL for the Pulsar cluster. The default is "pulsar://localhost:6650".
- /// </summary>
- IPulsarClientBuilder ServiceUrl(Uri uri);
+ /// <summary>
+ /// Add a trusted certificate authority. This is optional.
+ /// </summary>
+ IPulsarClientBuilder TrustedCertificateAuthority(X509Certificate2 trustedCertificateAuthority);
- /// <summary>
- /// Add a trusted certificate authority. This is optional.
- /// </summary>
- IPulsarClientBuilder TrustedCertificateAuthority(X509Certificate2 trustedCertificateAuthority);
+ /// <summary>
+ /// Verify the certificate authority. The default is 'true'.
+ /// </summary>
+ IPulsarClientBuilder VerifyCertificateAuthority(bool verifyCertificateAuthority);
- /// <summary>
- /// Verify the certificate authority. The default is 'true'.
- /// </summary>
- IPulsarClientBuilder VerifyCertificateAuthority(bool verifyCertificateAuthority);
+ /// <summary>
+ /// Verify the certificate name with the hostname. The default is 'false'.
+ /// </summary>
+ IPulsarClientBuilder VerifyCertificateName(bool verifyCertificateName);
- /// <summary>
- /// Verify the certificate name with the hostname. The default is 'false'.
- /// </summary>
- IPulsarClientBuilder VerifyCertificateName(bool verifyCertificateName);
+ /// <summary>
+ /// The time to wait before checking for inactive connections that can be closed. The default is 60 seconds.
+ /// </summary>
+ IPulsarClientBuilder CloseInactiveConnectionsInterval(TimeSpan interval);
- /// <summary>
- /// The time to wait before checking for inactive connections that can be closed. The default is 60 seconds.
- /// </summary>
- IPulsarClientBuilder CloseInactiveConnectionsInterval(TimeSpan interval);
-
- /// <summary>
- /// Create the client.
- /// </summary>
- IPulsarClient Build();
- }
+ /// <summary>
+ /// Create the client.
+ /// </summary>
+ IPulsarClient Build();
}
diff --git a/src/DotPulsar/Abstractions/IReader.cs b/src/DotPulsar/Abstractions/IReader.cs
index 3e438ac..a81bca7 100644
--- a/src/DotPulsar/Abstractions/IReader.cs
+++ b/src/DotPulsar/Abstractions/IReader.cs
@@ -12,23 +12,22 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+using System;
+
+/// <summary>
+/// A reader abstraction.
+/// </summary>
+public interface IReader : IGetLastMessageId, ISeek, IState<ReaderState>, IAsyncDisposable
{
- using System;
+ /// <summary>
+ /// The reader's service url.
+ /// </summary>
+ public Uri ServiceUrl { get; }
/// <summary>
- /// A reader abstraction.
+ /// The reader's topic.
/// </summary>
- public interface IReader : IGetLastMessageId, ISeek, IState<ReaderState>, IAsyncDisposable
- {
- /// <summary>
- /// The reader's service url.
- /// </summary>
- public Uri ServiceUrl { get; }
-
- /// <summary>
- /// The reader's topic.
- /// </summary>
- string Topic { get; }
- }
+ string Topic { get; }
}
diff --git a/src/DotPulsar/Abstractions/IReaderBuilder.cs b/src/DotPulsar/Abstractions/IReaderBuilder.cs
index 18235a6..184c4b0 100644
--- a/src/DotPulsar/Abstractions/IReaderBuilder.cs
+++ b/src/DotPulsar/Abstractions/IReaderBuilder.cs
@@ -12,46 +12,45 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+/// <summary>
+/// A reader building abstraction.
+/// </summary>
+public interface IReaderBuilder<TMessage>
{
/// <summary>
- /// A reader building abstraction.
+ /// Number of messages that will be prefetched. The default is 1000.
/// </summary>
- public interface IReaderBuilder<TMessage>
- {
- /// <summary>
- /// Number of messages that will be prefetched. The default is 1000.
- /// </summary>
- IReaderBuilder<TMessage> MessagePrefetchCount(uint count);
+ IReaderBuilder<TMessage> MessagePrefetchCount(uint count);
- /// <summary>
- /// Whether to read from the compacted topic. The default is 'false'.
- /// </summary>
- IReaderBuilder<TMessage> ReadCompacted(bool readCompacted);
+ /// <summary>
+ /// Whether to read from the compacted topic. The default is 'false'.
+ /// </summary>
+ IReaderBuilder<TMessage> ReadCompacted(bool readCompacted);
- /// <summary>
- /// Set the reader name. This is optional.
- /// </summary>
- IReaderBuilder<TMessage> ReaderName(string name);
+ /// <summary>
+ /// Set the reader name. This is optional.
+ /// </summary>
+ IReaderBuilder<TMessage> ReaderName(string name);
- /// <summary>
- /// The initial reader position is set to the specified message id. This is required.
- /// </summary>
- IReaderBuilder<TMessage> StartMessageId(MessageId messageId);
+ /// <summary>
+ /// The initial reader position is set to the specified message id. This is required.
+ /// </summary>
+ IReaderBuilder<TMessage> StartMessageId(MessageId messageId);
- /// <summary>
- /// Register a state changed handler.
- /// </summary>
- IReaderBuilder<TMessage> StateChangedHandler(IHandleStateChanged<ReaderStateChanged> handler);
+ /// <summary>
+ /// Register a state changed handler.
+ /// </summary>
+ IReaderBuilder<TMessage> StateChangedHandler(IHandleStateChanged<ReaderStateChanged> handler);
- /// <summary>
- /// Set the topic for this reader. This is required.
- /// </summary>
- IReaderBuilder<TMessage> Topic(string topic);
+ /// <summary>
+ /// Set the topic for this reader. This is required.
+ /// </summary>
+ IReaderBuilder<TMessage> Topic(string topic);
- /// <summary>
- /// Create the reader.
- /// </summary>
- IReader<TMessage> Create();
- }
+ /// <summary>
+ /// Create the reader.
+ /// </summary>
+ IReader<TMessage> Create();
}
diff --git a/src/DotPulsar/Abstractions/IReaderOfT.cs b/src/DotPulsar/Abstractions/IReaderOfT.cs
index 35f26c9..51c3236 100644
--- a/src/DotPulsar/Abstractions/IReaderOfT.cs
+++ b/src/DotPulsar/Abstractions/IReaderOfT.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
-{
- /// <summary>
- /// A generic reader abstraction.
- /// </summary>
- public interface IReader<TMessage> : IReader, IReceive<IMessage<TMessage>> { }
-}
+namespace DotPulsar.Abstractions;
+
+/// <summary>
+/// A generic reader abstraction.
+/// </summary>
+public interface IReader<TMessage> : IReader, IReceive<IMessage<TMessage>> { }
diff --git a/src/DotPulsar/Abstractions/IReceive.cs b/src/DotPulsar/Abstractions/IReceive.cs
index 994638a..9cac60d 100644
--- a/src/DotPulsar/Abstractions/IReceive.cs
+++ b/src/DotPulsar/Abstractions/IReceive.cs
@@ -12,19 +12,18 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
-{
- using System.Threading;
- using System.Threading.Tasks;
+namespace DotPulsar.Abstractions;
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// An abstraction for receiving a single message.
+/// </summary>
+public interface IReceive<TMessage>
+{
/// <summary>
- /// An abstraction for receiving a single message.
+ /// Receive a single message.
/// </summary>
- public interface IReceive<TMessage>
- {
- /// <summary>
- /// Receive a single message.
- /// </summary>
- ValueTask<TMessage> Receive(CancellationToken cancellationToken = default);
- }
+ ValueTask<TMessage> Receive(CancellationToken cancellationToken = default);
}
diff --git a/src/DotPulsar/Abstractions/ISchema.cs b/src/DotPulsar/Abstractions/ISchema.cs
index 698cad7..0fda8a4 100644
--- a/src/DotPulsar/Abstractions/ISchema.cs
+++ b/src/DotPulsar/Abstractions/ISchema.cs
@@ -12,28 +12,27 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+using System.Buffers;
+
+/// <summary>
+/// A schema abstraction.
+/// </summary>
+public interface ISchema<T>
{
- using System.Buffers;
+ /// <summary>
+ /// Decode the raw bytes.
+ /// </summary>
+ public T Decode(ReadOnlySequence<byte> bytes, byte[]? schemaVersion = null);
/// <summary>
- /// A schema abstraction.
+ /// Encode the message.
/// </summary>
- public interface ISchema<T>
- {
- /// <summary>
- /// Decode the raw bytes.
- /// </summary>
- public T Decode(ReadOnlySequence<byte> bytes, byte[]? schemaVersion = null);
+ public ReadOnlySequence<byte> Encode(T message);
- /// <summary>
- /// Encode the message.
- /// </summary>
- public ReadOnlySequence<byte> Encode(T message);
-
- /// <summary>
- /// The schema info.
- /// </summary>
- public SchemaInfo SchemaInfo { get; }
- }
+ /// <summary>
+ /// The schema info.
+ /// </summary>
+ public SchemaInfo SchemaInfo { get; }
}
diff --git a/src/DotPulsar/Abstractions/ISeek.cs b/src/DotPulsar/Abstractions/ISeek.cs
index 373c619..9079dc2 100644
--- a/src/DotPulsar/Abstractions/ISeek.cs
+++ b/src/DotPulsar/Abstractions/ISeek.cs
@@ -12,24 +12,23 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// An abstraction for seeking.
+/// </summary>
+public interface ISeek
{
- using System.Threading;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Reset the cursor associated with the consumer or reader to a specific MessageId.
+ /// </summary>
+ ValueTask Seek(MessageId messageId, CancellationToken cancellationToken = default);
/// <summary>
- /// An abstraction for seeking.
+ /// Reset the cursor associated with the consumer or reader to a specific message publish time using unix time in milliseconds.
/// </summary>
- public interface ISeek
- {
- /// <summary>
- /// Reset the cursor associated with the consumer or reader to a specific MessageId.
- /// </summary>
- ValueTask Seek(MessageId messageId, CancellationToken cancellationToken = default);
-
- /// <summary>
- /// Reset the cursor associated with the consumer or reader to a specific message publish time using unix time in milliseconds.
- /// </summary>
- ValueTask Seek(ulong publishTime, CancellationToken cancellationToken = default);
- }
+ ValueTask Seek(ulong publishTime, CancellationToken cancellationToken = default);
}
diff --git a/src/DotPulsar/Abstractions/ISend.cs b/src/DotPulsar/Abstractions/ISend.cs
index affe029..2f51c29 100644
--- a/src/DotPulsar/Abstractions/ISend.cs
+++ b/src/DotPulsar/Abstractions/ISend.cs
@@ -12,19 +12,18 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
-{
- using System.Threading;
- using System.Threading.Tasks;
+namespace DotPulsar.Abstractions;
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// An abstraction for sending a message.
+/// </summary>
+public interface ISend<TMessage>
+{
/// <summary>
- /// An abstraction for sending a message.
+ /// Sends a message with metadata.
/// </summary>
- public interface ISend<TMessage>
- {
- /// <summary>
- /// Sends a message with metadata.
- /// </summary>
- ValueTask<MessageId> Send(MessageMetadata metadata, TMessage message, CancellationToken cancellationToken = default);
- }
+ ValueTask<MessageId> Send(MessageMetadata metadata, TMessage message, CancellationToken cancellationToken = default);
}
diff --git a/src/DotPulsar/Abstractions/IState.cs b/src/DotPulsar/Abstractions/IState.cs
index 48a975e..615fe2d 100644
--- a/src/DotPulsar/Abstractions/IState.cs
+++ b/src/DotPulsar/Abstractions/IState.cs
@@ -12,52 +12,51 @@
* limitations under the License.
*/
-namespace DotPulsar.Abstractions
+namespace DotPulsar.Abstractions;
+
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// A state change monitoring abstraction.
+/// </summary>
+public interface IState<TState> where TState : notnull
{
- using System.Threading;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Ask whether the current state is final, meaning that it will never change.
+ /// </summary>
+ /// <returns>
+ /// True if it's final and False if it's not.
+ /// </returns>
+ bool IsFinalState();
/// <summary>
- /// A state change monitoring abstraction.
+ /// Ask whether the provided state is final, meaning that it will never change.
/// </summary>
- public interface IState<TState> where TState : notnull
- {
- /// <summary>
- /// Ask whether the current state is final, meaning that it will never change.
- /// </summary>
- /// <returns>
- /// True if it's final and False if it's not.
- /// </returns>
- bool IsFinalState();
+ /// <returns>
+ /// True if it's final and False if it's not.
+ /// </returns>
+ bool IsFinalState(TState state);
- /// <summary>
- /// Ask whether the provided state is final, meaning that it will never change.
- /// </summary>
- /// <returns>
- /// True if it's final and False if it's not.
- /// </returns>
- bool IsFinalState(TState state);
+ /// <summary>
+ /// Wait for the state to change to a specific state.
+ /// </summary>
+ /// <returns>
+ /// The current state.
+ /// </returns>
+ /// <remarks>
+ /// If the state change to a final state, then all awaiting tasks will complete.
+ /// </remarks>
+ ValueTask<TState> OnStateChangeTo(TState state, CancellationToken cancellationToken = default);
- /// <summary>
- /// Wait for the state to change to a specific state.
- /// </summary>
- /// <returns>
- /// The current state.
- /// </returns>
- /// <remarks>
- /// If the state change to a final state, then all awaiting tasks will complete.
- /// </remarks>
- ValueTask<TState> OnStateChangeTo(TState state, CancellationToken cancellationToken = default);
-
- /// <summary>
- /// Wait for the state to change from a specific state.
- /// </summary>
- /// <returns>
- /// The current state.
- /// </returns>
- /// <remarks>
- /// If the state change to a final state, then all awaiting tasks will complete.
- /// </remarks>
- ValueTask<TState> OnStateChangeFrom(TState state, CancellationToken cancellationToken = default);
- }
+ /// <summary>
+ /// Wait for the state to change from a specific state.
+ /// </summary>
+ /// <returns>
+ /// The current state.
+ /// </returns>
+ /// <remarks>
+ /// If the state change to a final state, then all awaiting tasks will complete.
+ /// </remarks>
+ ValueTask<TState> OnStateChangeFrom(TState state, CancellationToken cancellationToken = default);
}
diff --git a/src/DotPulsar/CompressionType.cs b/src/DotPulsar/CompressionType.cs
index 2e55628..a31a553 100644
--- a/src/DotPulsar/CompressionType.cs
+++ b/src/DotPulsar/CompressionType.cs
@@ -12,36 +12,35 @@
* limitations under the License.
*/
-namespace DotPulsar
+namespace DotPulsar;
+
+/// <summary>
+/// The compression types that can be set on a producer.
+/// </summary>
+public enum CompressionType : byte
{
/// <summary>
- /// The compression types that can be set on a producer.
+ /// No compression.
/// </summary>
- public enum CompressionType : byte
- {
- /// <summary>
- /// No compression.
- /// </summary>
- None = 0,
+ None = 0,
- /// <summary>
- /// Compress with LZ4.
- /// </summary>
- Lz4 = 1,
+ /// <summary>
+ /// Compress with LZ4.
+ /// </summary>
+ Lz4 = 1,
- /// <summary>
- /// Compress with zlib.
- /// </summary>
- Zlib = 2,
+ /// <summary>
+ /// Compress with zlib.
+ /// </summary>
+ Zlib = 2,
- /// <summary>
- /// Compress with zstd.
- /// </summary>
- Zstd = 3,
+ /// <summary>
+ /// Compress with zstd.
+ /// </summary>
+ Zstd = 3,
- /// <summary>
- /// Compress with Snappy.
- /// </summary>
- Snappy = 4
- }
+ /// <summary>
+ /// Compress with Snappy.
+ /// </summary>
+ Snappy = 4
}
diff --git a/src/DotPulsar/ConsumerOptions.cs b/src/DotPulsar/ConsumerOptions.cs
index 754f73a..4b30972 100644
--- a/src/DotPulsar/ConsumerOptions.cs
+++ b/src/DotPulsar/ConsumerOptions.cs
@@ -12,103 +12,102 @@
* limitations under the License.
*/
-namespace DotPulsar
+namespace DotPulsar;
+
+using DotPulsar.Abstractions;
+
+/// <summary>
+/// The consumer building options.
+/// </summary>
+public sealed class ConsumerOptions<TMessage>
{
- using DotPulsar.Abstractions;
+ /// <summary>
+ /// The default initial position.
+ /// </summary>
+ public static readonly SubscriptionInitialPosition DefaultInitialPosition = SubscriptionInitialPosition.Latest;
/// <summary>
- /// The consumer building options.
+ /// The default message prefetch count.
/// </summary>
- public sealed class ConsumerOptions<TMessage>
+ public static readonly uint DefaultMessagePrefetchCount = 1000;
+
+ /// <summary>
+ /// The default priority level.
+ /// </summary>
+ public static readonly int DefaultPriorityLevel = 0;
+
+ /// <summary>
+ /// The default of whether to read compacted.
+ /// </summary>
+ public static readonly bool DefaultReadCompacted = false;
+
+ /// <summary>
+ /// The default subscription type.
+ /// </summary>
+ public static readonly SubscriptionType DefaultSubscriptionType = SubscriptionType.Exclusive;
+
+ /// <summary>
+ /// Initializes a new instance using the specified subscription name and topic.
+ /// </summary>
+ public ConsumerOptions(string subscriptionName, string topic, ISchema<TMessage> schema)
{
- /// <summary>
- /// The default initial position.
- /// </summary>
- public static readonly SubscriptionInitialPosition DefaultInitialPosition = SubscriptionInitialPosition.Latest;
-
- /// <summary>
- /// The default message prefetch count.
- /// </summary>
- public static readonly uint DefaultMessagePrefetchCount = 1000;
-
- /// <summary>
- /// The default priority level.
- /// </summary>
- public static readonly int DefaultPriorityLevel = 0;
-
- /// <summary>
- /// The default of whether to read compacted.
- /// </summary>
- public static readonly bool DefaultReadCompacted = false;
-
- /// <summary>
- /// The default subscription type.
- /// </summary>
- public static readonly SubscriptionType DefaultSubscriptionType = SubscriptionType.Exclusive;
-
- /// <summary>
- /// Initializes a new instance using the specified subscription name and topic.
- /// </summary>
- public ConsumerOptions(string subscriptionName, string topic, ISchema<TMessage> schema)
- {
- InitialPosition = DefaultInitialPosition;
- PriorityLevel = DefaultPriorityLevel;
- MessagePrefetchCount = DefaultMessagePrefetchCount;
- ReadCompacted = DefaultReadCompacted;
- SubscriptionType = DefaultSubscriptionType;
- SubscriptionName = subscriptionName;
- Topic = topic;
- Schema = schema;
- }
-
- /// <summary>
- /// Set the consumer name. This is optional.
- /// </summary>
- public string? ConsumerName { get; set; }
-
- /// <summary>
- /// Set initial position for the subscription. The default is 'Latest'.
- /// </summary>
- public SubscriptionInitialPosition InitialPosition { get; set; }
-
- /// <summary>
- /// Number of messages that will be prefetched. The default is 1000.
- /// </summary>
- public uint MessagePrefetchCount { get; set; }
-
- /// <summary>
- /// Set the priority level for the shared subscription consumer. The default is 0.
- /// </summary>
- public int PriorityLevel { get; set; }
-
- /// <summary>
- /// Whether to read from the compacted topic. The default is 'false'.
- /// </summary>
- public bool ReadCompacted { get; set; }
-
- /// <summary>
- /// Set the schema. This is required.
- /// </summary>
- public ISchema<TMessage> Schema { get; set; }
-
- /// <summary>
- /// Register a state changed handler. This is optional.
- /// </summary>
- public IHandleStateChanged<ConsumerStateChanged>? StateChangedHandler { get; set; }
-
- /// <summary>
- /// Set the subscription name for this consumer. This is required.
- /// </summary>
- public string SubscriptionName { get; set; }
-
- /// <summary>
- /// Set the subscription type for this consumer. The default is 'Exclusive'.
- /// </summary>
- public SubscriptionType SubscriptionType { get; set; }
-
- /// <summary>
- /// Set the topic for this consumer. This is required.
- /// </summary>
- public string Topic { get; set; }
+ InitialPosition = DefaultInitialPosition;
+ PriorityLevel = DefaultPriorityLevel;
+ MessagePrefetchCount = DefaultMessagePrefetchCount;
+ ReadCompacted = DefaultReadCompacted;
+ SubscriptionType = DefaultSubscriptionType;
+ SubscriptionName = subscriptionName;
+ Topic = topic;
+ Schema = schema;
}
+
+ /// <summary>
+ /// Set the consumer name. This is optional.
+ /// </summary>
+ public string? ConsumerName { get; set; }
+
+ /// <summary>
+ /// Set initial position for the subscription. The default is 'Latest'.
+ /// </summary>
+ public SubscriptionInitialPosition InitialPosition { get; set; }
+
+ /// <summary>
+ /// Number of messages that will be prefetched. The default is 1000.
+ /// </summary>
+ public uint MessagePrefetchCount { get; set; }
+
+ /// <summary>
+ /// Set the priority level for the shared subscription consumer. The default is 0.
+ /// </summary>
+ public int PriorityLevel { get; set; }
+
+ /// <summary>
+ /// Whether to read from the compacted topic. The default is 'false'.
+ /// </summary>
+ public bool ReadCompacted { get; set; }
+
+ /// <summary>
+ /// Set the schema. This is required.
+ /// </summary>
+ public ISchema<TMessage> Schema { get; set; }
+
+ /// <summary>
+ /// Register a state changed handler. This is optional.
+ /// </summary>
+ public IHandleStateChanged<ConsumerStateChanged>? StateChangedHandler { get; set; }
+
+ /// <summary>
+ /// Set the subscription name for this consumer. This is required.
+ /// </summary>
+ public string SubscriptionName { get; set; }
+
+ /// <summary>
+ /// Set the subscription type for this consumer. The default is 'Exclusive'.
+ /// </summary>
+ public SubscriptionType SubscriptionType { get; set; }
+
+ /// <summary>
+ /// Set the topic for this consumer. This is required.
+ /// </summary>
+ public string Topic { get; set; }
}
diff --git a/src/DotPulsar/ConsumerState.cs b/src/DotPulsar/ConsumerState.cs
index 7c77164..d251e22 100644
--- a/src/DotPulsar/ConsumerState.cs
+++ b/src/DotPulsar/ConsumerState.cs
@@ -12,46 +12,45 @@
* limitations under the License.
*/
-namespace DotPulsar
+namespace DotPulsar;
+
+/// <summary>
+/// The possible states a consumer can be in.
+/// </summary>
+public enum ConsumerState : byte
{
/// <summary>
- /// The possible states a consumer can be in.
+ /// The consumer is connected and active. The subscription type is 'Failover' and this consumer is the active consumer.
/// </summary>
- public enum ConsumerState : byte
- {
- /// <summary>
- /// The consumer is connected and active. The subscription type is 'Failover' and this consumer is the active consumer.
- /// </summary>
- Active,
+ Active,
- /// <summary>
- /// The consumer is closed. This is a final state.
- /// </summary>
- Closed,
+ /// <summary>
+ /// The consumer is closed. This is a final state.
+ /// </summary>
+ Closed,
- /// <summary>
- /// The consumer is disconnected.
- /// </summary>
- Disconnected,
+ /// <summary>
+ /// The consumer is disconnected.
+ /// </summary>
+ Disconnected,
- /// <summary>
- /// The consumer is faulted. This is a final state.
- /// </summary>
- Faulted,
+ /// <summary>
+ /// The consumer is faulted. This is a final state.
+ /// </summary>
+ Faulted,
- /// <summary>
- /// The consumer is connected and inactive. The subscription type is 'Failover' and this consumer is not the active consumer.
- /// </summary>
- Inactive,
+ /// <summary>
+ /// The consumer is connected and inactive. The subscription type is 'Failover' and this consumer is not the active consumer.
+ /// </summary>
+ Inactive,
- /// <summary>
- /// The consumer has reached the end of the topic. This is a final state.
- /// </summary>
- ReachedEndOfTopic,
+ /// <summary>
+ /// The consumer has reached the end of the topic. This is a final state.
+ /// </summary>
+ ReachedEndOfTopic,
- /// <summary>
- /// The consumer has unsubscribed. This is a final state.
- /// </summary>
- Unsubscribed
- }
+ /// <summary>
+ /// The consumer has unsubscribed. This is a final state.
+ /// </summary>
+ Unsubscribed
}
diff --git a/src/DotPulsar/ConsumerStateChanged.cs b/src/DotPulsar/ConsumerStateChanged.cs
index 8c78145..24f61ee 100644
--- a/src/DotPulsar/ConsumerStateChanged.cs
+++ b/src/DotPulsar/ConsumerStateChanged.cs
@@ -12,29 +12,28 @@
* limitations under the License.
*/
-namespace DotPulsar
+namespace DotPulsar;
+
+using Abstractions;
+
+/// <summary>
+/// Representation of a consumer state change.
+/// </summary>
+public sealed class ConsumerStateChanged
{
- using Abstractions;
+ internal ConsumerStateChanged(IConsumer consumer, ConsumerState consumerState)
+ {
+ Consumer = consumer;
+ ConsumerState = consumerState;
+ }
/// <summary>
- /// Representation of a consumer state change.
+ /// The consumer that changed state.
/// </summary>
- public sealed class ConsumerStateChanged
- {
- internal ConsumerStateChanged(IConsumer consumer, ConsumerState consumerState)
- {
- Consumer = consumer;
- ConsumerState = consumerState;
- }
+ public IConsumer Consumer { get; }
- /// <summary>
- /// The consumer that changed state.
- /// </summary>
- public IConsumer Consumer { get; }
-
- /// <summary>
- /// The state that it changed to.
- /// </summary>
- public ConsumerState ConsumerState { get; }
- }
+ /// <summary>
+ /// The state that it changed to.
+ /// </summary>
+ public ConsumerState ConsumerState { get; }
}
diff --git a/src/DotPulsar/DotPulsar.csproj b/src/DotPulsar/DotPulsar.csproj
index 82be6fa..706c096 100644
--- a/src/DotPulsar/DotPulsar.csproj
+++ b/src/DotPulsar/DotPulsar.csproj
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <TargetFrameworks>netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0</TargetFrameworks>
+ <TargetFrameworks>netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0</TargetFrameworks>
<Version>1.1.2</Version>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
diff --git a/src/DotPulsar/EncryptionPolicy.cs b/src/DotPulsar/EncryptionPolicy.cs
index c4d153a..3cfb9dc 100644
--- a/src/DotPulsar/EncryptionPolicy.cs
+++ b/src/DotPulsar/EncryptionPolicy.cs
@@ -12,31 +12,30 @@
* limitations under the License.
*/
-namespace DotPulsar
+namespace DotPulsar;
+
+/// <summary>
+/// Encryption policies.
+/// </summary>
+public enum EncryptionPolicy : byte
{
/// <summary>
- /// Encryption policies.
+ /// Never encrypt the connection.
/// </summary>
- public enum EncryptionPolicy : byte
- {
- /// <summary>
- /// Never encrypt the connection.
- /// </summary>
- EnforceUnencrypted,
+ EnforceUnencrypted,
- /// <summary>
- /// Given the option of encrypting or not, prefer not to.
- /// </summary>
- PreferUnencrypted,
+ /// <summary>
+ /// Given the option of encrypting or not, prefer not to.
+ /// </summary>
+ PreferUnencrypted,
- /// <summary>
- /// Given the option of encrypting or not, prefer to do so.
- /// </summary>
- PreferEncrypted,
+ /// <summary>
+ /// Given the option of encrypting or not, prefer to do so.
+ /// </summary>
+ PreferEncrypted,
- /// <summary>
- /// Always encrypt the connection.
- /// </summary>
- EnforceEncrypted
- }
+ /// <summary>
+ /// Always encrypt the connection.
+ /// </summary>
+ EnforceEncrypted
}
diff --git a/src/DotPulsar/ExceptionContext.cs b/src/DotPulsar/ExceptionContext.cs
index 746b654..45b2cf5 100644
--- a/src/DotPulsar/ExceptionContext.cs
+++ b/src/DotPulsar/ExceptionContext.cs
@@ -12,39 +12,38 @@
* limitations under the License.
*/
-namespace DotPulsar
+namespace DotPulsar;
+
+using System;
+using System.Threading;
+
+public sealed class ExceptionContext
{
- using System;
- using System.Threading;
-
- public sealed class ExceptionContext
+ internal ExceptionContext(Exception exception, CancellationToken cancellationToken)
{
- internal ExceptionContext(Exception exception, CancellationToken cancellationToken)
- {
- Exception = exception;
- CancellationToken = cancellationToken;
- ExceptionHandled = false;
- Result = FaultAction.Rethrow;
- }
-
- /// <summary>
- /// The exception caught while executing the operation. This exception will be thrown if the fault action Result is set to 'ThrowException'.
- /// </summary>
- public Exception Exception { set; get; }
-
- /// <summary>
- /// The cancellation token given to the operation.
- /// </summary>
- public CancellationToken CancellationToken { get; }
-
- /// <summary>
- /// Gets or sets an indication that the exception has been handled. If 'true' no other exception handlers will be invoked.
- /// </summary>
- public bool ExceptionHandled { get; set; }
-
- /// <summary>
- /// Gets or sets the FaultAction.
- /// </summary>
- public FaultAction Result { get; set; }
+ Exception = exception;
+ CancellationToken = cancellationToken;
+ ExceptionHandled = false;
+ Result = FaultAction.Rethrow;
}
+
+ /// <summary>
+ /// The exception caught while executing the operation. This exception will be thrown if the fault action Result is set to 'ThrowException'.
+ /// </summary>
+ public Exception Exception { set; get; }
+
+ /// <summary>
+ /// The cancellation token given to the operation.
+ /// </summary>
+ public CancellationToken CancellationToken { get; }
+
+ /// <summary>
+ /// Gets or sets an indication that the exception has been handled. If 'true' no other exception handlers will be invoked.
+ /// </summary>
+ public bool ExceptionHandled { get; set; }
+
+ /// <summary>
+ /// Gets or sets the FaultAction.
+ /// </summary>
+ public FaultAction Result { get; set; }
}
diff --git a/src/DotPulsar/Exceptions/AuthenticationException.cs b/src/DotPulsar/Exceptions/AuthenticationException.cs
index b9634b2..ae60915 100644
--- a/src/DotPulsar/Exceptions/AuthenticationException.cs
+++ b/src/DotPulsar/Exceptions/AuthenticationException.cs
@@ -12,14 +12,13 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+using System;
+
+public sealed class AuthenticationException : DotPulsarException
{
- using System;
+ public AuthenticationException(string message) : base(message) { }
- public sealed class AuthenticationException : DotPulsarException
- {
- public AuthenticationException(string message) : base(message) { }
-
- public AuthenticationException(string message, Exception innerException) : base(message, innerException) { }
- }
+ public AuthenticationException(string message, Exception innerException) : base(message, innerException) { }
}
diff --git a/src/DotPulsar/Exceptions/AuthorizationException.cs b/src/DotPulsar/Exceptions/AuthorizationException.cs
index 5a9683e..211e4ee 100644
--- a/src/DotPulsar/Exceptions/AuthorizationException.cs
+++ b/src/DotPulsar/Exceptions/AuthorizationException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class AuthorizationException : DotPulsarException
{
- public sealed class AuthorizationException : DotPulsarException
- {
- public AuthorizationException(string message) : base(message) { }
- }
+ public AuthorizationException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/ChecksumException.cs b/src/DotPulsar/Exceptions/ChecksumException.cs
index 64171f0..5fd1690 100644
--- a/src/DotPulsar/Exceptions/ChecksumException.cs
+++ b/src/DotPulsar/Exceptions/ChecksumException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class ChecksumException : DotPulsarException
{
- public sealed class ChecksumException : DotPulsarException
- {
- public ChecksumException(string message) : base(message) { }
- }
+ public ChecksumException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/CompressionException.cs b/src/DotPulsar/Exceptions/CompressionException.cs
index be6d12a..359ee73 100644
--- a/src/DotPulsar/Exceptions/CompressionException.cs
+++ b/src/DotPulsar/Exceptions/CompressionException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class CompressionException : DotPulsarException
{
- public sealed class CompressionException : DotPulsarException
- {
- public CompressionException(string message) : base(message) { }
- }
+ public CompressionException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/ConfigurationException.cs b/src/DotPulsar/Exceptions/ConfigurationException.cs
index 5467426..6b90ddb 100644
--- a/src/DotPulsar/Exceptions/ConfigurationException.cs
+++ b/src/DotPulsar/Exceptions/ConfigurationException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class ConfigurationException : DotPulsarException
{
- public sealed class ConfigurationException : DotPulsarException
- {
- public ConfigurationException(string message) : base(message) { }
- }
+ public ConfigurationException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/ConnectionSecurityException.cs b/src/DotPulsar/Exceptions/ConnectionSecurityException.cs
index b7eb698..a8e5f59 100644
--- a/src/DotPulsar/Exceptions/ConnectionSecurityException.cs
+++ b/src/DotPulsar/Exceptions/ConnectionSecurityException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class ConnectionSecurityException : DotPulsarException
{
- public sealed class ConnectionSecurityException : DotPulsarException
- {
- public ConnectionSecurityException(string message) : base(message) { }
- }
+ public ConnectionSecurityException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/ConsumerAssignException.cs b/src/DotPulsar/Exceptions/ConsumerAssignException.cs
index dcbaba5..c8cf2fa 100644
--- a/src/DotPulsar/Exceptions/ConsumerAssignException.cs
+++ b/src/DotPulsar/Exceptions/ConsumerAssignException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class ConsumerAssignException : DotPulsarException
{
- public sealed class ConsumerAssignException : DotPulsarException
- {
- public ConsumerAssignException(string message) : base(message) { }
- }
+ public ConsumerAssignException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/ConsumerBusyException.cs b/src/DotPulsar/Exceptions/ConsumerBusyException.cs
index 3f6214e..9a858e7 100644
--- a/src/DotPulsar/Exceptions/ConsumerBusyException.cs
+++ b/src/DotPulsar/Exceptions/ConsumerBusyException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class ConsumerBusyException : DotPulsarException
{
- public sealed class ConsumerBusyException : DotPulsarException
- {
- public ConsumerBusyException(string message) : base(message) { }
- }
+ public ConsumerBusyException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/ConsumerClosedException.cs b/src/DotPulsar/Exceptions/ConsumerClosedException.cs
index fd61c0f..0cb8e2e 100644
--- a/src/DotPulsar/Exceptions/ConsumerClosedException.cs
+++ b/src/DotPulsar/Exceptions/ConsumerClosedException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class ConsumerClosedException : DotPulsarException
{
- public sealed class ConsumerClosedException : DotPulsarException
- {
- public ConsumerClosedException() : base("Consumer has closed") { }
- }
+ public ConsumerClosedException() : base("Consumer has closed") { }
}
diff --git a/src/DotPulsar/Exceptions/ConsumerDisposedException.cs b/src/DotPulsar/Exceptions/ConsumerDisposedException.cs
index 1ebdf11..1af7a18 100644
--- a/src/DotPulsar/Exceptions/ConsumerDisposedException.cs
+++ b/src/DotPulsar/Exceptions/ConsumerDisposedException.cs
@@ -12,12 +12,11 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
-{
- using System;
+namespace DotPulsar.Exceptions;
- public sealed class ConsumerDisposedException : ObjectDisposedException
- {
- public ConsumerDisposedException(string objectName) : base(objectName) { }
- }
+using System;
+
+public sealed class ConsumerDisposedException : ObjectDisposedException
+{
+ public ConsumerDisposedException(string objectName) : base(objectName) { }
}
diff --git a/src/DotPulsar/Exceptions/DotPulsarException.cs b/src/DotPulsar/Exceptions/DotPulsarException.cs
index 158f906..ef64f9d 100644
--- a/src/DotPulsar/Exceptions/DotPulsarException.cs
+++ b/src/DotPulsar/Exceptions/DotPulsarException.cs
@@ -12,14 +12,13 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+using System;
+
+public abstract class DotPulsarException : Exception
{
- using System;
+ public DotPulsarException(string message) : base(message) { }
- public abstract class DotPulsarException : Exception
- {
- public DotPulsarException(string message) : base(message) { }
-
- public DotPulsarException(string message, Exception innerException) : base(message, innerException) { }
- }
+ public DotPulsarException(string message, Exception innerException) : base(message, innerException) { }
}
diff --git a/src/DotPulsar/Exceptions/IncompatibleSchemaException.cs b/src/DotPulsar/Exceptions/IncompatibleSchemaException.cs
index 9271095..2ed83ae 100644
--- a/src/DotPulsar/Exceptions/IncompatibleSchemaException.cs
+++ b/src/DotPulsar/Exceptions/IncompatibleSchemaException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class IncompatibleSchemaException : DotPulsarException
{
- public sealed class IncompatibleSchemaException : DotPulsarException
- {
- public IncompatibleSchemaException(string message) : base(message) { }
- }
+ public IncompatibleSchemaException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/InvalidSchemeException.cs b/src/DotPulsar/Exceptions/InvalidSchemeException.cs
index 970ddaf..561acf0 100644
--- a/src/DotPulsar/Exceptions/InvalidSchemeException.cs
+++ b/src/DotPulsar/Exceptions/InvalidSchemeException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class InvalidSchemeException : DotPulsarException
{
- public sealed class InvalidSchemeException : DotPulsarException
- {
- public InvalidSchemeException(string message) : base(message) { }
- }
+ public InvalidSchemeException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/InvalidTopicNameException.cs b/src/DotPulsar/Exceptions/InvalidTopicNameException.cs
index 39b0df3..ff84f8b 100644
--- a/src/DotPulsar/Exceptions/InvalidTopicNameException.cs
+++ b/src/DotPulsar/Exceptions/InvalidTopicNameException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class InvalidTopicNameException : DotPulsarException
{
- public sealed class InvalidTopicNameException : DotPulsarException
- {
- public InvalidTopicNameException(string message) : base(message) { }
- }
+ public InvalidTopicNameException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/InvalidTransactionStatusException.cs b/src/DotPulsar/Exceptions/InvalidTransactionStatusException.cs
index e106f5e..caba91a 100644
--- a/src/DotPulsar/Exceptions/InvalidTransactionStatusException.cs
+++ b/src/DotPulsar/Exceptions/InvalidTransactionStatusException.cs
@@ -12,14 +12,13 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+using System;
+
+public sealed class InvalidTransactionStatusException : DotPulsarException
{
- using System;
+ public InvalidTransactionStatusException(string message) : base(message) { }
- public sealed class InvalidTransactionStatusException : DotPulsarException
- {
- public InvalidTransactionStatusException(string message) : base(message) { }
-
- public InvalidTransactionStatusException(string message, Exception innerException) : base(message, innerException) { }
- }
+ public InvalidTransactionStatusException(string message, Exception innerException) : base(message, innerException) { }
}
diff --git a/src/DotPulsar/Exceptions/MetadataException.cs b/src/DotPulsar/Exceptions/MetadataException.cs
index 2c3c54c..d8906cd 100644
--- a/src/DotPulsar/Exceptions/MetadataException.cs
+++ b/src/DotPulsar/Exceptions/MetadataException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class MetadataException : DotPulsarException
{
- public sealed class MetadataException : DotPulsarException
- {
- public MetadataException(string message) : base(message) { }
- }
+ public MetadataException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/NotAllowedException.cs b/src/DotPulsar/Exceptions/NotAllowedException.cs
index bce6316..8d76b87 100644
--- a/src/DotPulsar/Exceptions/NotAllowedException.cs
+++ b/src/DotPulsar/Exceptions/NotAllowedException.cs
@@ -12,14 +12,13 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+using System;
+
+public sealed class NotAllowedException : DotPulsarException
{
- using System;
+ public NotAllowedException(string message) : base(message) { }
- public sealed class NotAllowedException : DotPulsarException
- {
- public NotAllowedException(string message) : base(message) { }
-
- public NotAllowedException(string message, Exception innerException) : base(message, innerException) { }
- }
+ public NotAllowedException(string message, Exception innerException) : base(message, innerException) { }
}
diff --git a/src/DotPulsar/Exceptions/PersistenceException.cs b/src/DotPulsar/Exceptions/PersistenceException.cs
index bf9b57e..2058aa2 100644
--- a/src/DotPulsar/Exceptions/PersistenceException.cs
+++ b/src/DotPulsar/Exceptions/PersistenceException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class PersistenceException : DotPulsarException
{
- public sealed class PersistenceException : DotPulsarException
- {
- public PersistenceException(string message) : base(message) { }
- }
+ public PersistenceException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/ProducerBlockedQuotaExceededException.cs b/src/DotPulsar/Exceptions/ProducerBlockedQuotaExceededException.cs
index fed9ea3..d644a49 100644
--- a/src/DotPulsar/Exceptions/ProducerBlockedQuotaExceededException.cs
+++ b/src/DotPulsar/Exceptions/ProducerBlockedQuotaExceededException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class ProducerBlockedQuotaExceededException : DotPulsarException
{
- public sealed class ProducerBlockedQuotaExceededException : DotPulsarException
- {
- public ProducerBlockedQuotaExceededException(string message) : base(message) { }
- }
+ public ProducerBlockedQuotaExceededException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/ProducerBusyException.cs b/src/DotPulsar/Exceptions/ProducerBusyException.cs
index 094e615..5e573af 100644
--- a/src/DotPulsar/Exceptions/ProducerBusyException.cs
+++ b/src/DotPulsar/Exceptions/ProducerBusyException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class ProducerBusyException : DotPulsarException
{
- public sealed class ProducerBusyException : DotPulsarException
- {
- public ProducerBusyException(string message) : base(message) { }
- }
+ public ProducerBusyException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/ProducerClosedException.cs b/src/DotPulsar/Exceptions/ProducerClosedException.cs
index 2f388dc..0ad4ac9 100644
--- a/src/DotPulsar/Exceptions/ProducerClosedException.cs
+++ b/src/DotPulsar/Exceptions/ProducerClosedException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class ProducerClosedException : DotPulsarException
{
- public sealed class ProducerClosedException : DotPulsarException
- {
- public ProducerClosedException() : base("Producer has closed") { }
- }
+ public ProducerClosedException() : base("Producer has closed") { }
}
diff --git a/src/DotPulsar/Exceptions/ProducerDisposedException.cs b/src/DotPulsar/Exceptions/ProducerDisposedException.cs
index f07fb1b..7098cd7 100644
--- a/src/DotPulsar/Exceptions/ProducerDisposedException.cs
+++ b/src/DotPulsar/Exceptions/ProducerDisposedException.cs
@@ -12,12 +12,11 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
-{
- using System;
+namespace DotPulsar.Exceptions;
- public sealed class ProducerDisposedException : ObjectDisposedException
- {
- public ProducerDisposedException(string objectName) : base(objectName) { }
- }
+using System;
+
+public sealed class ProducerDisposedException : ObjectDisposedException
+{
+ public ProducerDisposedException(string objectName) : base(objectName) { }
}
diff --git a/src/DotPulsar/Exceptions/PulsarClientClosedException.cs b/src/DotPulsar/Exceptions/PulsarClientClosedException.cs
index 8a0c70b..4506037 100644
--- a/src/DotPulsar/Exceptions/PulsarClientClosedException.cs
+++ b/src/DotPulsar/Exceptions/PulsarClientClosedException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class PulsarClientClosedException : DotPulsarException
{
- public sealed class PulsarClientClosedException : DotPulsarException
- {
- public PulsarClientClosedException() : base("Client has closed") { }
- }
+ public PulsarClientClosedException() : base("Client has closed") { }
}
diff --git a/src/DotPulsar/Exceptions/PulsarClientDisposedException.cs b/src/DotPulsar/Exceptions/PulsarClientDisposedException.cs
index 3b3ceb6..d5dd996 100644
--- a/src/DotPulsar/Exceptions/PulsarClientDisposedException.cs
+++ b/src/DotPulsar/Exceptions/PulsarClientDisposedException.cs
@@ -12,12 +12,11 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
-{
- using System;
+namespace DotPulsar.Exceptions;
- public sealed class PulsarClientDisposedException : ObjectDisposedException
- {
- public PulsarClientDisposedException() : base(typeof(PulsarClient).FullName) { }
- }
+using System;
+
+public sealed class PulsarClientDisposedException : ObjectDisposedException
+{
+ public PulsarClientDisposedException() : base(typeof(PulsarClient).FullName) { }
}
diff --git a/src/DotPulsar/Exceptions/ReaderClosedException.cs b/src/DotPulsar/Exceptions/ReaderClosedException.cs
index 5ff801e..2022ad8 100644
--- a/src/DotPulsar/Exceptions/ReaderClosedException.cs
+++ b/src/DotPulsar/Exceptions/ReaderClosedException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class ReaderClosedException : DotPulsarException
{
- public sealed class ReaderClosedException : DotPulsarException
- {
- public ReaderClosedException() : base("Reader has closed") { }
- }
+ public ReaderClosedException() : base("Reader has closed") { }
}
diff --git a/src/DotPulsar/Exceptions/ReaderDisposedException.cs b/src/DotPulsar/Exceptions/ReaderDisposedException.cs
index 1ab4b80..3458df7 100644
--- a/src/DotPulsar/Exceptions/ReaderDisposedException.cs
+++ b/src/DotPulsar/Exceptions/ReaderDisposedException.cs
@@ -12,12 +12,11 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
-{
- using System;
+namespace DotPulsar.Exceptions;
- public sealed class ReaderDisposedException : ObjectDisposedException
- {
- public ReaderDisposedException(string objectName) : base(objectName) { }
- }
+using System;
+
+public sealed class ReaderDisposedException : ObjectDisposedException
+{
+ public ReaderDisposedException(string objectName) : base(objectName) { }
}
diff --git a/src/DotPulsar/Exceptions/SchemaSerializationException.cs b/src/DotPulsar/Exceptions/SchemaSerializationException.cs
index 900f8b1..fdb12a0 100644
--- a/src/DotPulsar/Exceptions/SchemaSerializationException.cs
+++ b/src/DotPulsar/Exceptions/SchemaSerializationException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class SchemaSerializationException : DotPulsarException
{
- public sealed class SchemaSerializationException : DotPulsarException
- {
- public SchemaSerializationException(string message) : base(message) { }
- }
+ public SchemaSerializationException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/SubscriptionNotFoundException.cs b/src/DotPulsar/Exceptions/SubscriptionNotFoundException.cs
index 37d2d1a..64a7415 100644
--- a/src/DotPulsar/Exceptions/SubscriptionNotFoundException.cs
+++ b/src/DotPulsar/Exceptions/SubscriptionNotFoundException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class SubscriptionNotFoundException : DotPulsarException
{
- public sealed class SubscriptionNotFoundException : DotPulsarException
- {
- public SubscriptionNotFoundException(string message) : base(message) { }
- }
+ public SubscriptionNotFoundException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/TopicNotFoundException.cs b/src/DotPulsar/Exceptions/TopicNotFoundException.cs
index 8cb4680..c2585c5 100644
--- a/src/DotPulsar/Exceptions/TopicNotFoundException.cs
+++ b/src/DotPulsar/Exceptions/TopicNotFoundException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class TopicNotFoundException : DotPulsarException
{
- public sealed class TopicNotFoundException : DotPulsarException
- {
- public TopicNotFoundException(string message) : base(message) { }
- }
+ public TopicNotFoundException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/TopicTerminatedException.cs b/src/DotPulsar/Exceptions/TopicTerminatedException.cs
index 0a97502..076f0d3 100644
--- a/src/DotPulsar/Exceptions/TopicTerminatedException.cs
+++ b/src/DotPulsar/Exceptions/TopicTerminatedException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class TopicTerminatedException : DotPulsarException
{
- public sealed class TopicTerminatedException : DotPulsarException
- {
- public TopicTerminatedException(string message) : base(message) { }
- }
+ public TopicTerminatedException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/TransactionConflictException.cs b/src/DotPulsar/Exceptions/TransactionConflictException.cs
index c358d39..1a83c10 100644
--- a/src/DotPulsar/Exceptions/TransactionConflictException.cs
+++ b/src/DotPulsar/Exceptions/TransactionConflictException.cs
@@ -12,14 +12,13 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+using System;
+
+public sealed class TransactionConflictException : DotPulsarException
{
- using System;
+ public TransactionConflictException(string message) : base(message) { }
- public sealed class TransactionConflictException : DotPulsarException
- {
- public TransactionConflictException(string message) : base(message) { }
-
- public TransactionConflictException(string message, Exception innerException) : base(message, innerException) { }
- }
+ public TransactionConflictException(string message, Exception innerException) : base(message, innerException) { }
}
diff --git a/src/DotPulsar/Exceptions/TransactionCoordinatorNotFoundException.cs b/src/DotPulsar/Exceptions/TransactionCoordinatorNotFoundException.cs
index 33d9158..c79117a 100644
--- a/src/DotPulsar/Exceptions/TransactionCoordinatorNotFoundException.cs
+++ b/src/DotPulsar/Exceptions/TransactionCoordinatorNotFoundException.cs
@@ -12,14 +12,13 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+using System;
+
+public sealed class TransactionCoordinatorNotFoundException : DotPulsarException
{
- using System;
+ public TransactionCoordinatorNotFoundException(string message) : base(message) { }
- public sealed class TransactionCoordinatorNotFoundException : DotPulsarException
- {
- public TransactionCoordinatorNotFoundException(string message) : base(message) { }
-
- public TransactionCoordinatorNotFoundException(string message, Exception innerException) : base(message, innerException) { }
- }
+ public TransactionCoordinatorNotFoundException(string message, Exception innerException) : base(message, innerException) { }
}
diff --git a/src/DotPulsar/Exceptions/UnknownException.cs b/src/DotPulsar/Exceptions/UnknownException.cs
index ff6cb35..af5d7b8 100644
--- a/src/DotPulsar/Exceptions/UnknownException.cs
+++ b/src/DotPulsar/Exceptions/UnknownException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class UnknownException : DotPulsarException
{
- public sealed class UnknownException : DotPulsarException
- {
- public UnknownException(string message) : base(message) { }
- }
+ public UnknownException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Exceptions/UnsupportedVersionException.cs b/src/DotPulsar/Exceptions/UnsupportedVersionException.cs
index fe9b5a5..28594a4 100644
--- a/src/DotPulsar/Exceptions/UnsupportedVersionException.cs
+++ b/src/DotPulsar/Exceptions/UnsupportedVersionException.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Exceptions
+namespace DotPulsar.Exceptions;
+
+public sealed class UnsupportedVersionException : DotPulsarException
{
- public sealed class UnsupportedVersionException : DotPulsarException
- {
- public UnsupportedVersionException(string message) : base(message) { }
- }
+ public UnsupportedVersionException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Extensions/ConsumerBuilderExtensions.cs b/src/DotPulsar/Extensions/ConsumerBuilderExtensions.cs
index 08fecd7..7ab0354 100644
--- a/src/DotPulsar/Extensions/ConsumerBuilderExtensions.cs
+++ b/src/DotPulsar/Extensions/ConsumerBuilderExtensions.cs
@@ -12,41 +12,40 @@
* limitations under the License.
*/
-namespace DotPulsar.Extensions
+namespace DotPulsar.Extensions;
+
+using DotPulsar.Abstractions;
+using DotPulsar.Internal;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// Extensions for IConsumerBuilder.
+/// </summary>
+public static class ConsumerBuilderExtensions
{
- using DotPulsar.Abstractions;
- using DotPulsar.Internal;
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Register a state changed handler.
+ /// </summary>
+ public static IConsumerBuilder<TMessage> StateChangedHandler<TMessage>(
+ this IConsumerBuilder<TMessage> builder,
+ Action<ConsumerStateChanged, CancellationToken> handler,
+ CancellationToken cancellationToken = default)
+ {
+ builder.StateChangedHandler(new ActionStateChangedHandler<ConsumerStateChanged>(handler, cancellationToken));
+ return builder;
+ }
/// <summary>
- /// Extensions for IConsumerBuilder.
+ /// Register a state changed handler.
/// </summary>
- public static class ConsumerBuilderExtensions
+ public static IConsumerBuilder<TMessage> StateChangedHandler<TMessage>(
+ this IConsumerBuilder<TMessage> builder,
+ Func<ConsumerStateChanged, CancellationToken, ValueTask> handler,
+ CancellationToken cancellationToken = default)
{
- /// <summary>
- /// Register a state changed handler.
- /// </summary>
- public static IConsumerBuilder<TMessage> StateChangedHandler<TMessage>(
- this IConsumerBuilder<TMessage> builder,
- Action<ConsumerStateChanged, CancellationToken> handler,
- CancellationToken cancellationToken = default)
- {
- builder.StateChangedHandler(new ActionStateChangedHandler<ConsumerStateChanged>(handler, cancellationToken));
- return builder;
- }
-
- /// <summary>
- /// Register a state changed handler.
- /// </summary>
- public static IConsumerBuilder<TMessage> StateChangedHandler<TMessage>(
- this IConsumerBuilder<TMessage> builder,
- Func<ConsumerStateChanged, CancellationToken, ValueTask> handler,
- CancellationToken cancellationToken = default)
- {
- builder.StateChangedHandler(new FuncStateChangedHandler<ConsumerStateChanged>(handler, cancellationToken));
- return builder;
- }
+ builder.StateChangedHandler(new FuncStateChangedHandler<ConsumerStateChanged>(handler, cancellationToken));
+ return builder;
}
}
diff --git a/src/DotPulsar/Extensions/ConsumerExtensions.cs b/src/DotPulsar/Extensions/ConsumerExtensions.cs
index 88f12cd..7d38591 100644
--- a/src/DotPulsar/Extensions/ConsumerExtensions.cs
+++ b/src/DotPulsar/Extensions/ConsumerExtensions.cs
@@ -12,111 +12,110 @@
* limitations under the License.
*/
-namespace DotPulsar.Extensions
+namespace DotPulsar.Extensions;
+
+using DotPulsar.Abstractions;
+using DotPulsar.Internal;
+using DotPulsar.Internal.Extensions;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// Extensions for IConsumer.
+/// </summary>
+public static class ConsumerExtensions
{
- using DotPulsar.Abstractions;
- using DotPulsar.Internal;
- using DotPulsar.Internal.Extensions;
- using System;
- using System.Collections.Generic;
- using System.Threading;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Acknowledge the consumption of a single message.
+ /// </summary>
+ public static async ValueTask Acknowledge(this IConsumer consumer, IMessage message, CancellationToken cancellationToken = default)
+ => await consumer.Acknowledge(message.MessageId, cancellationToken).ConfigureAwait(false);
/// <summary>
- /// Extensions for IConsumer.
+ /// Acknowledge the consumption of all the messages in the topic up to and including the provided message.
/// </summary>
- public static class ConsumerExtensions
+ public static async ValueTask AcknowledgeCumulative(this IConsumer consumer, IMessage message, CancellationToken cancellationToken = default)
+ => await consumer.AcknowledgeCumulative(message.MessageId, cancellationToken).ConfigureAwait(false);
+
+ /// <summary>
+ /// Process and auto-acknowledge a message.
+ /// </summary>
+ public static async ValueTask Process<TMessage>(
+ this IConsumer<TMessage> consumer,
+ Func<IMessage<TMessage>, CancellationToken, ValueTask> processor,
+ CancellationToken cancellationToken = default)
{
- /// <summary>
- /// Acknowledge the consumption of a single message.
- /// </summary>
- public static async ValueTask Acknowledge(this IConsumer consumer, IMessage message, CancellationToken cancellationToken = default)
- => await consumer.Acknowledge(message.MessageId, cancellationToken).ConfigureAwait(false);
+ const string operation = "process";
+ var operationName = $"{consumer.Topic} {operation}";
- /// <summary>
- /// Acknowledge the consumption of all the messages in the topic up to and including the provided message.
- /// </summary>
- public static async ValueTask AcknowledgeCumulative(this IConsumer consumer, IMessage message, CancellationToken cancellationToken = default)
- => await consumer.AcknowledgeCumulative(message.MessageId, cancellationToken).ConfigureAwait(false);
-
- /// <summary>
- /// Process and auto-acknowledge a message.
- /// </summary>
- public static async ValueTask Process<TMessage>(
- this IConsumer<TMessage> consumer,
- Func<IMessage<TMessage>, CancellationToken, ValueTask> processor,
- CancellationToken cancellationToken = default)
+ var tags = new KeyValuePair<string, object?>[]
{
- const string operation = "process";
- var operationName = $"{consumer.Topic} {operation}";
-
- var tags = new KeyValuePair<string, object?>[]
- {
new KeyValuePair<string, object?>("messaging.destination", consumer.Topic),
new KeyValuePair<string, object?>("messaging.destination_kind", "topic"),
new KeyValuePair<string, object?>("messaging.operation", operation),
new KeyValuePair<string, object?>("messaging.system", "pulsar"),
new KeyValuePair<string, object?>("messaging.url", consumer.ServiceUrl),
new KeyValuePair<string, object?>("messaging.pulsar.subscription", consumer.SubscriptionName)
- };
+ };
- while (!cancellationToken.IsCancellationRequested)
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ var message = await consumer.Receive(cancellationToken).ConfigureAwait(false);
+
+ var activity = DotPulsarActivitySource.StartConsumerActivity(message, operationName, tags);
+
+ if (activity is not null && activity.IsAllDataRequested)
{
- var message = await consumer.Receive(cancellationToken).ConfigureAwait(false);
-
- var activity = DotPulsarActivitySource.StartConsumerActivity(message, operationName, tags);
-
- if (activity is not null && activity.IsAllDataRequested)
- {
- activity.SetMessageId(message.MessageId);
- activity.SetPayloadSize(message.Data.Length);
- activity.SetStatusCode("OK");
- }
-
- try
- {
- await processor(message, cancellationToken).ConfigureAwait(false);
- }
- catch (Exception exception)
- {
- if (activity is not null && activity.IsAllDataRequested)
- activity.AddException(exception);
- }
-
- activity?.Dispose();
-
- await consumer.Acknowledge(message.MessageId, cancellationToken).ConfigureAwait(false);
+ activity.SetMessageId(message.MessageId);
+ activity.SetPayloadSize(message.Data.Length);
+ activity.SetStatusCode("OK");
}
- }
- /// <summary>
- /// Wait for the state to change to a specific state.
- /// </summary>
- /// <returns>
- /// The current state.
- /// </returns>
- /// <remarks>
- /// If the state change to a final state, then all awaiting tasks will complete.
- /// </remarks>
- public static async ValueTask<ConsumerStateChanged> StateChangedTo(this IConsumer consumer, ConsumerState state, CancellationToken cancellationToken = default)
- {
- var newState = await consumer.OnStateChangeTo(state, cancellationToken).ConfigureAwait(false);
- return new ConsumerStateChanged(consumer, newState);
- }
+ try
+ {
+ await processor(message, cancellationToken).ConfigureAwait(false);
+ }
+ catch (Exception exception)
+ {
+ if (activity is not null && activity.IsAllDataRequested)
+ activity.AddException(exception);
+ }
- /// <summary>
- /// Wait for the state to change from a specific state.
- /// </summary>
- /// <returns>
- /// The current state.
- /// </returns>
- /// <remarks>
- /// If the state change to a final state, then all awaiting tasks will complete.
- /// </remarks>
- public static async ValueTask<ConsumerStateChanged> StateChangedFrom(this IConsumer consumer, ConsumerState state, CancellationToken cancellationToken = default)
- {
- var newState = await consumer.OnStateChangeFrom(state, cancellationToken).ConfigureAwait(false);
- return new ConsumerStateChanged(consumer, newState);
+ activity?.Dispose();
+
+ await consumer.Acknowledge(message.MessageId, cancellationToken).ConfigureAwait(false);
}
}
+
+ /// <summary>
+ /// Wait for the state to change to a specific state.
+ /// </summary>
+ /// <returns>
+ /// The current state.
+ /// </returns>
+ /// <remarks>
+ /// If the state change to a final state, then all awaiting tasks will complete.
+ /// </remarks>
+ public static async ValueTask<ConsumerStateChanged> StateChangedTo(this IConsumer consumer, ConsumerState state, CancellationToken cancellationToken = default)
+ {
+ var newState = await consumer.OnStateChangeTo(state, cancellationToken).ConfigureAwait(false);
+ return new ConsumerStateChanged(consumer, newState);
+ }
+
+ /// <summary>
+ /// Wait for the state to change from a specific state.
+ /// </summary>
+ /// <returns>
+ /// The current state.
+ /// </returns>
+ /// <remarks>
+ /// If the state change to a final state, then all awaiting tasks will complete.
+ /// </remarks>
+ public static async ValueTask<ConsumerStateChanged> StateChangedFrom(this IConsumer consumer, ConsumerState state, CancellationToken cancellationToken = default)
+ {
+ var newState = await consumer.OnStateChangeFrom(state, cancellationToken).ConfigureAwait(false);
+ return new ConsumerStateChanged(consumer, newState);
+ }
}
diff --git a/src/DotPulsar/Extensions/MessageBuilderExtensions.cs b/src/DotPulsar/Extensions/MessageBuilderExtensions.cs
index aaf2da3..cf72a32 100644
--- a/src/DotPulsar/Extensions/MessageBuilderExtensions.cs
+++ b/src/DotPulsar/Extensions/MessageBuilderExtensions.cs
@@ -12,29 +12,28 @@
* limitations under the License.
*/
-namespace DotPulsar.Extensions
+namespace DotPulsar.Extensions;
+
+using DotPulsar.Abstractions;
+using System;
+using System.Buffers;
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// Extensions for IMessageBuilder.
+/// </summary>
+public static class MessageBuilderExtensions
{
- using DotPulsar.Abstractions;
- using System;
- using System.Buffers;
- using System.Threading;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Sends a message.
+ /// </summary>
+ public static async ValueTask<MessageId> Send(this IMessageBuilder<ReadOnlySequence<byte>> builder, byte[] payload, CancellationToken cancellationToken = default)
+ => await builder.Send(new ReadOnlySequence<byte>(payload), cancellationToken).ConfigureAwait(false);
/// <summary>
- /// Extensions for IMessageBuilder.
+ /// Sends a message.
/// </summary>
- public static class MessageBuilderExtensions
- {
- /// <summary>
- /// Sends a message.
- /// </summary>
- public static async ValueTask<MessageId> Send(this IMessageBuilder<ReadOnlySequence<byte>> builder, byte[] payload, CancellationToken cancellationToken = default)
- => await builder.Send(new ReadOnlySequence<byte>(payload), cancellationToken).ConfigureAwait(false);
-
- /// <summary>
- /// Sends a message.
- /// </summary>
- public static async ValueTask<MessageId> Send(this IMessageBuilder<ReadOnlySequence<byte>> builder, ReadOnlyMemory<byte> payload, CancellationToken cancellationToken = default)
- => await builder.Send(new ReadOnlySequence<byte>(payload), cancellationToken).ConfigureAwait(false);
- }
+ public static async ValueTask<MessageId> Send(this IMessageBuilder<ReadOnlySequence<byte>> builder, ReadOnlyMemory<byte> payload, CancellationToken cancellationToken = default)
+ => await builder.Send(new ReadOnlySequence<byte>(payload), cancellationToken).ConfigureAwait(false);
}
diff --git a/src/DotPulsar/Extensions/ProducerBuilderExtensions.cs b/src/DotPulsar/Extensions/ProducerBuilderExtensions.cs
index 2c11133..907e770 100644
--- a/src/DotPulsar/Extensions/ProducerBuilderExtensions.cs
+++ b/src/DotPulsar/Extensions/ProducerBuilderExtensions.cs
@@ -12,41 +12,40 @@
* limitations under the License.
*/
-namespace DotPulsar.Extensions
+namespace DotPulsar.Extensions;
+
+using DotPulsar.Abstractions;
+using DotPulsar.Internal;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// Extensions for IProducerBuilder.
+/// </summary>
+public static class ProducerBuilderExtensions
{
- using DotPulsar.Abstractions;
- using DotPulsar.Internal;
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Register a state changed handler.
+ /// </summary>
+ public static IProducerBuilder<TMessage> StateChangedHandler<TMessage>(
+ this IProducerBuilder<TMessage> builder,
+ Action<ProducerStateChanged, CancellationToken> handler,
+ CancellationToken cancellationToken = default)
+ {
+ builder.StateChangedHandler(new ActionStateChangedHandler<ProducerStateChanged>(handler, cancellationToken));
+ return builder;
+ }
/// <summary>
- /// Extensions for IProducerBuilder.
+ /// Register a state changed handler.
/// </summary>
- public static class ProducerBuilderExtensions
+ public static IProducerBuilder<TMessage> StateChangedHandler<TMessage>(
+ this IProducerBuilder<TMessage> builder,
+ Func<ProducerStateChanged, CancellationToken, ValueTask> handler,
+ CancellationToken cancellationToken = default)
{
- /// <summary>
- /// Register a state changed handler.
- /// </summary>
- public static IProducerBuilder<TMessage> StateChangedHandler<TMessage>(
- this IProducerBuilder<TMessage> builder,
- Action<ProducerStateChanged, CancellationToken> handler,
- CancellationToken cancellationToken = default)
- {
- builder.StateChangedHandler(new ActionStateChangedHandler<ProducerStateChanged>(handler, cancellationToken));
- return builder;
- }
-
- /// <summary>
- /// Register a state changed handler.
- /// </summary>
- public static IProducerBuilder<TMessage> StateChangedHandler<TMessage>(
- this IProducerBuilder<TMessage> builder,
- Func<ProducerStateChanged, CancellationToken, ValueTask> handler,
- CancellationToken cancellationToken = default)
- {
- builder.StateChangedHandler(new FuncStateChangedHandler<ProducerStateChanged>(handler, cancellationToken));
- return builder;
- }
+ builder.StateChangedHandler(new FuncStateChangedHandler<ProducerStateChanged>(handler, cancellationToken));
+ return builder;
}
}
diff --git a/src/DotPulsar/Extensions/ProducerExtensions.cs b/src/DotPulsar/Extensions/ProducerExtensions.cs
index 130941e..71ea70d 100644
--- a/src/DotPulsar/Extensions/ProducerExtensions.cs
+++ b/src/DotPulsar/Extensions/ProducerExtensions.cs
@@ -12,52 +12,51 @@
* limitations under the License.
*/
-namespace DotPulsar.Extensions
+namespace DotPulsar.Extensions;
+
+using Abstractions;
+using Internal;
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// Extensions for IProducer.
+/// </summary>
+public static class ProducerExtensions
{
- using Abstractions;
- using Internal;
- using System.Threading;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Get a builder that can be used to configure and build a Message.
+ /// </summary>
+ public static IMessageBuilder<TMessage> NewMessage<TMessage>(this IProducer<TMessage> producer)
+ => new MessageBuilder<TMessage>(producer);
/// <summary>
- /// Extensions for IProducer.
+ /// Wait for the state to change to a specific state.
/// </summary>
- public static class ProducerExtensions
+ /// <returns>
+ /// The current state.
+ /// </returns>
+ /// <remarks>
+ /// If the state change to a final state, then all awaiting tasks will complete.
+ /// </remarks>
+ public static async ValueTask<ProducerStateChanged> StateChangedTo(this IProducer producer, ProducerState state, CancellationToken cancellationToken = default)
{
- /// <summary>
- /// Get a builder that can be used to configure and build a Message.
- /// </summary>
- public static IMessageBuilder<TMessage> NewMessage<TMessage>(this IProducer<TMessage> producer)
- => new MessageBuilder<TMessage>(producer);
+ var newState = await producer.OnStateChangeTo(state, cancellationToken).ConfigureAwait(false);
+ return new ProducerStateChanged(producer, newState);
+ }
- /// <summary>
- /// Wait for the state to change to a specific state.
- /// </summary>
- /// <returns>
- /// The current state.
- /// </returns>
- /// <remarks>
- /// If the state change to a final state, then all awaiting tasks will complete.
- /// </remarks>
- public static async ValueTask<ProducerStateChanged> StateChangedTo(this IProducer producer, ProducerState state, CancellationToken cancellationToken = default)
- {
- var newState = await producer.OnStateChangeTo(state, cancellationToken).ConfigureAwait(false);
- return new ProducerStateChanged(producer, newState);
- }
-
- /// <summary>
- /// Wait for the state to change from a specific state.
- /// </summary>
- /// <returns>
- /// The current state.
- /// </returns>
- /// <remarks>
- /// If the state change to a final state, then all awaiting tasks will complete.
- /// </remarks>
- public static async ValueTask<ProducerStateChanged> StateChangedFrom(this IProducer producer, ProducerState state, CancellationToken cancellationToken = default)
- {
- var newState = await producer.OnStateChangeFrom(state, cancellationToken).ConfigureAwait(false);
- return new ProducerStateChanged(producer, newState);
- }
+ /// <summary>
+ /// Wait for the state to change from a specific state.
+ /// </summary>
+ /// <returns>
+ /// The current state.
+ /// </returns>
+ /// <remarks>
+ /// If the state change to a final state, then all awaiting tasks will complete.
+ /// </remarks>
+ public static async ValueTask<ProducerStateChanged> StateChangedFrom(this IProducer producer, ProducerState state, CancellationToken cancellationToken = default)
+ {
+ var newState = await producer.OnStateChangeFrom(state, cancellationToken).ConfigureAwait(false);
+ return new ProducerStateChanged(producer, newState);
}
}
diff --git a/src/DotPulsar/Extensions/PulsarClientBuilderExtensions.cs b/src/DotPulsar/Extensions/PulsarClientBuilderExtensions.cs
index 863872d..33bc5a9 100644
--- a/src/DotPulsar/Extensions/PulsarClientBuilderExtensions.cs
+++ b/src/DotPulsar/Extensions/PulsarClientBuilderExtensions.cs
@@ -12,34 +12,33 @@
* limitations under the License.
*/
-namespace DotPulsar.Extensions
+namespace DotPulsar.Extensions;
+
+using DotPulsar.Abstractions;
+using DotPulsar.Internal;
+using System;
+using System.Threading.Tasks;
+
+/// <summary>
+/// Extensions for IPulsarClientBuilder.
+/// </summary>
+public static class PulsarClientBuilderExtensions
{
- using DotPulsar.Abstractions;
- using DotPulsar.Internal;
- using System;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Register a custom exception handler that will be invoked before the default exception handler.
+ /// </summary>
+ public static IPulsarClientBuilder ExceptionHandler(this IPulsarClientBuilder builder, Action<ExceptionContext> exceptionHandler)
+ {
+ builder.ExceptionHandler(new ActionExceptionHandler(exceptionHandler));
+ return builder;
+ }
/// <summary>
- /// Extensions for IPulsarClientBuilder.
+ /// Register a custom exception handler that will be invoked before the default exception handler.
/// </summary>
- public static class PulsarClientBuilderExtensions
+ public static IPulsarClientBuilder ExceptionHandler(this IPulsarClientBuilder builder, Func<ExceptionContext, ValueTask> exceptionHandler)
{
- /// <summary>
- /// Register a custom exception handler that will be invoked before the default exception handler.
- /// </summary>
- public static IPulsarClientBuilder ExceptionHandler(this IPulsarClientBuilder builder, Action<ExceptionContext> exceptionHandler)
- {
- builder.ExceptionHandler(new ActionExceptionHandler(exceptionHandler));
- return builder;
- }
-
- /// <summary>
- /// Register a custom exception handler that will be invoked before the default exception handler.
- /// </summary>
- public static IPulsarClientBuilder ExceptionHandler(this IPulsarClientBuilder builder, Func<ExceptionContext, ValueTask> exceptionHandler)
- {
- builder.ExceptionHandler(new FuncExceptionHandler(exceptionHandler));
- return builder;
- }
+ builder.ExceptionHandler(new FuncExceptionHandler(exceptionHandler));
+ return builder;
}
}
diff --git a/src/DotPulsar/Extensions/PulsarClientExtensions.cs b/src/DotPulsar/Extensions/PulsarClientExtensions.cs
index 0f836a6..9750024 100644
--- a/src/DotPulsar/Extensions/PulsarClientExtensions.cs
+++ b/src/DotPulsar/Extensions/PulsarClientExtensions.cs
@@ -12,51 +12,50 @@
* limitations under the License.
*/
-namespace DotPulsar.Extensions
+namespace DotPulsar.Extensions;
+
+using Abstractions;
+using Internal;
+using System.Buffers;
+
+/// <summary>
+/// Extensions for IPulsarClient.
+/// </summary>
+public static class PulsarClientExtensions
{
- using Abstractions;
- using Internal;
- using System.Buffers;
+ /// <summary>
+ /// Get a builder that can be used to configure and build a Producer instance.
+ /// </summary>
+ public static IProducerBuilder<ReadOnlySequence<byte>> NewProducer(this IPulsarClient pulsarClient)
+ => new ProducerBuilder<ReadOnlySequence<byte>>(pulsarClient, Schema.ByteSequence);
/// <summary>
- /// Extensions for IPulsarClient.
+ /// Get a builder that can be used to configure and build a Consumer instance.
/// </summary>
- public static class PulsarClientExtensions
- {
- /// <summary>
- /// Get a builder that can be used to configure and build a Producer instance.
- /// </summary>
- public static IProducerBuilder<ReadOnlySequence<byte>> NewProducer(this IPulsarClient pulsarClient)
- => new ProducerBuilder<ReadOnlySequence<byte>>(pulsarClient, Schema.ByteSequence);
+ public static IConsumerBuilder<ReadOnlySequence<byte>> NewConsumer(this IPulsarClient pulsarClient)
+ => new ConsumerBuilder<ReadOnlySequence<byte>>(pulsarClient, Schema.ByteSequence);
- /// <summary>
- /// Get a builder that can be used to configure and build a Consumer instance.
- /// </summary>
- public static IConsumerBuilder<ReadOnlySequence<byte>> NewConsumer(this IPulsarClient pulsarClient)
- => new ConsumerBuilder<ReadOnlySequence<byte>>(pulsarClient, Schema.ByteSequence);
+ /// <summary>
+ /// Get a builder that can be used to configure and build a Reader instance.
+ /// </summary>
+ public static IReaderBuilder<ReadOnlySequence<byte>> NewReader(this IPulsarClient pulsarClient)
+ => new ReaderBuilder<ReadOnlySequence<byte>>(pulsarClient, Schema.ByteSequence);
- /// <summary>
- /// Get a builder that can be used to configure and build a Reader instance.
- /// </summary>
- public static IReaderBuilder<ReadOnlySequence<byte>> NewReader(this IPulsarClient pulsarClient)
- => new ReaderBuilder<ReadOnlySequence<byte>>(pulsarClient, Schema.ByteSequence);
+ /// <summary>
+ /// Get a builder that can be used to configure and build a Producer instance.
+ /// </summary>
+ public static IProducerBuilder<TMessage> NewProducer<TMessage>(this IPulsarClient pulsarClient, ISchema<TMessage> schema)
+ => new ProducerBuilder<TMessage>(pulsarClient, schema);
- /// <summary>
- /// Get a builder that can be used to configure and build a Producer instance.
- /// </summary>
- public static IProducerBuilder<TMessage> NewProducer<TMessage>(this IPulsarClient pulsarClient, ISchema<TMessage> schema)
- => new ProducerBuilder<TMessage>(pulsarClient, schema);
+ /// <summary>
+ /// Get a builder that can be used to configure and build a Consumer instance.
+ /// </summary>
+ public static IConsumerBuilder<TMessage> NewConsumer<TMessage>(this IPulsarClient pulsarClient, ISchema<TMessage> schema)
+ => new ConsumerBuilder<TMessage>(pulsarClient, schema);
- /// <summary>
- /// Get a builder that can be used to configure and build a Consumer instance.
- /// </summary>
- public static IConsumerBuilder<TMessage> NewConsumer<TMessage>(this IPulsarClient pulsarClient, ISchema<TMessage> schema)
- => new ConsumerBuilder<TMessage>(pulsarClient, schema);
-
- /// <summary>
- /// Get a builder that can be used to configure and build a Reader instance.
- /// </summary>
- public static IReaderBuilder<TMessage> NewReader<TMessage>(this IPulsarClient pulsarClient, ISchema<TMessage> schema)
- => new ReaderBuilder<TMessage>(pulsarClient, schema);
- }
+ /// <summary>
+ /// Get a builder that can be used to configure and build a Reader instance.
+ /// </summary>
+ public static IReaderBuilder<TMessage> NewReader<TMessage>(this IPulsarClient pulsarClient, ISchema<TMessage> schema)
+ => new ReaderBuilder<TMessage>(pulsarClient, schema);
}
diff --git a/src/DotPulsar/Extensions/ReaderBuilderExtensions.cs b/src/DotPulsar/Extensions/ReaderBuilderExtensions.cs
index 7f86286..32f7505 100644
--- a/src/DotPulsar/Extensions/ReaderBuilderExtensions.cs
+++ b/src/DotPulsar/Extensions/ReaderBuilderExtensions.cs
@@ -12,41 +12,40 @@
* limitations under the License.
*/
-namespace DotPulsar.Extensions
+namespace DotPulsar.Extensions;
+
+using DotPulsar.Abstractions;
+using DotPulsar.Internal;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// Extensions for IReaderBuilder.
+/// </summary>
+public static class ReaderBuilderExtensions
{
- using DotPulsar.Abstractions;
- using DotPulsar.Internal;
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Register a state changed handler.
+ /// </summary>
+ public static IReaderBuilder<TMessage> StateChangedHandler<TMessage>(
+ this IReaderBuilder<TMessage> builder,
+ Action<ReaderStateChanged, CancellationToken> handler,
+ CancellationToken cancellationToken = default)
+ {
+ builder.StateChangedHandler(new ActionStateChangedHandler<ReaderStateChanged>(handler, cancellationToken));
+ return builder;
+ }
/// <summary>
- /// Extensions for IReaderBuilder.
+ /// Register a state changed handler.
/// </summary>
- public static class ReaderBuilderExtensions
+ public static IReaderBuilder<TMessage> StateChangedHandler<TMessage>(
+ this IReaderBuilder<TMessage> builder,
+ Func<ReaderStateChanged, CancellationToken, ValueTask> handler,
+ CancellationToken cancellationToken = default)
{
- /// <summary>
- /// Register a state changed handler.
- /// </summary>
- public static IReaderBuilder<TMessage> StateChangedHandler<TMessage>(
- this IReaderBuilder<TMessage> builder,
- Action<ReaderStateChanged, CancellationToken> handler,
- CancellationToken cancellationToken = default)
- {
- builder.StateChangedHandler(new ActionStateChangedHandler<ReaderStateChanged>(handler, cancellationToken));
- return builder;
- }
-
- /// <summary>
- /// Register a state changed handler.
- /// </summary>
- public static IReaderBuilder<TMessage> StateChangedHandler<TMessage>(
- this IReaderBuilder<TMessage> builder,
- Func<ReaderStateChanged, CancellationToken, ValueTask> handler,
- CancellationToken cancellationToken = default)
- {
- builder.StateChangedHandler(new FuncStateChangedHandler<ReaderStateChanged>(handler, cancellationToken));
- return builder;
- }
+ builder.StateChangedHandler(new FuncStateChangedHandler<ReaderStateChanged>(handler, cancellationToken));
+ return builder;
}
}
diff --git a/src/DotPulsar/Extensions/ReaderExtensions.cs b/src/DotPulsar/Extensions/ReaderExtensions.cs
index 86d093b..661c5be 100644
--- a/src/DotPulsar/Extensions/ReaderExtensions.cs
+++ b/src/DotPulsar/Extensions/ReaderExtensions.cs
@@ -12,45 +12,44 @@
* limitations under the License.
*/
-namespace DotPulsar.Extensions
+namespace DotPulsar.Extensions;
+
+using DotPulsar.Abstractions;
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// Extensions for IReader.
+/// </summary>
+public static class ReaderExtensions
{
- using DotPulsar.Abstractions;
- using System.Threading;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Wait for the state to change to a specific state.
+ /// </summary>
+ /// <returns>
+ /// The current state.
+ /// </returns>
+ /// <remarks>
+ /// If the state change to a final state, then all awaiting tasks will complete.
+ /// </remarks>
+ public static async ValueTask<ReaderStateChanged> StateChangedTo(this IReader reader, ReaderState state, CancellationToken cancellationToken = default)
+ {
+ var newState = await reader.OnStateChangeTo(state, cancellationToken).ConfigureAwait(false);
+ return new ReaderStateChanged(reader, newState);
+ }
/// <summary>
- /// Extensions for IReader.
+ /// Wait for the state to change from a specific state.
/// </summary>
- public static class ReaderExtensions
+ /// <returns>
+ /// The current state.
+ /// </returns>
+ /// <remarks>
+ /// If the state change to a final state, then all awaiting tasks will complete.
+ /// </remarks>
+ public static async ValueTask<ReaderStateChanged> StateChangedFrom(this IReader reader, ReaderState state, CancellationToken cancellationToken = default)
{
- /// <summary>
- /// Wait for the state to change to a specific state.
- /// </summary>
- /// <returns>
- /// The current state.
- /// </returns>
- /// <remarks>
- /// If the state change to a final state, then all awaiting tasks will complete.
- /// </remarks>
- public static async ValueTask<ReaderStateChanged> StateChangedTo(this IReader reader, ReaderState state, CancellationToken cancellationToken = default)
- {
- var newState = await reader.OnStateChangeTo(state, cancellationToken).ConfigureAwait(false);
- return new ReaderStateChanged(reader, newState);
- }
-
- /// <summary>
- /// Wait for the state to change from a specific state.
- /// </summary>
- /// <returns>
- /// The current state.
- /// </returns>
- /// <remarks>
- /// If the state change to a final state, then all awaiting tasks will complete.
- /// </remarks>
- public static async ValueTask<ReaderStateChanged> StateChangedFrom(this IReader reader, ReaderState state, CancellationToken cancellationToken = default)
- {
- var newState = await reader.OnStateChangeFrom(state, cancellationToken).ConfigureAwait(false);
- return new ReaderStateChanged(reader, newState);
- }
+ var newState = await reader.OnStateChangeFrom(state, cancellationToken).ConfigureAwait(false);
+ return new ReaderStateChanged(reader, newState);
}
}
diff --git a/src/DotPulsar/Extensions/ReceiveExtensions.cs b/src/DotPulsar/Extensions/ReceiveExtensions.cs
index 5a165a6..bac5a22 100644
--- a/src/DotPulsar/Extensions/ReceiveExtensions.cs
+++ b/src/DotPulsar/Extensions/ReceiveExtensions.cs
@@ -12,25 +12,24 @@
* limitations under the License.
*/
-namespace DotPulsar.Extensions
-{
- using DotPulsar.Abstractions;
- using System.Collections.Generic;
- using System.Runtime.CompilerServices;
- using System.Threading;
+namespace DotPulsar.Extensions;
+using DotPulsar.Abstractions;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+using System.Threading;
+
+/// <summary>
+/// Extensions for IReceive.
+/// </summary>
+public static class ReceiveExtensions
+{
/// <summary>
- /// Extensions for IReceive.
+ /// Get an IAsyncEnumerable for receiving messages.
/// </summary>
- public static class ReceiveExtensions
+ public static async IAsyncEnumerable<TMessage> Messages<TMessage>(this IReceive<TMessage> receiver, [EnumeratorCancellation] CancellationToken cancellationToken = default)
{
- /// <summary>
- /// Get an IAsyncEnumerable for receiving messages.
- /// </summary>
- public static async IAsyncEnumerable<TMessage> Messages<TMessage>(this IReceive<TMessage> receiver, [EnumeratorCancellation] CancellationToken cancellationToken = default)
- {
- while (!cancellationToken.IsCancellationRequested)
- yield return await receiver.Receive(cancellationToken).ConfigureAwait(false);
- }
+ while (!cancellationToken.IsCancellationRequested)
+ yield return await receiver.Receive(cancellationToken).ConfigureAwait(false);
}
}
diff --git a/src/DotPulsar/Extensions/SeekExtensions.cs b/src/DotPulsar/Extensions/SeekExtensions.cs
index b4f0d2c..d2dfdec 100644
--- a/src/DotPulsar/Extensions/SeekExtensions.cs
+++ b/src/DotPulsar/Extensions/SeekExtensions.cs
@@ -12,28 +12,27 @@
* limitations under the License.
*/
-namespace DotPulsar.Extensions
+namespace DotPulsar.Extensions;
+
+using DotPulsar.Abstractions;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// Extensions for ISeek.
+/// </summary>
+public static class SeekExtensions
{
- using DotPulsar.Abstractions;
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Reset the cursor associated with the consumer or reader to a specific message publish time using an UTC DateTime.
+ /// </summary>
+ public static async ValueTask Seek(this ISeek seeker, DateTime publishTime, CancellationToken cancellationToken = default)
+ => await seeker.Seek((ulong) new DateTimeOffset(publishTime).ToUnixTimeMilliseconds(), cancellationToken).ConfigureAwait(false);
/// <summary>
- /// Extensions for ISeek.
+ /// Reset the cursor associated with the consumer or reader to a specific message publish time using a DateTimeOffset.
/// </summary>
- public static class SeekExtensions
- {
- /// <summary>
- /// Reset the cursor associated with the consumer or reader to a specific message publish time using an UTC DateTime.
- /// </summary>
- public static async ValueTask Seek(this ISeek seeker, DateTime publishTime, CancellationToken cancellationToken = default)
- => await seeker.Seek((ulong) new DateTimeOffset(publishTime).ToUnixTimeMilliseconds(), cancellationToken).ConfigureAwait(false);
-
- /// <summary>
- /// Reset the cursor associated with the consumer or reader to a specific message publish time using a DateTimeOffset.
- /// </summary>
- public static async ValueTask Seek(this ISeek seeker, DateTimeOffset publishTime, CancellationToken cancellationToken = default)
- => await seeker.Seek((ulong) publishTime.ToUnixTimeMilliseconds(), cancellationToken).ConfigureAwait(false);
- }
+ public static async ValueTask Seek(this ISeek seeker, DateTimeOffset publishTime, CancellationToken cancellationToken = default)
+ => await seeker.Seek((ulong) publishTime.ToUnixTimeMilliseconds(), cancellationToken).ConfigureAwait(false);
}
diff --git a/src/DotPulsar/Extensions/SendExtensions.cs b/src/DotPulsar/Extensions/SendExtensions.cs
index 479fe69..0c3a2bf 100644
--- a/src/DotPulsar/Extensions/SendExtensions.cs
+++ b/src/DotPulsar/Extensions/SendExtensions.cs
@@ -12,68 +12,67 @@
* limitations under the License.
*/
-namespace DotPulsar.Extensions
+namespace DotPulsar.Extensions;
+
+using Abstractions;
+using Microsoft.Extensions.ObjectPool;
+using System;
+using System.Buffers;
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// Extensions for ISend.
+/// </summary>
+public static class SendExtensions
{
- using Abstractions;
- using Microsoft.Extensions.ObjectPool;
- using System;
- using System.Buffers;
- using System.Threading;
- using System.Threading.Tasks;
+ private static readonly ObjectPool<MessageMetadata> _messageMetadataPool;
+
+ static SendExtensions()
+ {
+ var messageMetadataPolicy = new DefaultPooledObjectPolicy<MessageMetadata>();
+ _messageMetadataPool = new DefaultObjectPool<MessageMetadata>(messageMetadataPolicy);
+ }
/// <summary>
- /// Extensions for ISend.
+ /// Sends a message.
/// </summary>
- public static class SendExtensions
+ public static async ValueTask<MessageId> Send(this ISend<ReadOnlySequence<byte>> sender, byte[] data, CancellationToken cancellationToken = default)
+ => await Send(sender, new ReadOnlySequence<byte>(data), cancellationToken).ConfigureAwait(false);
+
+ /// <summary>
+ /// Sends a message.
+ /// </summary>
+ public static async ValueTask<MessageId> Send(this ISend<ReadOnlySequence<byte>> sender, ReadOnlyMemory<byte> data, CancellationToken cancellationToken = default)
+ => await Send(sender, new ReadOnlySequence<byte>(data), cancellationToken).ConfigureAwait(false);
+
+ /// <summary>
+ /// Sends a message with metadata.
+ /// </summary>
+ public static async ValueTask<MessageId> Send(this ISend<ReadOnlySequence<byte>> sender, MessageMetadata metadata, byte[] data, CancellationToken cancellationToken = default)
+ => await sender.Send(metadata, new ReadOnlySequence<byte>(data), cancellationToken).ConfigureAwait(false);
+
+ /// <summary>
+ /// Sends a message with metadata.
+ /// </summary>
+ public static async ValueTask<MessageId> Send(this ISend<ReadOnlySequence<byte>> sender, MessageMetadata metadata, ReadOnlyMemory<byte> data, CancellationToken cancellationToken = default)
+ => await sender.Send(metadata, new ReadOnlySequence<byte>(data), cancellationToken).ConfigureAwait(false);
+
+ /// <summary>
+ /// Sends a message without metadata.
+ /// </summary>
+ public static async ValueTask<MessageId> Send<TMessage>(this ISend<TMessage> sender, TMessage message, CancellationToken cancellationToken = default)
{
- private static readonly ObjectPool<MessageMetadata> _messageMetadataPool;
+ var metadata = _messageMetadataPool.Get();
- static SendExtensions()
+ try
{
- var messageMetadataPolicy = new DefaultPooledObjectPolicy<MessageMetadata>();
- _messageMetadataPool = new DefaultObjectPool<MessageMetadata>(messageMetadataPolicy);
+ return await sender.Send(metadata, message, cancellationToken).ConfigureAwait(false);
}
-
- /// <summary>
- /// Sends a message.
- /// </summary>
- public static async ValueTask<MessageId> Send(this ISend<ReadOnlySequence<byte>> sender, byte[] data, CancellationToken cancellationToken = default)
- => await Send(sender, new ReadOnlySequence<byte>(data), cancellationToken).ConfigureAwait(false);
-
- /// <summary>
- /// Sends a message.
- /// </summary>
- public static async ValueTask<MessageId> Send(this ISend<ReadOnlySequence<byte>> sender, ReadOnlyMemory<byte> data, CancellationToken cancellationToken = default)
- => await Send(sender, new ReadOnlySequence<byte>(data), cancellationToken).ConfigureAwait(false);
-
- /// <summary>
- /// Sends a message with metadata.
- /// </summary>
- public static async ValueTask<MessageId> Send(this ISend<ReadOnlySequence<byte>> sender, MessageMetadata metadata, byte[] data, CancellationToken cancellationToken = default)
- => await sender.Send(metadata, new ReadOnlySequence<byte>(data), cancellationToken).ConfigureAwait(false);
-
- /// <summary>
- /// Sends a message with metadata.
- /// </summary>
- public static async ValueTask<MessageId> Send(this ISend<ReadOnlySequence<byte>> sender, MessageMetadata metadata, ReadOnlyMemory<byte> data, CancellationToken cancellationToken = default)
- => await sender.Send(metadata, new ReadOnlySequence<byte>(data), cancellationToken).ConfigureAwait(false);
-
- /// <summary>
- /// Sends a message without metadata.
- /// </summary>
- public static async ValueTask<MessageId> Send<TMessage>(this ISend<TMessage> sender, TMessage message, CancellationToken cancellationToken = default)
+ finally
{
- var metadata = _messageMetadataPool.Get();
-
- try
- {
- return await sender.Send(metadata, message, cancellationToken).ConfigureAwait(false);
- }
- finally
- {
- metadata.Metadata.Properties.Clear();
- _messageMetadataPool.Return(metadata);
- }
+ metadata.Metadata.Properties.Clear();
+ _messageMetadataPool.Return(metadata);
}
}
}
diff --git a/src/DotPulsar/FaultAction.cs b/src/DotPulsar/FaultAction.cs
index c6475a8..fc58e5f 100644
--- a/src/DotPulsar/FaultAction.cs
+++ b/src/DotPulsar/FaultAction.cs
@@ -12,26 +12,25 @@
* limitations under the License.
*/
-namespace DotPulsar
+namespace DotPulsar;
+
+/// <summary>
+/// Actions to take when an exception has been caught while executing an operation.
+/// </summary>
+public enum FaultAction : byte
{
/// <summary>
- /// Actions to take when an exception has been caught while executing an operation.
+ /// Rethrow the exception.
/// </summary>
- public enum FaultAction : byte
- {
- /// <summary>
- /// Rethrow the exception.
- /// </summary>
- Rethrow,
+ Rethrow,
- /// <summary>
- /// Throw the exception from the ExceptionContext.
- /// </summary>
- ThrowException,
+ /// <summary>
+ /// Throw the exception from the ExceptionContext.
+ /// </summary>
+ ThrowException,
- /// <summary>
- /// Retry the operation.
- /// </summary>
- Retry
- }
+ /// <summary>
+ /// Retry the operation.
+ /// </summary>
+ Retry
}
diff --git a/src/DotPulsar/Internal/Abstractions/IChannel.cs b/src/DotPulsar/Internal/Abstractions/IChannel.cs
index d9409dd..2549e7f 100644
--- a/src/DotPulsar/Internal/Abstractions/IChannel.cs
+++ b/src/DotPulsar/Internal/Abstractions/IChannel.cs
@@ -12,20 +12,19 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using System;
+namespace DotPulsar.Internal.Abstractions;
- public interface IChannel
- {
- void Received(MessagePackage message);
- void Activated();
- void ClosedByServer();
- void Connected();
- void Deactivated();
- void Disconnected();
- void ReachedEndOfTopic();
- void Unsubscribed();
- IDisposable SenderLock();
- }
+using System;
+
+public interface IChannel
+{
+ void Received(MessagePackage message);
+ void Activated();
+ void ClosedByServer();
+ void Connected();
+ void Deactivated();
+ void Disconnected();
+ void ReachedEndOfTopic();
+ void Unsubscribed();
+ IDisposable SenderLock();
}
diff --git a/src/DotPulsar/Internal/Abstractions/ICompress.cs b/src/DotPulsar/Internal/Abstractions/ICompress.cs
index 39ea5a0..de7fe49 100644
--- a/src/DotPulsar/Internal/Abstractions/ICompress.cs
+++ b/src/DotPulsar/Internal/Abstractions/ICompress.cs
@@ -12,13 +12,12 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using System;
- using System.Buffers;
+namespace DotPulsar.Internal.Abstractions;
- public interface ICompress : IDisposable
- {
- ReadOnlySequence<byte> Compress(ReadOnlySequence<byte> data);
- }
+using System;
+using System.Buffers;
+
+public interface ICompress : IDisposable
+{
+ ReadOnlySequence<byte> Compress(ReadOnlySequence<byte> data);
}
diff --git a/src/DotPulsar/Internal/Abstractions/ICompressorFactory.cs b/src/DotPulsar/Internal/Abstractions/ICompressorFactory.cs
index f658e24..90249f0 100644
--- a/src/DotPulsar/Internal/Abstractions/ICompressorFactory.cs
+++ b/src/DotPulsar/Internal/Abstractions/ICompressorFactory.cs
@@ -12,13 +12,12 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using DotPulsar.Internal.PulsarApi;
+namespace DotPulsar.Internal.Abstractions;
- public interface ICompressorFactory
- {
- CompressionType CompressionType { get; }
- ICompress Create();
- }
+using DotPulsar.Internal.PulsarApi;
+
+public interface ICompressorFactory
+{
+ CompressionType CompressionType { get; }
+ ICompress Create();
}
diff --git a/src/DotPulsar/Internal/Abstractions/IConnection.cs b/src/DotPulsar/Internal/Abstractions/IConnection.cs
index f6c7092..e6e81d8 100644
--- a/src/DotPulsar/Internal/Abstractions/IConnection.cs
+++ b/src/DotPulsar/Internal/Abstractions/IConnection.cs
@@ -12,35 +12,34 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
+namespace DotPulsar.Internal.Abstractions;
+
+using PulsarApi;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+public interface IConnection : IAsyncDisposable
{
- using PulsarApi;
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+ ValueTask<bool> HasChannels(CancellationToken cancellationToken);
- public interface IConnection : IAsyncDisposable
- {
- ValueTask<bool> HasChannels(CancellationToken cancellationToken);
+ Task<ProducerResponse> Send(CommandProducer command, IChannel channel, CancellationToken cancellationToken);
+ Task<SubscribeResponse> Send(CommandSubscribe command, IChannel channel, CancellationToken cancellationToken);
- Task<ProducerResponse> Send(CommandProducer command, IChannel channel, CancellationToken cancellationToken);
- Task<SubscribeResponse> Send(CommandSubscribe command, IChannel channel, CancellationToken cancellationToken);
+ Task Send(CommandPing command, CancellationToken cancellationToken);
+ Task Send(CommandPong command, CancellationToken cancellationToken);
+ Task Send(CommandAck command, CancellationToken cancellationToken);
+ Task Send(CommandFlow command, CancellationToken cancellationToken);
+ Task Send(CommandRedeliverUnacknowledgedMessages command, CancellationToken cancellationToken);
- Task Send(CommandPing command, CancellationToken cancellationToken);
- Task Send(CommandPong command, CancellationToken cancellationToken);
- Task Send(CommandAck command, CancellationToken cancellationToken);
- Task Send(CommandFlow command, CancellationToken cancellationToken);
- Task Send(CommandRedeliverUnacknowledgedMessages command, CancellationToken cancellationToken);
-
- Task<BaseCommand> Send(CommandUnsubscribe command, CancellationToken cancellationToken);
- Task<BaseCommand> Send(CommandConnect command, CancellationToken cancellationToken);
- Task<BaseCommand> Send(CommandLookupTopic command, CancellationToken cancellationToken);
- Task<BaseCommand> Send(CommandSeek command, CancellationToken cancellationToken);
- Task<BaseCommand> Send(CommandGetLastMessageId command, CancellationToken cancellationToken);
- Task<BaseCommand> Send(CommandCloseProducer command, CancellationToken cancellationToken);
- Task<BaseCommand> Send(CommandCloseConsumer command, CancellationToken cancellationToken);
- Task<BaseCommand> Send(SendPackage command, CancellationToken cancellationToken);
- Task<BaseCommand> Send(CommandGetOrCreateSchema command, CancellationToken cancellationToken);
- Task<BaseCommand> Send(CommandPartitionedTopicMetadata command, CancellationToken cancellationToken);
- }
+ Task<BaseCommand> Send(CommandUnsubscribe command, CancellationToken cancellationToken);
+ Task<BaseCommand> Send(CommandConnect command, CancellationToken cancellationToken);
+ Task<BaseCommand> Send(CommandLookupTopic command, CancellationToken cancellationToken);
+ Task<BaseCommand> Send(CommandSeek command, CancellationToken cancellationToken);
+ Task<BaseCommand> Send(CommandGetLastMessageId command, CancellationToken cancellationToken);
+ Task<BaseCommand> Send(CommandCloseProducer command, CancellationToken cancellationToken);
+ Task<BaseCommand> Send(CommandCloseConsumer command, CancellationToken cancellationToken);
+ Task<BaseCommand> Send(SendPackage command, CancellationToken cancellationToken);
+ Task<BaseCommand> Send(CommandGetOrCreateSchema command, CancellationToken cancellationToken);
+ Task<BaseCommand> Send(CommandPartitionedTopicMetadata command, CancellationToken cancellationToken);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IConnectionPool.cs b/src/DotPulsar/Internal/Abstractions/IConnectionPool.cs
index ad313b1..f7e82d9 100644
--- a/src/DotPulsar/Internal/Abstractions/IConnectionPool.cs
+++ b/src/DotPulsar/Internal/Abstractions/IConnectionPool.cs
@@ -12,14 +12,13 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+namespace DotPulsar.Internal.Abstractions;
- public interface IConnectionPool : IAsyncDisposable
- {
- ValueTask<IConnection> FindConnectionForTopic(string topic, CancellationToken cancellationToken = default);
- }
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+public interface IConnectionPool : IAsyncDisposable
+{
+ ValueTask<IConnection> FindConnectionForTopic(string topic, CancellationToken cancellationToken = default);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IConsumerChannel.cs b/src/DotPulsar/Internal/Abstractions/IConsumerChannel.cs
index a359508..b984fe5 100644
--- a/src/DotPulsar/Internal/Abstractions/IConsumerChannel.cs
+++ b/src/DotPulsar/Internal/Abstractions/IConsumerChannel.cs
@@ -12,22 +12,21 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using DotPulsar.Abstractions;
- using PulsarApi;
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+namespace DotPulsar.Internal.Abstractions;
- public interface IConsumerChannel<TMessage> : IAsyncDisposable
- {
- Task Send(CommandAck command, CancellationToken cancellationToken);
- Task Send(CommandRedeliverUnacknowledgedMessages command, CancellationToken cancellationToken);
- Task Send(CommandUnsubscribe command, CancellationToken cancellationToken);
- Task Send(CommandSeek command, CancellationToken cancellationToken);
- Task<MessageId> Send(CommandGetLastMessageId command, CancellationToken cancellationToken);
- ValueTask<IMessage<TMessage>> Receive(CancellationToken cancellationToken);
- ValueTask ClosedByClient(CancellationToken cancellationToken);
- }
+using DotPulsar.Abstractions;
+using PulsarApi;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+public interface IConsumerChannel<TMessage> : IAsyncDisposable
+{
+ Task Send(CommandAck command, CancellationToken cancellationToken);
+ Task Send(CommandRedeliverUnacknowledgedMessages command, CancellationToken cancellationToken);
+ Task Send(CommandUnsubscribe command, CancellationToken cancellationToken);
+ Task Send(CommandSeek command, CancellationToken cancellationToken);
+ Task<MessageId> Send(CommandGetLastMessageId command, CancellationToken cancellationToken);
+ ValueTask<IMessage<TMessage>> Receive(CancellationToken cancellationToken);
+ ValueTask ClosedByClient(CancellationToken cancellationToken);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IConsumerChannelFactory.cs b/src/DotPulsar/Internal/Abstractions/IConsumerChannelFactory.cs
index 76fb932..99e196b 100644
--- a/src/DotPulsar/Internal/Abstractions/IConsumerChannelFactory.cs
+++ b/src/DotPulsar/Internal/Abstractions/IConsumerChannelFactory.cs
@@ -12,13 +12,12 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using System.Threading;
- using System.Threading.Tasks;
+namespace DotPulsar.Internal.Abstractions;
- public interface IConsumerChannelFactory<TMessage>
- {
- Task<IConsumerChannel<TMessage>> Create(CancellationToken cancellationToken = default);
- }
+using System.Threading;
+using System.Threading.Tasks;
+
+public interface IConsumerChannelFactory<TMessage>
+{
+ Task<IConsumerChannel<TMessage>> Create(CancellationToken cancellationToken = default);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IDecompress.cs b/src/DotPulsar/Internal/Abstractions/IDecompress.cs
index 0584a26..14f8ebd 100644
--- a/src/DotPulsar/Internal/Abstractions/IDecompress.cs
+++ b/src/DotPulsar/Internal/Abstractions/IDecompress.cs
@@ -12,13 +12,12 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using System;
- using System.Buffers;
+namespace DotPulsar.Internal.Abstractions;
- public interface IDecompress : IDisposable
- {
- ReadOnlySequence<byte> Decompress(ReadOnlySequence<byte> data, int decompressedSize);
- }
+using System;
+using System.Buffers;
+
+public interface IDecompress : IDisposable
+{
+ ReadOnlySequence<byte> Decompress(ReadOnlySequence<byte> data, int decompressedSize);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IDecompressorFactory.cs b/src/DotPulsar/Internal/Abstractions/IDecompressorFactory.cs
index 7cbbd96..bccbf10 100644
--- a/src/DotPulsar/Internal/Abstractions/IDecompressorFactory.cs
+++ b/src/DotPulsar/Internal/Abstractions/IDecompressorFactory.cs
@@ -12,13 +12,12 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using DotPulsar.Internal.PulsarApi;
+namespace DotPulsar.Internal.Abstractions;
- public interface IDecompressorFactory
- {
- CompressionType CompressionType { get; }
- IDecompress Create();
- }
+using DotPulsar.Internal.PulsarApi;
+
+public interface IDecompressorFactory
+{
+ CompressionType CompressionType { get; }
+ IDecompress Create();
}
diff --git a/src/DotPulsar/Internal/Abstractions/IDequeue.cs b/src/DotPulsar/Internal/Abstractions/IDequeue.cs
index f99da40..3bf46d8 100644
--- a/src/DotPulsar/Internal/Abstractions/IDequeue.cs
+++ b/src/DotPulsar/Internal/Abstractions/IDequeue.cs
@@ -12,13 +12,12 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using System.Threading;
- using System.Threading.Tasks;
+namespace DotPulsar.Internal.Abstractions;
- public interface IDequeue<T>
- {
- ValueTask<T> Dequeue(CancellationToken cancellationToken = default);
- }
+using System.Threading;
+using System.Threading.Tasks;
+
+public interface IDequeue<T>
+{
+ ValueTask<T> Dequeue(CancellationToken cancellationToken = default);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IEnqueue.cs b/src/DotPulsar/Internal/Abstractions/IEnqueue.cs
index c5794b7..6617d16 100644
--- a/src/DotPulsar/Internal/Abstractions/IEnqueue.cs
+++ b/src/DotPulsar/Internal/Abstractions/IEnqueue.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
+namespace DotPulsar.Internal.Abstractions;
+
+public interface IEnqueue<T>
{
- public interface IEnqueue<T>
- {
- void Enqueue(T item);
- }
+ void Enqueue(T item);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IEstablishNewChannel.cs b/src/DotPulsar/Internal/Abstractions/IEstablishNewChannel.cs
index bcf8723..972fe77 100644
--- a/src/DotPulsar/Internal/Abstractions/IEstablishNewChannel.cs
+++ b/src/DotPulsar/Internal/Abstractions/IEstablishNewChannel.cs
@@ -12,14 +12,13 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+namespace DotPulsar.Internal.Abstractions;
- public interface IEstablishNewChannel : IAsyncDisposable
- {
- Task EstablishNewChannel(CancellationToken cancellationToken);
- }
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+public interface IEstablishNewChannel : IAsyncDisposable
+{
+ Task EstablishNewChannel(CancellationToken cancellationToken);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IEvent.cs b/src/DotPulsar/Internal/Abstractions/IEvent.cs
index f399d4e..52e8372 100644
--- a/src/DotPulsar/Internal/Abstractions/IEvent.cs
+++ b/src/DotPulsar/Internal/Abstractions/IEvent.cs
@@ -1,4 +1,4 @@
-/*
+/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
@@ -12,12 +12,11 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using System;
+namespace DotPulsar.Internal.Abstractions;
- public interface IEvent
- {
- Guid CorrelationId { get; }
- }
+using System;
+
+public interface IEvent
+{
+ Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/Abstractions/IExecute.cs b/src/DotPulsar/Internal/Abstractions/IExecute.cs
index 1b4ec62..ad9b07f 100644
--- a/src/DotPulsar/Internal/Abstractions/IExecute.cs
+++ b/src/DotPulsar/Internal/Abstractions/IExecute.cs
@@ -12,24 +12,23 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
+namespace DotPulsar.Internal.Abstractions;
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+public interface IExecute
{
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+ ValueTask Execute(Action action, CancellationToken cancellationToken = default);
- public interface IExecute
- {
- ValueTask Execute(Action action, CancellationToken cancellationToken = default);
+ ValueTask Execute(Func<Task> func, CancellationToken cancellationToken = default);
- ValueTask Execute(Func<Task> func, CancellationToken cancellationToken = default);
+ ValueTask Execute(Func<ValueTask> func, CancellationToken cancellationToken = default);
- ValueTask Execute(Func<ValueTask> func, CancellationToken cancellationToken = default);
+ ValueTask<TResult> Execute<TResult>(Func<TResult> func, CancellationToken cancellationToken = default);
- ValueTask<TResult> Execute<TResult>(Func<TResult> func, CancellationToken cancellationToken = default);
+ ValueTask<TResult> Execute<TResult>(Func<Task<TResult>> func, CancellationToken cancellationToken = default);
- ValueTask<TResult> Execute<TResult>(Func<Task<TResult>> func, CancellationToken cancellationToken = default);
-
- ValueTask<TResult> Execute<TResult>(Func<ValueTask<TResult>> func, CancellationToken cancellationToken = default);
- }
+ ValueTask<TResult> Execute<TResult>(Func<ValueTask<TResult>> func, CancellationToken cancellationToken = default);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IMessageFactory.cs b/src/DotPulsar/Internal/Abstractions/IMessageFactory.cs
index ebdb3ee..59009cd 100644
--- a/src/DotPulsar/Internal/Abstractions/IMessageFactory.cs
+++ b/src/DotPulsar/Internal/Abstractions/IMessageFactory.cs
@@ -12,14 +12,13 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using DotPulsar.Abstractions;
- using DotPulsar.Internal.PulsarApi;
- using System.Buffers;
+namespace DotPulsar.Internal.Abstractions;
- public interface IMessageFactory<TValue>
- {
- IMessage<TValue> Create(MessageId messageId, uint redeliveryCount, ReadOnlySequence<byte> data, MessageMetadata metadata, SingleMessageMetadata? singleMetadata = null);
- }
+using DotPulsar.Abstractions;
+using DotPulsar.Internal.PulsarApi;
+using System.Buffers;
+
+public interface IMessageFactory<TValue>
+{
+ IMessage<TValue> Create(MessageId messageId, uint redeliveryCount, ReadOnlySequence<byte> data, MessageMetadata metadata, SingleMessageMetadata? singleMetadata = null);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IProcess.cs b/src/DotPulsar/Internal/Abstractions/IProcess.cs
index 4c48c39..831f456 100644
--- a/src/DotPulsar/Internal/Abstractions/IProcess.cs
+++ b/src/DotPulsar/Internal/Abstractions/IProcess.cs
@@ -12,15 +12,14 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
+namespace DotPulsar.Internal.Abstractions;
+
+using System;
+
+public interface IProcess : IAsyncDisposable
{
- using System;
+ Guid CorrelationId { get; }
- public interface IProcess : IAsyncDisposable
- {
- Guid CorrelationId { get; }
-
- void Start();
- void Handle(IEvent @event);
- }
+ void Start();
+ void Handle(IEvent @event);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IProducerChannel.cs b/src/DotPulsar/Internal/Abstractions/IProducerChannel.cs
index b214237..df6b291 100644
--- a/src/DotPulsar/Internal/Abstractions/IProducerChannel.cs
+++ b/src/DotPulsar/Internal/Abstractions/IProducerChannel.cs
@@ -12,17 +12,16 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using PulsarApi;
- using System;
- using System.Buffers;
- using System.Threading;
- using System.Threading.Tasks;
+namespace DotPulsar.Internal.Abstractions;
- public interface IProducerChannel : IAsyncDisposable
- {
- Task<CommandSendReceipt> Send(MessageMetadata metadata, ReadOnlySequence<byte> payload, CancellationToken cancellationToken);
- ValueTask ClosedByClient(CancellationToken cancellationToken);
- }
+using PulsarApi;
+using System;
+using System.Buffers;
+using System.Threading;
+using System.Threading.Tasks;
+
+public interface IProducerChannel : IAsyncDisposable
+{
+ Task<CommandSendReceipt> Send(MessageMetadata metadata, ReadOnlySequence<byte> payload, CancellationToken cancellationToken);
+ ValueTask ClosedByClient(CancellationToken cancellationToken);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IProducerChannelFactory.cs b/src/DotPulsar/Internal/Abstractions/IProducerChannelFactory.cs
index 2f84785..eb7085a 100644
--- a/src/DotPulsar/Internal/Abstractions/IProducerChannelFactory.cs
+++ b/src/DotPulsar/Internal/Abstractions/IProducerChannelFactory.cs
@@ -12,13 +12,12 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using System.Threading;
- using System.Threading.Tasks;
+namespace DotPulsar.Internal.Abstractions;
- public interface IProducerChannelFactory
- {
- Task<IProducerChannel> Create(CancellationToken cancellationToken = default);
- }
+using System.Threading;
+using System.Threading.Tasks;
+
+public interface IProducerChannelFactory
+{
+ Task<IProducerChannel> Create(CancellationToken cancellationToken = default);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IPulsarStream.cs b/src/DotPulsar/Internal/Abstractions/IPulsarStream.cs
index 0ce67ef..c562528 100644
--- a/src/DotPulsar/Internal/Abstractions/IPulsarStream.cs
+++ b/src/DotPulsar/Internal/Abstractions/IPulsarStream.cs
@@ -12,17 +12,16 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using System;
- using System.Buffers;
- using System.Collections.Generic;
- using System.Threading;
- using System.Threading.Tasks;
+namespace DotPulsar.Internal.Abstractions;
- public interface IPulsarStream : IAsyncDisposable
- {
- Task Send(ReadOnlySequence<byte> sequence);
- IAsyncEnumerable<ReadOnlySequence<byte>> Frames(CancellationToken cancellationToken = default);
- }
+using System;
+using System.Buffers;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+public interface IPulsarStream : IAsyncDisposable
+{
+ Task Send(ReadOnlySequence<byte> sequence);
+ IAsyncEnumerable<ReadOnlySequence<byte>> Frames(CancellationToken cancellationToken = default);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IRegisterEvent.cs b/src/DotPulsar/Internal/Abstractions/IRegisterEvent.cs
index ef3b427..2470ccd 100644
--- a/src/DotPulsar/Internal/Abstractions/IRegisterEvent.cs
+++ b/src/DotPulsar/Internal/Abstractions/IRegisterEvent.cs
@@ -12,10 +12,9 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
+namespace DotPulsar.Internal.Abstractions;
+
+public interface IRegisterEvent
{
- public interface IRegisterEvent
- {
- void Register(IEvent @event);
- }
+ void Register(IEvent @event);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IRequest.cs b/src/DotPulsar/Internal/Abstractions/IRequest.cs
index 0841e26..1f8508d 100644
--- a/src/DotPulsar/Internal/Abstractions/IRequest.cs
+++ b/src/DotPulsar/Internal/Abstractions/IRequest.cs
@@ -12,15 +12,14 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
-{
- using DotPulsar.Internal.PulsarApi;
- using System;
+namespace DotPulsar.Internal.Abstractions;
- public interface IRequest : IEquatable<IRequest>
- {
- bool SenderIsProducer(ulong producerId);
- bool SenderIsConsumer(ulong consumerId);
- bool IsCommandType(BaseCommand.Type commandType);
- }
+using DotPulsar.Internal.PulsarApi;
+using System;
+
+public interface IRequest : IEquatable<IRequest>
+{
+ bool SenderIsProducer(ulong producerId);
+ bool SenderIsConsumer(ulong consumerId);
+ bool IsCommandType(BaseCommand.Type commandType);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IStateChanged.cs b/src/DotPulsar/Internal/Abstractions/IStateChanged.cs
index da45aa0..a1de336 100644
--- a/src/DotPulsar/Internal/Abstractions/IStateChanged.cs
+++ b/src/DotPulsar/Internal/Abstractions/IStateChanged.cs
@@ -12,52 +12,51 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
+namespace DotPulsar.Internal.Abstractions;
+
+using System.Threading;
+using System.Threading.Tasks;
+
+/// <summary>
+/// A state change monitoring abstraction.
+/// </summary>
+public interface IStateChanged<TState> where TState : notnull
{
- using System.Threading;
- using System.Threading.Tasks;
+ /// <summary>
+ /// Wait for the state to change to a specific state.
+ /// </summary>
+ /// <returns>
+ /// The current state.
+ /// </returns>
+ /// <remarks>
+ /// If the state change to a final state, then all awaiting tasks will complete.
+ /// </remarks>
+ ValueTask<TState> StateChangedTo(TState state, CancellationToken cancellationToken = default);
/// <summary>
- /// A state change monitoring abstraction.
+ /// Wait for the state to change from a specific state.
/// </summary>
- public interface IStateChanged<TState> where TState : notnull
- {
- /// <summary>
- /// Wait for the state to change to a specific state.
- /// </summary>
- /// <returns>
- /// The current state.
- /// </returns>
- /// <remarks>
- /// If the state change to a final state, then all awaiting tasks will complete.
- /// </remarks>
- ValueTask<TState> StateChangedTo(TState state, CancellationToken cancellationToken = default);
+ /// <returns>
+ /// The current state.
+ /// </returns>
+ /// <remarks>
+ /// If the state change to a final state, then all awaiting tasks will complete.
+ /// </remarks>
+ ValueTask<TState> StateChangedFrom(TState state, CancellationToken cancellationToken = default);
- /// <summary>
- /// Wait for the state to change from a specific state.
- /// </summary>
- /// <returns>
- /// The current state.
- /// </returns>
- /// <remarks>
- /// If the state change to a final state, then all awaiting tasks will complete.
- /// </remarks>
- ValueTask<TState> StateChangedFrom(TState state, CancellationToken cancellationToken = default);
+ /// <summary>
+ /// Ask whether the current state is final, meaning that it will never change.
+ /// </summary>
+ /// <returns>
+ /// True if it's final and False if it's not.
+ /// </returns>
+ bool IsFinalState();
- /// <summary>
- /// Ask whether the current state is final, meaning that it will never change.
- /// </summary>
- /// <returns>
- /// True if it's final and False if it's not.
- /// </returns>
- bool IsFinalState();
-
- /// <summary>
- /// Ask whether the provided state is final, meaning that it will never change.
- /// </summary>
- /// <returns>
- /// True if it's final and False if it's not.
- /// </returns>
- bool IsFinalState(TState state);
- }
+ /// <summary>
+ /// Ask whether the provided state is final, meaning that it will never change.
+ /// </summary>
+ /// <returns>
+ /// True if it's final and False if it's not.
+ /// </returns>
+ bool IsFinalState(TState state);
}
diff --git a/src/DotPulsar/Internal/Abstractions/IStateManager.cs b/src/DotPulsar/Internal/Abstractions/IStateManager.cs
index 19e616c..135a2ac 100644
--- a/src/DotPulsar/Internal/Abstractions/IStateManager.cs
+++ b/src/DotPulsar/Internal/Abstractions/IStateManager.cs
@@ -12,11 +12,10 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
+namespace DotPulsar.Internal.Abstractions;
+
+public interface IStateManager<TState> : IStateChanged<TState> where TState : notnull
{
- public interface IStateManager<TState> : IStateChanged<TState> where TState : notnull
- {
- TState CurrentState { get; }
- TState SetState(TState state);
- }
+ TState CurrentState { get; }
+ TState SetState(TState state);
}
diff --git a/src/DotPulsar/Internal/Abstractions/Process.cs b/src/DotPulsar/Internal/Abstractions/Process.cs
index 056471a..85d1582 100644
--- a/src/DotPulsar/Internal/Abstractions/Process.cs
+++ b/src/DotPulsar/Internal/Abstractions/Process.cs
@@ -12,67 +12,66 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Abstractions
+namespace DotPulsar.Internal.Abstractions;
+
+using Events;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+public abstract class Process : IProcess
{
- using Events;
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+ protected readonly CancellationTokenSource CancellationTokenSource;
+ protected ChannelState ChannelState;
+ protected ExecutorState ExecutorState;
- public abstract class Process : IProcess
+ protected Process(Guid correlationId)
{
- protected readonly CancellationTokenSource CancellationTokenSource;
- protected ChannelState ChannelState;
- protected ExecutorState ExecutorState;
-
- protected Process(Guid correlationId)
- {
- CancellationTokenSource = new CancellationTokenSource();
- ChannelState = ChannelState.Disconnected;
- ExecutorState = ExecutorState.Ok;
- CorrelationId = correlationId;
- }
-
- public Guid CorrelationId { get; }
-
- public void Start()
- => CalculateState();
-
- public abstract ValueTask DisposeAsync();
-
- public void Handle(IEvent e)
- {
- switch (e)
- {
- case ExecutorFaulted _:
- ExecutorState = ExecutorState.Faulted;
- break;
- case ChannelActivated _:
- ChannelState = ChannelState.Active;
- break;
- case ChannelClosedByServer _:
- ChannelState = ChannelState.ClosedByServer;
- break;
- case ChannelConnected _:
- ChannelState = ChannelState.Connected;
- break;
- case ChannelDeactivated _:
- ChannelState = ChannelState.Inactive;
- break;
- case ChannelDisconnected _:
- ChannelState = ChannelState.Disconnected;
- break;
- case ChannelReachedEndOfTopic _:
- ChannelState = ChannelState.ReachedEndOfTopic;
- break;
- case ChannelUnsubscribed _:
- ChannelState = ChannelState.Unsubscribed;
- break;
- }
-
- CalculateState();
- }
-
- protected abstract void CalculateState();
+ CancellationTokenSource = new CancellationTokenSource();
+ ChannelState = ChannelState.Disconnected;
+ ExecutorState = ExecutorState.Ok;
+ CorrelationId = correlationId;
}
+
+ public Guid CorrelationId { get; }
+
+ public void Start()
+ => CalculateState();
+
+ public abstract ValueTask DisposeAsync();
+
+ public void Handle(IEvent e)
+ {
+ switch (e)
+ {
+ case ExecutorFaulted _:
+ ExecutorState = ExecutorState.Faulted;
+ break;
+ case ChannelActivated _:
+ ChannelState = ChannelState.Active;
+ break;
+ case ChannelClosedByServer _:
+ ChannelState = ChannelState.ClosedByServer;
+ break;
+ case ChannelConnected _:
+ ChannelState = ChannelState.Connected;
+ break;
+ case ChannelDeactivated _:
+ ChannelState = ChannelState.Inactive;
+ break;
+ case ChannelDisconnected _:
+ ChannelState = ChannelState.Disconnected;
+ break;
+ case ChannelReachedEndOfTopic _:
+ ChannelState = ChannelState.ReachedEndOfTopic;
+ break;
+ case ChannelUnsubscribed _:
+ ChannelState = ChannelState.Unsubscribed;
+ break;
+ }
+
+ CalculateState();
+ }
+
+ protected abstract void CalculateState();
}
diff --git a/src/DotPulsar/Internal/ActionExceptionHandler.cs b/src/DotPulsar/Internal/ActionExceptionHandler.cs
index 0327153..1c8ce6f 100644
--- a/src/DotPulsar/Internal/ActionExceptionHandler.cs
+++ b/src/DotPulsar/Internal/ActionExceptionHandler.cs
@@ -12,23 +12,22 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using DotPulsar.Abstractions;
+using System;
+using System.Threading.Tasks;
+
+public sealed class ActionExceptionHandler : IHandleException
{
- using DotPulsar.Abstractions;
- using System;
- using System.Threading.Tasks;
+ private readonly Action<ExceptionContext> _exceptionHandler;
- public sealed class ActionExceptionHandler : IHandleException
+ public ActionExceptionHandler(Action<ExceptionContext> exceptionHandler)
+ => _exceptionHandler = exceptionHandler;
+
+ public ValueTask OnException(ExceptionContext exceptionContext)
{
- private readonly Action<ExceptionContext> _exceptionHandler;
-
- public ActionExceptionHandler(Action<ExceptionContext> exceptionHandler)
- => _exceptionHandler = exceptionHandler;
-
- public ValueTask OnException(ExceptionContext exceptionContext)
- {
- _exceptionHandler(exceptionContext);
- return new ValueTask();
- }
+ _exceptionHandler(exceptionContext);
+ return new ValueTask();
}
}
diff --git a/src/DotPulsar/Internal/ActionStateChangedHandler.cs b/src/DotPulsar/Internal/ActionStateChangedHandler.cs
index 804d7b3..274441d 100644
--- a/src/DotPulsar/Internal/ActionStateChangedHandler.cs
+++ b/src/DotPulsar/Internal/ActionStateChangedHandler.cs
@@ -12,29 +12,28 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using DotPulsar.Abstractions;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+public sealed class ActionStateChangedHandler<TStateChanged> : IHandleStateChanged<TStateChanged>
{
- using DotPulsar.Abstractions;
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+ private readonly Action<TStateChanged, CancellationToken> _stateChangedHandler;
- public sealed class ActionStateChangedHandler<TStateChanged> : IHandleStateChanged<TStateChanged>
+ public ActionStateChangedHandler(Action<TStateChanged, CancellationToken> stateChangedHandler, CancellationToken cancellationToken)
{
- private readonly Action<TStateChanged, CancellationToken> _stateChangedHandler;
+ _stateChangedHandler = stateChangedHandler;
+ CancellationToken = cancellationToken;
+ }
- public ActionStateChangedHandler(Action<TStateChanged, CancellationToken> stateChangedHandler, CancellationToken cancellationToken)
- {
- _stateChangedHandler = stateChangedHandler;
- CancellationToken = cancellationToken;
- }
+ public CancellationToken CancellationToken { get; }
- public CancellationToken CancellationToken { get; }
-
- public ValueTask OnStateChanged(TStateChanged stateChanged, CancellationToken cancellationToken)
- {
- _stateChangedHandler(stateChanged, CancellationToken);
- return new ValueTask();
- }
+ public ValueTask OnStateChanged(TStateChanged stateChanged, CancellationToken cancellationToken)
+ {
+ _stateChangedHandler(stateChanged, CancellationToken);
+ return new ValueTask();
}
}
diff --git a/src/DotPulsar/Internal/AsyncLock.cs b/src/DotPulsar/Internal/AsyncLock.cs
index 432eb37..a572dde 100644
--- a/src/DotPulsar/Internal/AsyncLock.cs
+++ b/src/DotPulsar/Internal/AsyncLock.cs
@@ -12,122 +12,121 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using Exceptions;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+public sealed class AsyncLock : IAsyncDisposable
{
- using Exceptions;
- using System;
- using System.Collections.Generic;
- using System.Threading;
- using System.Threading.Tasks;
+ private readonly LinkedList<CancelableCompletionSource<IDisposable>> _pending;
+ private readonly SemaphoreSlim _semaphoreSlim;
+ private readonly Releaser _releaser;
+ private readonly Task<IDisposable> _completedTask;
+ private int _isDisposed;
- public sealed class AsyncLock : IAsyncDisposable
+ public AsyncLock()
{
- private readonly LinkedList<CancelableCompletionSource<IDisposable>> _pending;
- private readonly SemaphoreSlim _semaphoreSlim;
- private readonly Releaser _releaser;
- private readonly Task<IDisposable> _completedTask;
- private int _isDisposed;
+ _pending = new LinkedList<CancelableCompletionSource<IDisposable>>();
+ _semaphoreSlim = new SemaphoreSlim(1, 1);
+ _releaser = new Releaser(Release);
+ _completedTask = Task.FromResult((IDisposable) _releaser);
+ }
- public AsyncLock()
+ public Task<IDisposable> Lock(CancellationToken cancellationToken)
+ {
+ LinkedListNode<CancelableCompletionSource<IDisposable>>? node = null;
+
+ lock (_pending)
{
- _pending = new LinkedList<CancelableCompletionSource<IDisposable>>();
- _semaphoreSlim = new SemaphoreSlim(1, 1);
- _releaser = new Releaser(Release);
- _completedTask = Task.FromResult((IDisposable) _releaser);
- }
+ ThrowIfDisposed();
- public Task<IDisposable> Lock(CancellationToken cancellationToken)
- {
- LinkedListNode<CancelableCompletionSource<IDisposable>>? node = null;
-
- lock (_pending)
+ if (_semaphoreSlim.CurrentCount == 1) //Lock is free
{
- ThrowIfDisposed();
-
- if (_semaphoreSlim.CurrentCount == 1) //Lock is free
- {
- _semaphoreSlim.Wait(cancellationToken); //Will never block
- return _completedTask;
- }
-
- //Lock was not free
- var ccs = new CancelableCompletionSource<IDisposable>();
- node = _pending.AddLast(ccs);
+ _semaphoreSlim.Wait(cancellationToken); //Will never block
+ return _completedTask;
}
- cancellationToken.Register(() => Cancel(node));
-
- return node.Value.Task;
+ //Lock was not free
+ var ccs = new CancelableCompletionSource<IDisposable>();
+ node = _pending.AddLast(ccs);
}
- public async ValueTask DisposeAsync()
+ cancellationToken.Register(() => Cancel(node));
+
+ return node.Value.Task;
+ }
+
+ public async ValueTask DisposeAsync()
+ {
+ lock (_pending)
{
- lock (_pending)
+ if (Interlocked.Exchange(ref _isDisposed, 1) != 0)
+ return;
+
+ foreach (var pending in _pending)
+ pending.Dispose();
+
+ _pending.Clear();
+ }
+
+ await _semaphoreSlim.WaitAsync().ConfigureAwait(false); //Wait for possible lock-holder to finish
+
+ _semaphoreSlim.Release();
+ _semaphoreSlim.Dispose();
+ }
+
+ private void Cancel(LinkedListNode<CancelableCompletionSource<IDisposable>> node)
+ {
+ lock (_pending)
+ {
+ try
{
- if (Interlocked.Exchange(ref _isDisposed, 1) != 0)
- return;
-
- foreach (var pending in _pending)
- pending.Dispose();
-
- _pending.Clear();
+ _pending.Remove(node);
+ node.Value.Dispose();
}
-
- await _semaphoreSlim.WaitAsync().ConfigureAwait(false); //Wait for possible lock-holder to finish
-
- _semaphoreSlim.Release();
- _semaphoreSlim.Dispose();
- }
-
- private void Cancel(LinkedListNode<CancelableCompletionSource<IDisposable>> node)
- {
- lock (_pending)
+ catch
{
- try
- {
- _pending.Remove(node);
- node.Value.Dispose();
- }
- catch
- {
- // Ignore
- }
+ // Ignore
}
}
+ }
- private void Release()
+ private void Release()
+ {
+ lock (_pending)
{
- lock (_pending)
+ var node = _pending.First;
+ if (node is not null)
{
- var node = _pending.First;
- if (node is not null)
- {
- node.Value.SetResult(_releaser);
- node.Value.Dispose();
- _pending.RemoveFirst();
- return;
- }
-
- if (_semaphoreSlim.CurrentCount == 0)
- _semaphoreSlim.Release();
+ node.Value.SetResult(_releaser);
+ node.Value.Dispose();
+ _pending.RemoveFirst();
+ return;
}
+
+ if (_semaphoreSlim.CurrentCount == 0)
+ _semaphoreSlim.Release();
}
+ }
- private void ThrowIfDisposed()
- {
- if (_isDisposed != 0)
- throw new AsyncLockDisposedException();
- }
+ private void ThrowIfDisposed()
+ {
+ if (_isDisposed != 0)
+ throw new AsyncLockDisposedException();
+ }
- private class Releaser : IDisposable
- {
- private readonly Action _release;
+ private class Releaser : IDisposable
+ {
+ private readonly Action _release;
- public Releaser(Action release)
- => _release = release;
+ public Releaser(Action release)
+ => _release = release;
- public void Dispose()
- => _release();
- }
+ public void Dispose()
+ => _release();
}
}
diff --git a/src/DotPulsar/Internal/AsyncQueue.cs b/src/DotPulsar/Internal/AsyncQueue.cs
index 5c22c43..cca67cf 100644
--- a/src/DotPulsar/Internal/AsyncQueue.cs
+++ b/src/DotPulsar/Internal/AsyncQueue.cs
@@ -12,100 +12,99 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using Abstractions;
+using Exceptions;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+public sealed class AsyncQueue<T> : IEnqueue<T>, IDequeue<T>, IDisposable
{
- using Abstractions;
- using Exceptions;
- using System;
- using System.Collections.Generic;
- using System.Threading;
- using System.Threading.Tasks;
+ private readonly object _lock;
+ private readonly Queue<T> _queue;
+ private readonly LinkedList<CancelableCompletionSource<T>> _pendingDequeues;
+ private int _isDisposed;
- public sealed class AsyncQueue<T> : IEnqueue<T>, IDequeue<T>, IDisposable
+ public AsyncQueue()
{
- private readonly object _lock;
- private readonly Queue<T> _queue;
- private readonly LinkedList<CancelableCompletionSource<T>> _pendingDequeues;
- private int _isDisposed;
+ _lock = new object();
+ _queue = new Queue<T>();
+ _pendingDequeues = new LinkedList<CancelableCompletionSource<T>>();
+ }
- public AsyncQueue()
+ public void Enqueue(T item)
+ {
+ lock (_lock)
{
- _lock = new object();
- _queue = new Queue<T>();
- _pendingDequeues = new LinkedList<CancelableCompletionSource<T>>();
+ ThrowIfDisposed();
+
+ var node = _pendingDequeues.First;
+ if (node is not null)
+ {
+ node.Value.SetResult(item);
+ node.Value.Dispose();
+ _pendingDequeues.RemoveFirst();
+ }
+ else
+ _queue.Enqueue(item);
+ }
+ }
+
+ public ValueTask<T> Dequeue(CancellationToken cancellationToken = default)
+ {
+ LinkedListNode<CancelableCompletionSource<T>>? node = null;
+
+ lock (_lock)
+ {
+ ThrowIfDisposed();
+
+ if (_queue.Count > 0)
+ return new ValueTask<T>(_queue.Dequeue());
+
+ node = _pendingDequeues.AddLast(new CancelableCompletionSource<T>());
}
- public void Enqueue(T item)
- {
- lock (_lock)
- {
- ThrowIfDisposed();
+ node.Value.SetupCancellation(() => Cancel(node), cancellationToken);
+ return new ValueTask<T>(node.Value.Task);
+ }
- var node = _pendingDequeues.First;
- if (node is not null)
- {
- node.Value.SetResult(item);
- node.Value.Dispose();
- _pendingDequeues.RemoveFirst();
- }
- else
- _queue.Enqueue(item);
+ public void Dispose()
+ {
+ lock (_lock)
+ {
+ if (Interlocked.Exchange(ref _isDisposed, 1) != 0)
+ return;
+
+ foreach (var pendingDequeue in _pendingDequeues)
+ pendingDequeue.Dispose();
+
+ _pendingDequeues.Clear();
+ _queue.Clear();
+ }
+ }
+
+ private void Cancel(LinkedListNode<CancelableCompletionSource<T>> node)
+ {
+ lock (_lock)
+ {
+ try
+ {
+ node.Value.Dispose();
+ _pendingDequeues.Remove(node);
+ }
+ catch
+ {
+ // ignored
}
}
+ }
- public ValueTask<T> Dequeue(CancellationToken cancellationToken = default)
- {
- LinkedListNode<CancelableCompletionSource<T>>? node = null;
-
- lock (_lock)
- {
- ThrowIfDisposed();
-
- if (_queue.Count > 0)
- return new ValueTask<T>(_queue.Dequeue());
-
- node = _pendingDequeues.AddLast(new CancelableCompletionSource<T>());
- }
-
- node.Value.SetupCancellation(() => Cancel(node), cancellationToken);
- return new ValueTask<T>(node.Value.Task);
- }
-
- public void Dispose()
- {
- lock (_lock)
- {
- if (Interlocked.Exchange(ref _isDisposed, 1) != 0)
- return;
-
- foreach (var pendingDequeue in _pendingDequeues)
- pendingDequeue.Dispose();
-
- _pendingDequeues.Clear();
- _queue.Clear();
- }
- }
-
- private void Cancel(LinkedListNode<CancelableCompletionSource<T>> node)
- {
- lock (_lock)
- {
- try
- {
- node.Value.Dispose();
- _pendingDequeues.Remove(node);
- }
- catch
- {
- // ignored
- }
- }
- }
-
- private void ThrowIfDisposed()
- {
- if (_isDisposed != 0)
- throw new AsyncQueueDisposedException();
- }
+ private void ThrowIfDisposed()
+ {
+ if (_isDisposed != 0)
+ throw new AsyncQueueDisposedException();
}
}
diff --git a/src/DotPulsar/Internal/Awaiter.cs b/src/DotPulsar/Internal/Awaiter.cs
index 6cec51c..c7360c7 100644
--- a/src/DotPulsar/Internal/Awaiter.cs
+++ b/src/DotPulsar/Internal/Awaiter.cs
@@ -12,47 +12,46 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+public sealed class Awaiter<T, TResult> : IDisposable where T : notnull
{
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Threading.Tasks;
+ private readonly ConcurrentDictionary<T, TaskCompletionSource<TResult>> _items;
- public sealed class Awaiter<T, TResult> : IDisposable where T : notnull
+ public Awaiter()
+ => _items = new ConcurrentDictionary<T, TaskCompletionSource<TResult>>();
+
+ public Task<TResult> CreateTask(T item)
{
- private readonly ConcurrentDictionary<T, TaskCompletionSource<TResult>> _items;
+ var tcs = new TaskCompletionSource<TResult>(TaskCreationOptions.RunContinuationsAsynchronously);
+ _ = _items.TryAdd(item, tcs);
+ return tcs.Task;
+ }
- public Awaiter()
- => _items = new ConcurrentDictionary<T, TaskCompletionSource<TResult>>();
+ public void SetResult(T item, TResult result)
+ {
+ if (_items.TryRemove(item, out var tcs))
+ tcs.SetResult(result);
+ }
- public Task<TResult> CreateTask(T item)
- {
- var tcs = new TaskCompletionSource<TResult>(TaskCreationOptions.RunContinuationsAsynchronously);
- _ = _items.TryAdd(item, tcs);
- return tcs.Task;
- }
+ public void Cancel(T item)
+ {
+ if (_items.TryRemove(item, out var tcs))
+ tcs.SetCanceled();
+ }
- public void SetResult(T item, TResult result)
- {
- if (_items.TryRemove(item, out var tcs))
- tcs.SetResult(result);
- }
+ public IEnumerable<T> Keys => _items.Keys;
- public void Cancel(T item)
- {
- if (_items.TryRemove(item, out var tcs))
- tcs.SetCanceled();
- }
+ public void Dispose()
+ {
+ foreach (var item in _items.Values)
+ item.SetCanceled();
- public IEnumerable<T> Keys => _items.Keys;
-
- public void Dispose()
- {
- foreach (var item in _items.Values)
- item.SetCanceled();
-
- _items.Clear();
- }
+ _items.Clear();
}
}
diff --git a/src/DotPulsar/Internal/BatchHandler.cs b/src/DotPulsar/Internal/BatchHandler.cs
index 60d2e9e..7ec382a 100644
--- a/src/DotPulsar/Internal/BatchHandler.cs
+++ b/src/DotPulsar/Internal/BatchHandler.cs
@@ -12,131 +12,130 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using DotPulsar.Abstractions;
+using DotPulsar.Internal.Abstractions;
+using Extensions;
+using PulsarApi;
+using System.Buffers;
+using System.Collections;
+using System.Collections.Generic;
+
+public sealed class BatchHandler<TMessage>
{
- using DotPulsar.Abstractions;
- using DotPulsar.Internal.Abstractions;
- using Extensions;
- using PulsarApi;
- using System.Buffers;
- using System.Collections;
- using System.Collections.Generic;
+ private readonly object _lock;
+ private readonly bool _trackBatches;
+ private readonly IMessageFactory<TMessage> _messageFactory;
+ private readonly Queue<IMessage<TMessage>> _messages;
+ private readonly LinkedList<Batch> _batches;
- public sealed class BatchHandler<TMessage>
+ public BatchHandler(bool trackBatches, IMessageFactory<TMessage> messageFactory)
{
- private readonly object _lock;
- private readonly bool _trackBatches;
- private readonly IMessageFactory<TMessage> _messageFactory;
- private readonly Queue<IMessage<TMessage>> _messages;
- private readonly LinkedList<Batch> _batches;
+ _lock = new object();
+ _trackBatches = trackBatches;
+ _messageFactory = messageFactory;
+ _messages = new Queue<IMessage<TMessage>>();
+ _batches = new LinkedList<Batch>();
+ }
- public BatchHandler(bool trackBatches, IMessageFactory<TMessage> messageFactory)
+ public IMessage<TMessage> Add(MessageIdData messageId, uint redeliveryCount, MessageMetadata metadata, ReadOnlySequence<byte> data)
+ {
+ var messages = new List<IMessage<TMessage>>(metadata.NumMessagesInBatch);
+
+ long index = 0;
+
+ for (var i = 0; i < metadata.NumMessagesInBatch; ++i)
{
- _lock = new object();
- _trackBatches = trackBatches;
- _messageFactory = messageFactory;
- _messages = new Queue<IMessage<TMessage>>();
- _batches = new LinkedList<Batch>();
+ var singleMetadataSize = data.ReadUInt32(index, true);
+ index += 4;
+ var singleMetadata = Serializer.Deserialize<SingleMessageMetadata>(data.Slice(index, singleMetadataSize));
+ index += singleMetadataSize;
+ var singleMessageId = new MessageId(messageId.LedgerId, messageId.EntryId, messageId.Partition, i);
+ var message = _messageFactory.Create(singleMessageId, redeliveryCount, data.Slice(index, singleMetadata.PayloadSize), metadata, singleMetadata);
+ messages.Add(message);
+ index += (uint) singleMetadata.PayloadSize;
}
- public IMessage<TMessage> Add(MessageIdData messageId, uint redeliveryCount, MessageMetadata metadata, ReadOnlySequence<byte> data)
+ lock (_lock)
{
- var messages = new List<IMessage<TMessage>>(metadata.NumMessagesInBatch);
+ if (_trackBatches)
+ _batches.AddLast(new Batch(messageId, metadata.NumMessagesInBatch));
- long index = 0;
-
- for (var i = 0; i < metadata.NumMessagesInBatch; ++i)
+ foreach (var message in messages)
{
- var singleMetadataSize = data.ReadUInt32(index, true);
- index += 4;
- var singleMetadata = Serializer.Deserialize<SingleMessageMetadata>(data.Slice(index, singleMetadataSize));
- index += singleMetadataSize;
- var singleMessageId = new MessageId(messageId.LedgerId, messageId.EntryId, messageId.Partition, i);
- var message = _messageFactory.Create(singleMessageId, redeliveryCount, data.Slice(index, singleMetadata.PayloadSize), metadata, singleMetadata);
- messages.Add(message);
- index += (uint) singleMetadata.PayloadSize;
+ _messages.Enqueue(message);
}
- lock (_lock)
- {
- if (_trackBatches)
- _batches.AddLast(new Batch(messageId, metadata.NumMessagesInBatch));
+ return _messages.Dequeue();
+ }
+ }
- foreach (var message in messages)
+ public IMessage<TMessage>? GetNext()
+ {
+ lock (_lock)
+ return _messages.Count == 0 ? null : _messages.Dequeue();
+ }
+
+ public void Clear()
+ {
+ lock (_lock)
+ {
+ _messages.Clear();
+ _batches.Clear();
+ }
+ }
+
+ public MessageIdData? Acknowledge(MessageIdData messageId)
+ {
+ lock (_lock)
+ {
+ foreach (var batch in _batches)
+ {
+ if (messageId.LedgerId != batch.MessageId.LedgerId ||
+ messageId.EntryId != batch.MessageId.EntryId ||
+ messageId.Partition != batch.MessageId.Partition)
+ continue;
+
+ batch.Acknowledge(messageId.BatchIndex);
+
+ if (batch.IsAcknowledged())
{
- _messages.Enqueue(message);
+ _batches.Remove(batch);
+ return batch.MessageId;
}
- return _messages.Dequeue();
+ break;
}
+
+ return null;
+ }
+ }
+
+ private sealed class Batch
+ {
+ private readonly BitArray _acknowledgementIndex;
+
+ public Batch(MessageIdData messageId, int numberOfMessages)
+ {
+ MessageId = messageId;
+ _acknowledgementIndex = new BitArray(numberOfMessages, false);
}
- public IMessage<TMessage>? GetNext()
- {
- lock (_lock)
- return _messages.Count == 0 ? null : _messages.Dequeue();
- }
+ public MessageIdData MessageId { get; }
- public void Clear()
+ public void Acknowledge(int batchIndex)
+ => _acknowledgementIndex.Set(batchIndex, true);
+
+ public bool IsAcknowledged()
{
- lock (_lock)
+ for (var i = 0; i < _acknowledgementIndex.Length; i++)
{
- _messages.Clear();
- _batches.Clear();
- }
- }
-
- public MessageIdData? Acknowledge(MessageIdData messageId)
- {
- lock (_lock)
- {
- foreach (var batch in _batches)
- {
- if (messageId.LedgerId != batch.MessageId.LedgerId ||
- messageId.EntryId != batch.MessageId.EntryId ||
- messageId.Partition != batch.MessageId.Partition)
- continue;
-
- batch.Acknowledge(messageId.BatchIndex);
-
- if (batch.IsAcknowledged())
- {
- _batches.Remove(batch);
- return batch.MessageId;
- }
-
- break;
- }
-
- return null;
- }
- }
-
- private sealed class Batch
- {
- private readonly BitArray _acknowledgementIndex;
-
- public Batch(MessageIdData messageId, int numberOfMessages)
- {
- MessageId = messageId;
- _acknowledgementIndex = new BitArray(numberOfMessages, false);
+ if (!_acknowledgementIndex[i])
+ return false;
}
- public MessageIdData MessageId { get; }
-
- public void Acknowledge(int batchIndex)
- => _acknowledgementIndex.Set(batchIndex, true);
-
- public bool IsAcknowledged()
- {
- for (var i = 0; i < _acknowledgementIndex.Length; i++)
- {
- if (!_acknowledgementIndex[i])
- return false;
- }
-
- return true;
- }
+ return true;
}
}
}
diff --git a/src/DotPulsar/Internal/CancelableCompletionSource.cs b/src/DotPulsar/Internal/CancelableCompletionSource.cs
index ff66a9a..f706427 100644
--- a/src/DotPulsar/Internal/CancelableCompletionSource.cs
+++ b/src/DotPulsar/Internal/CancelableCompletionSource.cs
@@ -12,35 +12,34 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+public sealed class CancelableCompletionSource<T> : IDisposable
{
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+ private readonly TaskCompletionSource<T> _source;
+ private CancellationTokenRegistration? _registration;
- public sealed class CancelableCompletionSource<T> : IDisposable
+ public CancelableCompletionSource()
+ => _source = new TaskCompletionSource<T>(TaskCreationOptions.RunContinuationsAsynchronously);
+
+ public void SetupCancellation(Action callback, CancellationToken token)
+ => _registration = token.Register(callback);
+
+ public void SetResult(T result)
+ => _ = _source.TrySetResult(result);
+
+ public void SetException(Exception exception)
+ => _ = _source.TrySetException(exception);
+
+ public Task<T> Task => _source.Task;
+
+ public void Dispose()
{
- private readonly TaskCompletionSource<T> _source;
- private CancellationTokenRegistration? _registration;
-
- public CancelableCompletionSource()
- => _source = new TaskCompletionSource<T>(TaskCreationOptions.RunContinuationsAsynchronously);
-
- public void SetupCancellation(Action callback, CancellationToken token)
- => _registration = token.Register(callback);
-
- public void SetResult(T result)
- => _ = _source.TrySetResult(result);
-
- public void SetException(Exception exception)
- => _ = _source.TrySetException(exception);
-
- public Task<T> Task => _source.Task;
-
- public void Dispose()
- {
- _ = _source.TrySetCanceled();
- _registration?.Dispose();
- }
+ _ = _source.TrySetCanceled();
+ _registration?.Dispose();
}
}
diff --git a/src/DotPulsar/Internal/Channel.cs b/src/DotPulsar/Internal/Channel.cs
index eb67755..361b838 100644
--- a/src/DotPulsar/Internal/Channel.cs
+++ b/src/DotPulsar/Internal/Channel.cs
@@ -12,101 +12,100 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using Abstractions;
+using Events;
+using System;
+using System.Threading;
+
+public sealed class Channel : IChannel
{
- using Abstractions;
- using Events;
- using System;
- using System.Threading;
+ private readonly Lock _senderLock;
+ private readonly Guid _correlationId;
+ private readonly IRegisterEvent _eventRegister;
+ private readonly IEnqueue<MessagePackage> _enqueue;
- public sealed class Channel : IChannel
+ public Channel(Guid correlationId, IRegisterEvent eventRegister, IEnqueue<MessagePackage> enqueue)
{
- private readonly Lock _senderLock;
- private readonly Guid _correlationId;
- private readonly IRegisterEvent _eventRegister;
- private readonly IEnqueue<MessagePackage> _enqueue;
+ _senderLock = new Lock();
+ _correlationId = correlationId;
+ _eventRegister = eventRegister;
+ _enqueue = enqueue;
+ }
- public Channel(Guid correlationId, IRegisterEvent eventRegister, IEnqueue<MessagePackage> enqueue)
+ public void Received(MessagePackage message)
+ {
+ try
{
- _senderLock = new Lock();
- _correlationId = correlationId;
- _eventRegister = eventRegister;
- _enqueue = enqueue;
+ _enqueue.Enqueue(message);
+ }
+ catch
+ {
+ // Ignore
+ }
+ }
+
+ public void Activated()
+ => _eventRegister.Register(new ChannelActivated(_correlationId));
+
+ public void ClosedByServer()
+ {
+ _senderLock.Disable();
+ _eventRegister.Register(new ChannelClosedByServer(_correlationId));
+ }
+
+ public void Connected()
+ => _eventRegister.Register(new ChannelConnected(_correlationId));
+
+ public void Deactivated()
+ => _eventRegister.Register(new ChannelDeactivated(_correlationId));
+
+ public void Disconnected()
+ {
+ _senderLock.Disable();
+ _eventRegister.Register(new ChannelDisconnected(_correlationId));
+ }
+
+ public void ReachedEndOfTopic()
+ => _eventRegister.Register(new ChannelReachedEndOfTopic(_correlationId));
+
+ public void Unsubscribed()
+ => _eventRegister.Register(new ChannelUnsubscribed(_correlationId));
+
+ public IDisposable SenderLock()
+ => _senderLock.Enter();
+
+ private sealed class Lock : IDisposable
+ {
+ private readonly object _lock;
+ private bool _canSend;
+
+ public Lock()
+ {
+ _lock = new object();
+ _canSend = true;
}
- public void Received(MessagePackage message)
+ public void Disable()
{
- try
- {
- _enqueue.Enqueue(message);
- }
- catch
- {
- // Ignore
- }
+ Monitor.Enter(_lock);
+ _canSend = false;
+ Monitor.Exit(_lock);
}
- public void Activated()
- => _eventRegister.Register(new ChannelActivated(_correlationId));
-
- public void ClosedByServer()
+ public IDisposable Enter()
{
- _senderLock.Disable();
- _eventRegister.Register(new ChannelClosedByServer(_correlationId));
+ Monitor.Enter(_lock);
+
+ if (_canSend)
+ return this;
+
+ Monitor.Exit(_lock);
+ throw new OperationCanceledException();
}
- public void Connected()
- => _eventRegister.Register(new ChannelConnected(_correlationId));
-
- public void Deactivated()
- => _eventRegister.Register(new ChannelDeactivated(_correlationId));
-
- public void Disconnected()
- {
- _senderLock.Disable();
- _eventRegister.Register(new ChannelDisconnected(_correlationId));
- }
-
- public void ReachedEndOfTopic()
- => _eventRegister.Register(new ChannelReachedEndOfTopic(_correlationId));
-
- public void Unsubscribed()
- => _eventRegister.Register(new ChannelUnsubscribed(_correlationId));
-
- public IDisposable SenderLock()
- => _senderLock.Enter();
-
- private sealed class Lock : IDisposable
- {
- private readonly object _lock;
- private bool _canSend;
-
- public Lock()
- {
- _lock = new object();
- _canSend = true;
- }
-
- public void Disable()
- {
- Monitor.Enter(_lock);
- _canSend = false;
- Monitor.Exit(_lock);
- }
-
- public IDisposable Enter()
- {
- Monitor.Enter(_lock);
-
- if (_canSend)
- return this;
-
- Monitor.Exit(_lock);
- throw new OperationCanceledException();
- }
-
- public void Dispose()
- => Monitor.Exit(_lock);
- }
+ public void Dispose()
+ => Monitor.Exit(_lock);
}
}
diff --git a/src/DotPulsar/Internal/ChannelManager.cs b/src/DotPulsar/Internal/ChannelManager.cs
index b28ba5b..afc3343 100644
--- a/src/DotPulsar/Internal/ChannelManager.cs
+++ b/src/DotPulsar/Internal/ChannelManager.cs
@@ -12,246 +12,245 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using Abstractions;
+using Extensions;
+using PulsarApi;
+using System;
+using System.Buffers;
+using System.Threading.Tasks;
+
+public sealed class ChannelManager : IDisposable
{
- using Abstractions;
- using Extensions;
- using PulsarApi;
- using System;
- using System.Buffers;
- using System.Threading.Tasks;
+ private readonly RequestResponseHandler _requestResponseHandler;
+ private readonly IdLookup<IChannel> _consumerChannels;
+ private readonly IdLookup<IChannel> _producerChannels;
+ private readonly EnumLookup<BaseCommand.Type, Action<BaseCommand>> _incoming;
- public sealed class ChannelManager : IDisposable
+ public ChannelManager()
{
- private readonly RequestResponseHandler _requestResponseHandler;
- private readonly IdLookup<IChannel> _consumerChannels;
- private readonly IdLookup<IChannel> _producerChannels;
- private readonly EnumLookup<BaseCommand.Type, Action<BaseCommand>> _incoming;
+ _requestResponseHandler = new RequestResponseHandler();
+ _consumerChannels = new IdLookup<IChannel>();
+ _producerChannels = new IdLookup<IChannel>();
+ _incoming = new EnumLookup<BaseCommand.Type, Action<BaseCommand>>(cmd => _requestResponseHandler.Incoming(cmd));
+ _incoming.Set(BaseCommand.Type.CloseConsumer, cmd => Incoming(cmd.CloseConsumer));
+ _incoming.Set(BaseCommand.Type.CloseProducer, cmd => Incoming(cmd.CloseProducer));
+ _incoming.Set(BaseCommand.Type.ActiveConsumerChange, cmd => Incoming(cmd.ActiveConsumerChange));
+ _incoming.Set(BaseCommand.Type.ReachedEndOfTopic, cmd => Incoming(cmd.ReachedEndOfTopic));
+ }
- public ChannelManager()
+ public bool HasChannels()
+ => !_consumerChannels.IsEmpty() || !_producerChannels.IsEmpty();
+
+ public Task<ProducerResponse> Outgoing(CommandProducer command, IChannel channel)
+ {
+ var producerId = _producerChannels.Add(channel);
+ command.ProducerId = producerId;
+ var response = _requestResponseHandler.Outgoing(command);
+
+ return response.ContinueWith(result =>
{
- _requestResponseHandler = new RequestResponseHandler();
- _consumerChannels = new IdLookup<IChannel>();
- _producerChannels = new IdLookup<IChannel>();
- _incoming = new EnumLookup<BaseCommand.Type, Action<BaseCommand>>(cmd => _requestResponseHandler.Incoming(cmd));
- _incoming.Set(BaseCommand.Type.CloseConsumer, cmd => Incoming(cmd.CloseConsumer));
- _incoming.Set(BaseCommand.Type.CloseProducer, cmd => Incoming(cmd.CloseProducer));
- _incoming.Set(BaseCommand.Type.ActiveConsumerChange, cmd => Incoming(cmd.ActiveConsumerChange));
- _incoming.Set(BaseCommand.Type.ReachedEndOfTopic, cmd => Incoming(cmd.ReachedEndOfTopic));
- }
-
- public bool HasChannels()
- => !_consumerChannels.IsEmpty() || !_producerChannels.IsEmpty();
-
- public Task<ProducerResponse> Outgoing(CommandProducer command, IChannel channel)
- {
- var producerId = _producerChannels.Add(channel);
- command.ProducerId = producerId;
- var response = _requestResponseHandler.Outgoing(command);
-
- return response.ContinueWith(result =>
+ if (result.Result.CommandType == BaseCommand.Type.Error)
{
- if (result.Result.CommandType == BaseCommand.Type.Error)
- {
- _ = _producerChannels.Remove(producerId);
- result.Result.Error.Throw();
- }
-
- channel.Connected();
-
- return new ProducerResponse(producerId, result.Result.ProducerSuccess.ProducerName);
- }, TaskContinuationOptions.OnlyOnRanToCompletion);
- }
-
- public Task<SubscribeResponse> Outgoing(CommandSubscribe command, IChannel channel)
- {
- var consumerId = _consumerChannels.Add(channel);
- command.ConsumerId = consumerId;
- var response = _requestResponseHandler.Outgoing(command);
-
- return response.ContinueWith(result =>
- {
- if (result.Result.CommandType == BaseCommand.Type.Error)
- {
- _ = _consumerChannels.Remove(consumerId);
- result.Result.Error.Throw();
- }
-
- channel.Connected();
-
- return new SubscribeResponse(consumerId);
- }, TaskContinuationOptions.OnlyOnRanToCompletion);
- }
-
- public Task<BaseCommand> Outgoing(CommandCloseConsumer command)
- {
- var consumerId = command.ConsumerId;
-
- Task<BaseCommand> response;
-
- using (TakeConsumerSenderLock(consumerId))
- {
- response = _requestResponseHandler.Outgoing(command);
+ _ = _producerChannels.Remove(producerId);
+ result.Result.Error.Throw();
}
- _ = response.ContinueWith(result =>
- {
- if (result.Result.CommandType == BaseCommand.Type.Success)
- _ = _consumerChannels.Remove(consumerId);
- }, TaskContinuationOptions.OnlyOnRanToCompletion);
+ channel.Connected();
- return response;
- }
+ return new ProducerResponse(producerId, result.Result.ProducerSuccess.ProducerName);
+ }, TaskContinuationOptions.OnlyOnRanToCompletion);
+ }
- public Task<BaseCommand> Outgoing(CommandCloseProducer command)
+ public Task<SubscribeResponse> Outgoing(CommandSubscribe command, IChannel channel)
+ {
+ var consumerId = _consumerChannels.Add(channel);
+ command.ConsumerId = consumerId;
+ var response = _requestResponseHandler.Outgoing(command);
+
+ return response.ContinueWith(result =>
{
- var producerId = command.ProducerId;
-
- Task<BaseCommand> response;
-
- using (TakeProducerSenderLock(producerId))
+ if (result.Result.CommandType == BaseCommand.Type.Error)
{
- response = _requestResponseHandler.Outgoing(command);
+ _ = _consumerChannels.Remove(consumerId);
+ result.Result.Error.Throw();
}
- _ = response.ContinueWith(result =>
- {
- if (result.Result.CommandType == BaseCommand.Type.Success)
- _ = _producerChannels.Remove(producerId);
- }, TaskContinuationOptions.OnlyOnRanToCompletion);
+ channel.Connected();
- return response;
- }
+ return new SubscribeResponse(consumerId);
+ }, TaskContinuationOptions.OnlyOnRanToCompletion);
+ }
- public Task<BaseCommand> Outgoing(CommandUnsubscribe command)
+ public Task<BaseCommand> Outgoing(CommandCloseConsumer command)
+ {
+ var consumerId = command.ConsumerId;
+
+ Task<BaseCommand> response;
+
+ using (TakeConsumerSenderLock(consumerId))
{
- var consumerId = command.ConsumerId;
-
- Task<BaseCommand> response;
-
- using (TakeConsumerSenderLock(consumerId))
- {
- response = _requestResponseHandler.Outgoing(command);
- }
-
- _ = response.ContinueWith(result =>
- {
- if (result.Result.CommandType == BaseCommand.Type.Success)
- _consumerChannels.Remove(consumerId)?.Unsubscribed();
- }, TaskContinuationOptions.OnlyOnRanToCompletion);
-
- return response;
+ response = _requestResponseHandler.Outgoing(command);
}
- public Task<BaseCommand> Outgoing(CommandSend command)
+ _ = response.ContinueWith(result =>
{
- using (TakeProducerSenderLock(command.ProducerId))
- {
- return _requestResponseHandler.Outgoing(command);
- }
- }
+ if (result.Result.CommandType == BaseCommand.Type.Success)
+ _ = _consumerChannels.Remove(consumerId);
+ }, TaskContinuationOptions.OnlyOnRanToCompletion);
- public Task<BaseCommand> Outgoing(CommandGetOrCreateSchema command)
- => _requestResponseHandler.Outgoing(command);
+ return response;
+ }
- public Task<BaseCommand> Outgoing(CommandConnect command)
- => _requestResponseHandler.Outgoing(command);
+ public Task<BaseCommand> Outgoing(CommandCloseProducer command)
+ {
+ var producerId = command.ProducerId;
- public Task<BaseCommand> Outgoing(CommandLookupTopic command)
- => _requestResponseHandler.Outgoing(command);
+ Task<BaseCommand> response;
- public Task<BaseCommand> Outgoing(CommandPartitionedTopicMetadata command)
- => _requestResponseHandler.Outgoing(command);
-
- public Task<BaseCommand> Outgoing(CommandSeek command)
+ using (TakeProducerSenderLock(producerId))
{
- using (TakeConsumerSenderLock(command.ConsumerId))
- {
- return _requestResponseHandler.Outgoing(command);
- }
+ response = _requestResponseHandler.Outgoing(command);
}
- public Task<BaseCommand> Outgoing(CommandGetLastMessageId command)
+ _ = response.ContinueWith(result =>
{
- using (TakeConsumerSenderLock(command.ConsumerId))
- {
- return _requestResponseHandler.Outgoing(command);
- }
- }
+ if (result.Result.CommandType == BaseCommand.Type.Success)
+ _ = _producerChannels.Remove(producerId);
+ }, TaskContinuationOptions.OnlyOnRanToCompletion);
- public void Incoming(BaseCommand command)
- => _incoming.Get(command.CommandType)(command);
+ return response;
+ }
- public void Incoming(CommandMessage command, ReadOnlySequence<byte> data)
- => _consumerChannels[command.ConsumerId]?.Received(new MessagePackage(command.MessageId, command.RedeliveryCount, data));
+ public Task<BaseCommand> Outgoing(CommandUnsubscribe command)
+ {
+ var consumerId = command.ConsumerId;
- public void Dispose()
+ Task<BaseCommand> response;
+
+ using (TakeConsumerSenderLock(consumerId))
{
- _requestResponseHandler.Dispose();
-
- foreach (var channel in _consumerChannels.RemoveAll())
- channel.Disconnected();
-
- foreach (var channel in _producerChannels.RemoveAll())
- channel.Disconnected();
+ response = _requestResponseHandler.Outgoing(command);
}
- private void Incoming(CommandReachedEndOfTopic command)
- => _consumerChannels[command.ConsumerId]?.ReachedEndOfTopic();
-
- private void Incoming(CommandCloseConsumer command)
+ _ = response.ContinueWith(result =>
{
- var channel = _consumerChannels[command.ConsumerId];
+ if (result.Result.CommandType == BaseCommand.Type.Success)
+ _consumerChannels.Remove(consumerId)?.Unsubscribed();
+ }, TaskContinuationOptions.OnlyOnRanToCompletion);
- if (channel is null)
- return;
+ return response;
+ }
- _ = _consumerChannels.Remove(command.ConsumerId);
- _requestResponseHandler.Incoming(command);
- channel.ClosedByServer();
- }
-
- private void Incoming(CommandCloseProducer command)
+ public Task<BaseCommand> Outgoing(CommandSend command)
+ {
+ using (TakeProducerSenderLock(command.ProducerId))
{
- var channel = _producerChannels[command.ProducerId];
-
- if (channel is null)
- return;
-
- _ = _producerChannels.Remove(command.ProducerId);
- _requestResponseHandler.Incoming(command);
- channel.ClosedByServer();
+ return _requestResponseHandler.Outgoing(command);
}
+ }
- private void Incoming(CommandActiveConsumerChange command)
+ public Task<BaseCommand> Outgoing(CommandGetOrCreateSchema command)
+ => _requestResponseHandler.Outgoing(command);
+
+ public Task<BaseCommand> Outgoing(CommandConnect command)
+ => _requestResponseHandler.Outgoing(command);
+
+ public Task<BaseCommand> Outgoing(CommandLookupTopic command)
+ => _requestResponseHandler.Outgoing(command);
+
+ public Task<BaseCommand> Outgoing(CommandPartitionedTopicMetadata command)
+ => _requestResponseHandler.Outgoing(command);
+
+ public Task<BaseCommand> Outgoing(CommandSeek command)
+ {
+ using (TakeConsumerSenderLock(command.ConsumerId))
{
- var channel = _consumerChannels[command.ConsumerId];
-
- if (channel is null)
- return;
-
- if (command.IsActive)
- channel.Activated();
- else
- channel.Deactivated();
+ return _requestResponseHandler.Outgoing(command);
}
+ }
- private IDisposable TakeConsumerSenderLock(ulong consumerId)
+ public Task<BaseCommand> Outgoing(CommandGetLastMessageId command)
+ {
+ using (TakeConsumerSenderLock(command.ConsumerId))
{
- var channel = _consumerChannels[consumerId];
- if (channel is null)
- throw new OperationCanceledException();
-
- return channel.SenderLock();
+ return _requestResponseHandler.Outgoing(command);
}
+ }
- private IDisposable TakeProducerSenderLock(ulong producerId)
- {
- var channel = _producerChannels[producerId];
- if (channel is null)
- throw new OperationCanceledException();
+ public void Incoming(BaseCommand command)
+ => _incoming.Get(command.CommandType)(command);
- return channel.SenderLock();
- }
+ public void Incoming(CommandMessage command, ReadOnlySequence<byte> data)
+ => _consumerChannels[command.ConsumerId]?.Received(new MessagePackage(command.MessageId, command.RedeliveryCount, data));
+
+ public void Dispose()
+ {
+ _requestResponseHandler.Dispose();
+
+ foreach (var channel in _consumerChannels.RemoveAll())
+ channel.Disconnected();
+
+ foreach (var channel in _producerChannels.RemoveAll())
+ channel.Disconnected();
+ }
+
+ private void Incoming(CommandReachedEndOfTopic command)
+ => _consumerChannels[command.ConsumerId]?.ReachedEndOfTopic();
+
+ private void Incoming(CommandCloseConsumer command)
+ {
+ var channel = _consumerChannels[command.ConsumerId];
+
+ if (channel is null)
+ return;
+
+ _ = _consumerChannels.Remove(command.ConsumerId);
+ _requestResponseHandler.Incoming(command);
+ channel.ClosedByServer();
+ }
+
+ private void Incoming(CommandCloseProducer command)
+ {
+ var channel = _producerChannels[command.ProducerId];
+
+ if (channel is null)
+ return;
+
+ _ = _producerChannels.Remove(command.ProducerId);
+ _requestResponseHandler.Incoming(command);
+ channel.ClosedByServer();
+ }
+
+ private void Incoming(CommandActiveConsumerChange command)
+ {
+ var channel = _consumerChannels[command.ConsumerId];
+
+ if (channel is null)
+ return;
+
+ if (command.IsActive)
+ channel.Activated();
+ else
+ channel.Deactivated();
+ }
+
+ private IDisposable TakeConsumerSenderLock(ulong consumerId)
+ {
+ var channel = _consumerChannels[consumerId];
+ if (channel is null)
+ throw new OperationCanceledException();
+
+ return channel.SenderLock();
+ }
+
+ private IDisposable TakeProducerSenderLock(ulong producerId)
+ {
+ var channel = _producerChannels[producerId];
+ if (channel is null)
+ throw new OperationCanceledException();
+
+ return channel.SenderLock();
}
}
diff --git a/src/DotPulsar/Internal/ChannelState.cs b/src/DotPulsar/Internal/ChannelState.cs
index 28e7507..ccac012 100644
--- a/src/DotPulsar/Internal/ChannelState.cs
+++ b/src/DotPulsar/Internal/ChannelState.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+public enum ChannelState : byte
{
- public enum ChannelState : byte
- {
- ClosedByServer,
- Connected,
- Disconnected,
- ReachedEndOfTopic,
- Active,
- Inactive,
- Unsubscribed
- }
+ ClosedByServer,
+ Connected,
+ Disconnected,
+ ReachedEndOfTopic,
+ Active,
+ Inactive,
+ Unsubscribed
}
diff --git a/src/DotPulsar/Internal/ChunkingPipeline.cs b/src/DotPulsar/Internal/ChunkingPipeline.cs
index 2768f69..3528964 100644
--- a/src/DotPulsar/Internal/ChunkingPipeline.cs
+++ b/src/DotPulsar/Internal/ChunkingPipeline.cs
@@ -12,99 +12,98 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using System;
+using System.Buffers;
+using System.IO;
+using System.Threading.Tasks;
+
+public sealed class ChunkingPipeline
{
- using System;
- using System.Buffers;
- using System.IO;
- using System.Threading.Tasks;
+ private readonly Stream _stream;
+ private readonly int _chunkSize;
+ private readonly byte[] _buffer;
+ private int _bufferCount;
- public sealed class ChunkingPipeline
+ public ChunkingPipeline(Stream stream, int chunkSize)
{
- private readonly Stream _stream;
- private readonly int _chunkSize;
- private readonly byte[] _buffer;
- private int _bufferCount;
+ _stream = stream;
+ _chunkSize = chunkSize;
+ _buffer = new byte[_chunkSize];
+ }
- public ChunkingPipeline(Stream stream, int chunkSize)
+ private void CopyToBuffer(ReadOnlySequence<byte> sequence) => sequence.CopyTo(_buffer.AsSpan());
+
+ private void CopyToBuffer(ReadOnlyMemory<byte> memory) => memory.CopyTo(_buffer.AsMemory(_bufferCount));
+
+ public async ValueTask Send(ReadOnlySequence<byte> sequence)
+ {
+ var sequenceLength = sequence.Length;
+
+ if (sequenceLength <= _chunkSize)
{
- _stream = stream;
- _chunkSize = chunkSize;
- _buffer = new byte[_chunkSize];
- }
-
- private void CopyToBuffer(ReadOnlySequence<byte> sequence) => sequence.CopyTo(_buffer.AsSpan());
-
- private void CopyToBuffer(ReadOnlyMemory<byte> memory) => memory.CopyTo(_buffer.AsMemory(_bufferCount));
-
- public async ValueTask Send(ReadOnlySequence<byte> sequence)
- {
- var sequenceLength = sequence.Length;
-
- if (sequenceLength <= _chunkSize)
- {
- CopyToBuffer(sequence);
- _bufferCount = (int) sequenceLength;
- await SendBuffer().ConfigureAwait(false);
- return;
- }
-
- var enumerator = sequence.GetEnumerator();
- var hasNext = true;
-
- while (hasNext)
- {
- var current = enumerator.Current;
- var currentLength = current.Length;
- hasNext = enumerator.MoveNext();
-
- if (currentLength > _chunkSize)
- {
- await Send(current).ConfigureAwait(false);
- continue;
- }
-
- var total = currentLength + _bufferCount;
-
- if (total > _chunkSize)
- await SendBuffer().ConfigureAwait(false);
-
- if (_bufferCount != 0 || (hasNext && enumerator.Current.Length + total <= _chunkSize))
- {
- CopyToBuffer(current);
- _bufferCount = total;
- continue;
- }
-
- await Send(current).ConfigureAwait(false);
- }
-
+ CopyToBuffer(sequence);
+ _bufferCount = (int) sequenceLength;
await SendBuffer().ConfigureAwait(false);
+ return;
}
- private async ValueTask SendBuffer()
+ var enumerator = sequence.GetEnumerator();
+ var hasNext = true;
+
+ while (hasNext)
{
- if (_bufferCount != 0)
+ var current = enumerator.Current;
+ var currentLength = current.Length;
+ hasNext = enumerator.MoveNext();
+
+ if (currentLength > _chunkSize)
{
+ await Send(current).ConfigureAwait(false);
+ continue;
+ }
+
+ var total = currentLength + _bufferCount;
+
+ if (total > _chunkSize)
+ await SendBuffer().ConfigureAwait(false);
+
+ if (_bufferCount != 0 || (hasNext && enumerator.Current.Length + total <= _chunkSize))
+ {
+ CopyToBuffer(current);
+ _bufferCount = total;
+ continue;
+ }
+
+ await Send(current).ConfigureAwait(false);
+ }
+
+ await SendBuffer().ConfigureAwait(false);
+ }
+
+ private async ValueTask SendBuffer()
+ {
+ if (_bufferCount != 0)
+ {
#if NETSTANDARD2_0
- await _stream.WriteAsync(_buffer, 0, _bufferCount).ConfigureAwait(false);
+ await _stream.WriteAsync(_buffer, 0, _bufferCount).ConfigureAwait(false);
#else
await _stream.WriteAsync(_buffer.AsMemory(0, _bufferCount)).ConfigureAwait(false);
#endif
- _bufferCount = 0;
- }
+ _bufferCount = 0;
}
+ }
- private async ValueTask Send(ReadOnlyMemory<byte> memory)
- {
- await SendBuffer().ConfigureAwait(false);
+ private async ValueTask Send(ReadOnlyMemory<byte> memory)
+ {
+ await SendBuffer().ConfigureAwait(false);
#if NETSTANDARD2_0
- var data = memory.ToArray();
- await _stream.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
+ var data = memory.ToArray();
+ await _stream.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
#else
await _stream.WriteAsync(memory).ConfigureAwait(false);
#endif
- }
}
}
diff --git a/src/DotPulsar/Internal/Compression/CompressionFactories.cs b/src/DotPulsar/Internal/Compression/CompressionFactories.cs
index a2da330..b9eb1ef 100644
--- a/src/DotPulsar/Internal/Compression/CompressionFactories.cs
+++ b/src/DotPulsar/Internal/Compression/CompressionFactories.cs
@@ -12,45 +12,44 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Compression
+namespace DotPulsar.Internal.Compression;
+
+using DotPulsar.Internal.Abstractions;
+using System.Collections.Generic;
+
+public static class CompressionFactories
{
- using DotPulsar.Internal.Abstractions;
- using System.Collections.Generic;
+ private static readonly List<ICompressorFactory> _compressorFactories;
+ private static readonly List<IDecompressorFactory> _decompressorFactories;
- public static class CompressionFactories
+ static CompressionFactories()
{
- private static readonly List<ICompressorFactory> _compressorFactories;
- private static readonly List<IDecompressorFactory> _decompressorFactories;
-
- static CompressionFactories()
- {
- _compressorFactories = new List<ICompressorFactory>();
- _decompressorFactories = new List<IDecompressorFactory>();
+ _compressorFactories = new List<ICompressorFactory>();
+ _decompressorFactories = new List<IDecompressorFactory>();
- if (Lz4Compression.TryLoading(out ICompressorFactory? compressorFactory, out IDecompressorFactory? decompressorFactory))
- Add(compressorFactory, decompressorFactory);
+ if (Lz4Compression.TryLoading(out ICompressorFactory? compressorFactory, out IDecompressorFactory? decompressorFactory))
+ Add(compressorFactory, decompressorFactory);
- if (SnappyCompression.TryLoading(out compressorFactory, out decompressorFactory))
- Add(compressorFactory, decompressorFactory);
+ if (SnappyCompression.TryLoading(out compressorFactory, out decompressorFactory))
+ Add(compressorFactory, decompressorFactory);
- if (ZlibCompression.TryLoading(out compressorFactory, out decompressorFactory))
- Add(compressorFactory, decompressorFactory);
+ if (ZlibCompression.TryLoading(out compressorFactory, out decompressorFactory))
+ Add(compressorFactory, decompressorFactory);
- if (ZstdCompression.TryLoading(out compressorFactory, out decompressorFactory))
- Add(compressorFactory, decompressorFactory);
- }
-
- private static void Add(ICompressorFactory? compressorFactory, IDecompressorFactory? decompressorFactory)
- {
- _compressorFactories.Add(compressorFactory!);
- _decompressorFactories.Add(decompressorFactory!);
- }
-
- public static IEnumerable<ICompressorFactory> CompressorFactories()
- => _compressorFactories;
-
- public static IEnumerable<IDecompressorFactory> DecompressorFactories()
- => _decompressorFactories;
+ if (ZstdCompression.TryLoading(out compressorFactory, out decompressorFactory))
+ Add(compressorFactory, decompressorFactory);
}
+
+ private static void Add(ICompressorFactory? compressorFactory, IDecompressorFactory? decompressorFactory)
+ {
+ _compressorFactories.Add(compressorFactory!);
+ _decompressorFactories.Add(decompressorFactory!);
+ }
+
+ public static IEnumerable<ICompressorFactory> CompressorFactories()
+ => _compressorFactories;
+
+ public static IEnumerable<IDecompressorFactory> DecompressorFactories()
+ => _decompressorFactories;
}
diff --git a/src/DotPulsar/Internal/Compression/Compressor.cs b/src/DotPulsar/Internal/Compression/Compressor.cs
index 51ffaf9..5449f3c 100644
--- a/src/DotPulsar/Internal/Compression/Compressor.cs
+++ b/src/DotPulsar/Internal/Compression/Compressor.cs
@@ -12,30 +12,29 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Compression
+namespace DotPulsar.Internal.Compression;
+
+using DotPulsar.Internal.Abstractions;
+using System;
+using System.Buffers;
+
+public sealed class Compressor : ICompress
{
- using DotPulsar.Internal.Abstractions;
- using System;
- using System.Buffers;
+ private readonly IDisposable? _disposable;
+ private readonly Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> _compress;
- public sealed class Compressor : ICompress
+ public Compressor(Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> compress, IDisposable? disposable = null)
{
- private readonly IDisposable? _disposable;
- private readonly Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> _compress;
-
- public Compressor(Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> compress, IDisposable? disposable = null)
- {
- _disposable = disposable;
- _compress = compress;
- }
-
- public Compressor(Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> compress)
- => _compress = compress;
-
- public ReadOnlySequence<byte> Compress(ReadOnlySequence<byte> data)
- => _compress(data);
-
- public void Dispose()
- => _disposable?.Dispose();
+ _disposable = disposable;
+ _compress = compress;
}
+
+ public Compressor(Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> compress)
+ => _compress = compress;
+
+ public ReadOnlySequence<byte> Compress(ReadOnlySequence<byte> data)
+ => _compress(data);
+
+ public void Dispose()
+ => _disposable?.Dispose();
}
diff --git a/src/DotPulsar/Internal/Compression/CompressorFactory.cs b/src/DotPulsar/Internal/Compression/CompressorFactory.cs
index 230e1ff..1a8a9e4 100644
--- a/src/DotPulsar/Internal/Compression/CompressorFactory.cs
+++ b/src/DotPulsar/Internal/Compression/CompressorFactory.cs
@@ -12,25 +12,24 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Compression
+namespace DotPulsar.Internal.Compression;
+
+using DotPulsar.Internal.Abstractions;
+using DotPulsar.Internal.PulsarApi;
+using System;
+
+public sealed class CompressorFactory : ICompressorFactory
{
- using DotPulsar.Internal.Abstractions;
- using DotPulsar.Internal.PulsarApi;
- using System;
+ private readonly Func<ICompress> _create;
- public sealed class CompressorFactory : ICompressorFactory
+ public CompressorFactory(CompressionType compressionType, Func<ICompress> create)
{
- private readonly Func<ICompress> _create;
-
- public CompressorFactory(CompressionType compressionType, Func<ICompress> create)
- {
- CompressionType = compressionType;
- _create = create;
- }
-
- public CompressionType CompressionType { get; }
-
- public ICompress Create()
- => _create();
+ CompressionType = compressionType;
+ _create = create;
}
+
+ public CompressionType CompressionType { get; }
+
+ public ICompress Create()
+ => _create();
}
diff --git a/src/DotPulsar/Internal/Compression/Decompressor.cs b/src/DotPulsar/Internal/Compression/Decompressor.cs
index eddba6c..dc6a42c 100644
--- a/src/DotPulsar/Internal/Compression/Decompressor.cs
+++ b/src/DotPulsar/Internal/Compression/Decompressor.cs
@@ -12,27 +12,26 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Compression
+namespace DotPulsar.Internal.Compression;
+
+using DotPulsar.Internal.Abstractions;
+using System;
+using System.Buffers;
+
+public sealed class Decompressor : IDecompress
{
- using DotPulsar.Internal.Abstractions;
- using System;
- using System.Buffers;
+ private readonly IDisposable? _disposable;
+ private readonly Func<ReadOnlySequence<byte>, int, ReadOnlySequence<byte>> _decompress;
- public sealed class Decompressor : IDecompress
+ public Decompressor(Func<ReadOnlySequence<byte>, int, ReadOnlySequence<byte>> decompress, IDisposable? disposable = null)
{
- private readonly IDisposable? _disposable;
- private readonly Func<ReadOnlySequence<byte>, int, ReadOnlySequence<byte>> _decompress;
-
- public Decompressor(Func<ReadOnlySequence<byte>, int, ReadOnlySequence<byte>> decompress, IDisposable? disposable = null)
- {
- _disposable = disposable;
- _decompress = decompress;
- }
-
- public ReadOnlySequence<byte> Decompress(ReadOnlySequence<byte> data, int decompressedSize)
- => _decompress(data, decompressedSize);
-
- public void Dispose()
- => _disposable?.Dispose();
+ _disposable = disposable;
+ _decompress = decompress;
}
+
+ public ReadOnlySequence<byte> Decompress(ReadOnlySequence<byte> data, int decompressedSize)
+ => _decompress(data, decompressedSize);
+
+ public void Dispose()
+ => _disposable?.Dispose();
}
diff --git a/src/DotPulsar/Internal/Compression/DecompressorFactory.cs b/src/DotPulsar/Internal/Compression/DecompressorFactory.cs
index dc2b6da..6ce0388 100644
--- a/src/DotPulsar/Internal/Compression/DecompressorFactory.cs
+++ b/src/DotPulsar/Internal/Compression/DecompressorFactory.cs
@@ -12,25 +12,24 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Compression
+namespace DotPulsar.Internal.Compression;
+
+using DotPulsar.Internal.Abstractions;
+using DotPulsar.Internal.PulsarApi;
+using System;
+
+public sealed class DecompressorFactory : IDecompressorFactory
{
- using DotPulsar.Internal.Abstractions;
- using DotPulsar.Internal.PulsarApi;
- using System;
+ private readonly Func<IDecompress> _create;
- public sealed class DecompressorFactory : IDecompressorFactory
+ public DecompressorFactory(CompressionType compressionType, Func<IDecompress> create)
{
- private readonly Func<IDecompress> _create;
-
- public DecompressorFactory(CompressionType compressionType, Func<IDecompress> create)
- {
- CompressionType = compressionType;
- _create = create;
- }
-
- public CompressionType CompressionType { get; }
-
- public IDecompress Create()
- => _create();
+ CompressionType = compressionType;
+ _create = create;
}
+
+ public CompressionType CompressionType { get; }
+
+ public IDecompress Create()
+ => _create();
}
diff --git a/src/DotPulsar/Internal/Compression/Lz4Compression.cs b/src/DotPulsar/Internal/Compression/Lz4Compression.cs
index d528fb7..4809484 100644
--- a/src/DotPulsar/Internal/Compression/Lz4Compression.cs
+++ b/src/DotPulsar/Internal/Compression/Lz4Compression.cs
@@ -12,193 +12,192 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Compression
+namespace DotPulsar.Internal.Compression;
+
+using DotPulsar.Exceptions;
+using DotPulsar.Internal.Abstractions;
+using System;
+using System.Buffers;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+
+public static class Lz4Compression
{
- using DotPulsar.Exceptions;
- using DotPulsar.Internal.Abstractions;
- using System;
- using System.Buffers;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
+ public delegate int Decode(byte[] source, int sourceOffset, int sourceLength, byte[] target, int targetOffset, int targetLength);
+ public delegate int Encode(byte[] source, int sourceOffset, int sourceLength, byte[] target, int targetOffset, int targetLength, int level);
+ public delegate int MaximumOutputSize(int length);
- public static class Lz4Compression
+ public static bool TryLoading(out ICompressorFactory? compressorFactory, out IDecompressorFactory? decompressorFactory)
{
- public delegate int Decode(byte[] source, int sourceOffset, int sourceLength, byte[] target, int targetOffset, int targetLength);
- public delegate int Encode(byte[] source, int sourceOffset, int sourceLength, byte[] target, int targetOffset, int targetLength, int level);
- public delegate int MaximumOutputSize(int length);
-
- public static bool TryLoading(out ICompressorFactory? compressorFactory, out IDecompressorFactory? decompressorFactory)
+ try
{
- try
- {
- var assembly = Assembly.Load("K4os.Compression.LZ4");
+ var assembly = Assembly.Load("K4os.Compression.LZ4");
- var definedTypes = assembly.DefinedTypes.ToArray();
+ var definedTypes = assembly.DefinedTypes.ToArray();
- var lz4Codec = FindLZ4Codec(definedTypes);
- var lz4Level = FindLZ4Level(definedTypes);
+ var lz4Codec = FindLZ4Codec(definedTypes);
+ var lz4Level = FindLZ4Level(definedTypes);
- var methods = lz4Codec.GetMethods(BindingFlags.Public | BindingFlags.Static);
+ var methods = lz4Codec.GetMethods(BindingFlags.Public | BindingFlags.Static);
- var decode = FindDecode(methods);
- var encode = FindEncode(methods, lz4Level);
- var maximumOutputSize = FindMaximumOutputSize(methods);
+ var decode = FindDecode(methods);
+ var encode = FindEncode(methods, lz4Level);
+ var maximumOutputSize = FindMaximumOutputSize(methods);
- compressorFactory = new CompressorFactory(PulsarApi.CompressionType.Lz4, () => new Compressor(CreateCompressor(encode, maximumOutputSize)));
- decompressorFactory = new DecompressorFactory(PulsarApi.CompressionType.Lz4, () => new Decompressor(CreateDecompressor(decode)));
- return true;
- }
- catch
- {
- // Ignore
- }
-
- compressorFactory = null;
- decompressorFactory = null;
-
- return false;
+ compressorFactory = new CompressorFactory(PulsarApi.CompressionType.Lz4, () => new Compressor(CreateCompressor(encode, maximumOutputSize)));
+ decompressorFactory = new DecompressorFactory(PulsarApi.CompressionType.Lz4, () => new Decompressor(CreateDecompressor(decode)));
+ return true;
+ }
+ catch
+ {
+ // Ignore
}
- private static TypeInfo FindLZ4Codec(IEnumerable<TypeInfo> types)
+ compressorFactory = null;
+ decompressorFactory = null;
+
+ return false;
+ }
+
+ private static TypeInfo FindLZ4Codec(IEnumerable<TypeInfo> types)
+ {
+ const string fullName = "K4os.Compression.LZ4.LZ4Codec";
+
+ foreach (var type in types)
{
- const string fullName = "K4os.Compression.LZ4.LZ4Codec";
+ if (type.FullName is null || !type.FullName.Equals(fullName))
+ continue;
- foreach (var type in types)
- {
- if (type.FullName is null || !type.FullName.Equals(fullName))
- continue;
+ if (type.IsPublic && type.IsClass && type.IsAbstract && type.IsSealed)
+ return type;
- if (type.IsPublic && type.IsClass && type.IsAbstract && type.IsSealed)
- return type;
-
- break;
- }
-
- throw new Exception($"{fullName} as a public and static class was not found");
+ break;
}
- private static TypeInfo FindLZ4Level(IEnumerable<TypeInfo> types)
+ throw new Exception($"{fullName} as a public and static class was not found");
+ }
+
+ private static TypeInfo FindLZ4Level(IEnumerable<TypeInfo> types)
+ {
+ const string fullName = "K4os.Compression.LZ4.LZ4Level";
+
+ foreach (var type in types)
{
- const string fullName = "K4os.Compression.LZ4.LZ4Level";
+ if (type.FullName is null || !type.FullName.Equals(fullName))
+ continue;
- foreach (var type in types)
- {
- if (type.FullName is null || !type.FullName.Equals(fullName))
- continue;
+ if (type.IsPublic && type.IsEnum && Enum.GetUnderlyingType(type) == typeof(int))
+ return type;
- if (type.IsPublic && type.IsEnum && Enum.GetUnderlyingType(type) == typeof(int))
- return type;
-
- break;
- }
-
- throw new Exception($"{fullName} as a public enum with an int backing was not found");
+ break;
}
- private static Decode FindDecode(MethodInfo[] methods)
+ throw new Exception($"{fullName} as a public enum with an int backing was not found");
+ }
+
+ private static Decode FindDecode(MethodInfo[] methods)
+ {
+ const string name = "Decode";
+
+ foreach (var method in methods)
{
- const string name = "Decode";
+ if (method.Name != name || method.ReturnType != typeof(int))
+ continue;
- foreach (var method in methods)
- {
- if (method.Name != name || method.ReturnType != typeof(int))
- continue;
+ var parameters = method.GetParameters();
+ if (parameters.Length != 6)
+ continue;
- var parameters = method.GetParameters();
- if (parameters.Length != 6)
- continue;
+ if (parameters[0].ParameterType != typeof(byte[]) ||
+ parameters[1].ParameterType != typeof(int) ||
+ parameters[2].ParameterType != typeof(int) ||
+ parameters[3].ParameterType != typeof(byte[]) ||
+ parameters[4].ParameterType != typeof(int) ||
+ parameters[5].ParameterType != typeof(int))
+ continue;
- if (parameters[0].ParameterType != typeof(byte[]) ||
- parameters[1].ParameterType != typeof(int) ||
- parameters[2].ParameterType != typeof(int) ||
- parameters[3].ParameterType != typeof(byte[]) ||
- parameters[4].ParameterType != typeof(int) ||
- parameters[5].ParameterType != typeof(int))
- continue;
-
- return (Decode) method.CreateDelegate(typeof(Decode));
- }
-
- throw new Exception($"A method with the name '{name}' matching the delegate was not found");
+ return (Decode) method.CreateDelegate(typeof(Decode));
}
- private static Encode FindEncode(MethodInfo[] methods, Type lz4Level)
+ throw new Exception($"A method with the name '{name}' matching the delegate was not found");
+ }
+
+ private static Encode FindEncode(MethodInfo[] methods, Type lz4Level)
+ {
+ const string name = "Encode";
+
+ foreach (var method in methods)
{
- const string name = "Encode";
+ if (method.Name != name || method.ReturnType != typeof(int))
+ continue;
- foreach (var method in methods)
- {
- if (method.Name != name || method.ReturnType != typeof(int))
- continue;
+ var parameters = method.GetParameters();
+ if (parameters.Length != 7)
+ continue;
- var parameters = method.GetParameters();
- if (parameters.Length != 7)
- continue;
+ if (parameters[0].ParameterType != typeof(byte[]) ||
+ parameters[1].ParameterType != typeof(int) ||
+ parameters[2].ParameterType != typeof(int) ||
+ parameters[3].ParameterType != typeof(byte[]) ||
+ parameters[4].ParameterType != typeof(int) ||
+ parameters[5].ParameterType != typeof(int) ||
+ parameters[6].ParameterType != lz4Level)
+ continue;
- if (parameters[0].ParameterType != typeof(byte[]) ||
- parameters[1].ParameterType != typeof(int) ||
- parameters[2].ParameterType != typeof(int) ||
- parameters[3].ParameterType != typeof(byte[]) ||
- parameters[4].ParameterType != typeof(int) ||
- parameters[5].ParameterType != typeof(int) ||
- parameters[6].ParameterType != lz4Level)
- continue;
-
- return (Encode) method.CreateDelegate(typeof(Encode));
- }
-
- throw new Exception($"A method with the name '{name}' matching the delegate was not found");
+ return (Encode) method.CreateDelegate(typeof(Encode));
}
- private static MaximumOutputSize FindMaximumOutputSize(MethodInfo[] methods)
+ throw new Exception($"A method with the name '{name}' matching the delegate was not found");
+ }
+
+ private static MaximumOutputSize FindMaximumOutputSize(MethodInfo[] methods)
+ {
+ const string name = "MaximumOutputSize";
+
+ foreach (var method in methods)
{
- const string name = "MaximumOutputSize";
+ if (method.Name != name || method.ReturnType != typeof(int))
+ continue;
- foreach (var method in methods)
- {
- if (method.Name != name || method.ReturnType != typeof(int))
- continue;
+ var parameters = method.GetParameters();
+ if (parameters.Length != 1)
+ continue;
- var parameters = method.GetParameters();
- if (parameters.Length != 1)
- continue;
+ if (parameters[0].ParameterType != typeof(int))
+ continue;
- if (parameters[0].ParameterType != typeof(int))
- continue;
-
- return (MaximumOutputSize) method.CreateDelegate(typeof(MaximumOutputSize));
- }
-
- throw new Exception($"A method with the name '{name}' matching the delegate was not found");
+ return (MaximumOutputSize) method.CreateDelegate(typeof(MaximumOutputSize));
}
- private static Func<ReadOnlySequence<byte>, int, ReadOnlySequence<byte>> CreateDecompressor(Decode decompress)
+ throw new Exception($"A method with the name '{name}' matching the delegate was not found");
+ }
+
+ private static Func<ReadOnlySequence<byte>, int, ReadOnlySequence<byte>> CreateDecompressor(Decode decompress)
+ {
+ return (source, size) =>
{
- return (source, size) =>
- {
- var decompressed = new byte[size];
- var sourceBytes = source.ToArray();
- var bytesDecompressed = decompress(sourceBytes, 0, sourceBytes.Length, decompressed, 0, decompressed.Length);
- if (size == bytesDecompressed)
- return new ReadOnlySequence<byte>(decompressed);
+ var decompressed = new byte[size];
+ var sourceBytes = source.ToArray();
+ var bytesDecompressed = decompress(sourceBytes, 0, sourceBytes.Length, decompressed, 0, decompressed.Length);
+ if (size == bytesDecompressed)
+ return new ReadOnlySequence<byte>(decompressed);
- throw new CompressionException($"LZ4Codec.Decode returned {bytesDecompressed} but expected {size}");
- };
- }
+ throw new CompressionException($"LZ4Codec.Decode returned {bytesDecompressed} but expected {size}");
+ };
+ }
- private static Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> CreateCompressor(Encode compress, MaximumOutputSize maximumOutputSize)
+ private static Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> CreateCompressor(Encode compress, MaximumOutputSize maximumOutputSize)
+ {
+ return (source) =>
{
- return (source) =>
- {
- var sourceBytes = source.ToArray();
- var compressed = new byte[maximumOutputSize(sourceBytes.Length)];
- var bytesCompressed = compress(sourceBytes, 0, sourceBytes.Length, compressed, 0, compressed.Length, 0);
- if (bytesCompressed == -1)
- throw new CompressionException($"LZ4Codec.Encode returned -1 when compressing {sourceBytes.Length} bytes");
+ var sourceBytes = source.ToArray();
+ var compressed = new byte[maximumOutputSize(sourceBytes.Length)];
+ var bytesCompressed = compress(sourceBytes, 0, sourceBytes.Length, compressed, 0, compressed.Length, 0);
+ if (bytesCompressed == -1)
+ throw new CompressionException($"LZ4Codec.Encode returned -1 when compressing {sourceBytes.Length} bytes");
- return new ReadOnlySequence<byte>(compressed, 0, bytesCompressed);
- };
- }
+ return new ReadOnlySequence<byte>(compressed, 0, bytesCompressed);
+ };
}
}
diff --git a/src/DotPulsar/Internal/Compression/SnappyCompression.cs b/src/DotPulsar/Internal/Compression/SnappyCompression.cs
index 3f77a43..5d82747 100644
--- a/src/DotPulsar/Internal/Compression/SnappyCompression.cs
+++ b/src/DotPulsar/Internal/Compression/SnappyCompression.cs
@@ -12,116 +12,115 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Compression
+namespace DotPulsar.Internal.Compression;
+
+using DotPulsar.Internal.Abstractions;
+using System;
+using System.Buffers;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+
+public static class SnappyCompression
{
- using DotPulsar.Internal.Abstractions;
- using System;
- using System.Buffers;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
+ public delegate byte[] Decode(ReadOnlySpan<byte> source);
+ public delegate byte[] Encode(ReadOnlySpan<byte> source);
- public static class SnappyCompression
+ public static bool TryLoading(out ICompressorFactory? compressorFactory, out IDecompressorFactory? decompressorFactory)
{
- public delegate byte[] Decode(ReadOnlySpan<byte> source);
- public delegate byte[] Encode(ReadOnlySpan<byte> source);
-
- public static bool TryLoading(out ICompressorFactory? compressorFactory, out IDecompressorFactory? decompressorFactory)
+ try
{
- try
- {
- var assembly = Assembly.Load("IronSnappy");
+ var assembly = Assembly.Load("IronSnappy");
- var definedTypes = assembly.DefinedTypes.ToArray();
+ var definedTypes = assembly.DefinedTypes.ToArray();
- var snappy = FindSnappy(definedTypes);
+ var snappy = FindSnappy(definedTypes);
- var methods = snappy.GetMethods(BindingFlags.Public | BindingFlags.Static);
+ var methods = snappy.GetMethods(BindingFlags.Public | BindingFlags.Static);
- var decode = FindDecode(methods);
- var encode = FindEncode(methods);
+ var decode = FindDecode(methods);
+ var encode = FindEncode(methods);
- compressorFactory = new CompressorFactory(PulsarApi.CompressionType.Snappy, () => new Compressor(CreateCompressor(encode)));
- decompressorFactory = new DecompressorFactory(PulsarApi.CompressionType.Snappy, () => new Decompressor(CreateDecompressor(decode)));
- return true;
- }
- catch
- {
- // Ignore
- }
-
- compressorFactory = null;
- decompressorFactory = null;
-
- return false;
+ compressorFactory = new CompressorFactory(PulsarApi.CompressionType.Snappy, () => new Compressor(CreateCompressor(encode)));
+ decompressorFactory = new DecompressorFactory(PulsarApi.CompressionType.Snappy, () => new Decompressor(CreateDecompressor(decode)));
+ return true;
+ }
+ catch
+ {
+ // Ignore
}
- private static TypeInfo FindSnappy(IEnumerable<TypeInfo> types)
- {
- const string fullName = "IronSnappy.Snappy";
+ compressorFactory = null;
+ decompressorFactory = null;
- foreach (var type in types)
- {
- if (type.FullName is null || !type.FullName.Equals(fullName))
- continue;
-
- if (type.IsPublic && type.IsClass && type.IsAbstract && type.IsSealed)
- return type;
-
- break;
- }
-
- throw new Exception($"{fullName} as a public and static class was not found");
- }
-
- private static Decode FindDecode(MethodInfo[] methods)
- {
- const string name = "Decode";
-
- foreach (var method in methods)
- {
- if (method.Name != name || method.ReturnType != typeof(byte[]))
- continue;
-
- var parameters = method.GetParameters();
- if (parameters.Length != 1)
- continue;
-
- if (parameters[0].ParameterType != typeof(ReadOnlySpan<byte>))
- continue;
-
- return (Decode) method.CreateDelegate(typeof(Decode));
- }
-
- throw new Exception($"A method with the name '{name}' matching the delegate was not found");
- }
-
- private static Encode FindEncode(MethodInfo[] methods)
- {
- const string name = "Encode";
-
- foreach (var method in methods)
- {
- if (method.Name != name || method.ReturnType != typeof(byte[]))
- continue;
-
- var parameters = method.GetParameters();
- if (parameters.Length != 1)
- continue;
-
- if (parameters[0].ParameterType != typeof(ReadOnlySpan<byte>))
- continue;
-
- return (Encode) method.CreateDelegate(typeof(Encode));
- }
-
- throw new Exception($"A method with the name '{name}' matching the delegate was not found");
- }
-
- private static Func<ReadOnlySequence<byte>, int, ReadOnlySequence<byte>> CreateDecompressor(Decode decompress)
- => (source, size) => new ReadOnlySequence<byte>(decompress(source.ToArray()));
-
- private static Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> CreateCompressor(Encode compress)
- => (source) => new ReadOnlySequence<byte>(compress(source.ToArray()));
+ return false;
}
+
+ private static TypeInfo FindSnappy(IEnumerable<TypeInfo> types)
+ {
+ const string fullName = "IronSnappy.Snappy";
+
+ foreach (var type in types)
+ {
+ if (type.FullName is null || !type.FullName.Equals(fullName))
+ continue;
+
+ if (type.IsPublic && type.IsClass && type.IsAbstract && type.IsSealed)
+ return type;
+
+ break;
+ }
+
+ throw new Exception($"{fullName} as a public and static class was not found");
+ }
+
+ private static Decode FindDecode(MethodInfo[] methods)
+ {
+ const string name = "Decode";
+
+ foreach (var method in methods)
+ {
+ if (method.Name != name || method.ReturnType != typeof(byte[]))
+ continue;
+
+ var parameters = method.GetParameters();
+ if (parameters.Length != 1)
+ continue;
+
+ if (parameters[0].ParameterType != typeof(ReadOnlySpan<byte>))
+ continue;
+
+ return (Decode) method.CreateDelegate(typeof(Decode));
+ }
+
+ throw new Exception($"A method with the name '{name}' matching the delegate was not found");
+ }
+
+ private static Encode FindEncode(MethodInfo[] methods)
+ {
+ const string name = "Encode";
+
+ foreach (var method in methods)
+ {
+ if (method.Name != name || method.ReturnType != typeof(byte[]))
+ continue;
+
+ var parameters = method.GetParameters();
+ if (parameters.Length != 1)
+ continue;
+
+ if (parameters[0].ParameterType != typeof(ReadOnlySpan<byte>))
+ continue;
+
+ return (Encode) method.CreateDelegate(typeof(Encode));
+ }
+
+ throw new Exception($"A method with the name '{name}' matching the delegate was not found");
+ }
+
+ private static Func<ReadOnlySequence<byte>, int, ReadOnlySequence<byte>> CreateDecompressor(Decode decompress)
+ => (source, size) => new ReadOnlySequence<byte>(decompress(source.ToArray()));
+
+ private static Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> CreateCompressor(Encode compress)
+ => (source) => new ReadOnlySequence<byte>(compress(source.ToArray()));
}
diff --git a/src/DotPulsar/Internal/Compression/ZlibCompression.cs b/src/DotPulsar/Internal/Compression/ZlibCompression.cs
index 082b9b1..f4bdcbe 100644
--- a/src/DotPulsar/Internal/Compression/ZlibCompression.cs
+++ b/src/DotPulsar/Internal/Compression/ZlibCompression.cs
@@ -12,116 +12,115 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Compression
+namespace DotPulsar.Internal.Compression;
+
+using DotPulsar.Internal.Abstractions;
+using System;
+using System.Buffers;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+
+public static class ZlibCompression
{
- using DotPulsar.Internal.Abstractions;
- using System;
- using System.Buffers;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
+ public delegate byte[] CompressBuffer(byte[] source);
+ public delegate byte[] UncompressBuffer(byte[] source);
- public static class ZlibCompression
+ public static bool TryLoading(out ICompressorFactory? compressorFactory, out IDecompressorFactory? decompressorFactory)
{
- public delegate byte[] CompressBuffer(byte[] source);
- public delegate byte[] UncompressBuffer(byte[] source);
-
- public static bool TryLoading(out ICompressorFactory? compressorFactory, out IDecompressorFactory? decompressorFactory)
+ try
{
- try
- {
- var assembly = Assembly.Load("DotNetZip");
+ var assembly = Assembly.Load("DotNetZip");
- var definedTypes = assembly.DefinedTypes.ToArray();
+ var definedTypes = assembly.DefinedTypes.ToArray();
- var ZlibStream = FindZlibStream(definedTypes);
+ var ZlibStream = FindZlibStream(definedTypes);
- var methods = ZlibStream.GetMethods(BindingFlags.Public | BindingFlags.Static);
+ var methods = ZlibStream.GetMethods(BindingFlags.Public | BindingFlags.Static);
- var compressBuffer = FindCompressBuffer(methods);
- var uncompressBuffer = FindUncompressBuffer(methods);
+ var compressBuffer = FindCompressBuffer(methods);
+ var uncompressBuffer = FindUncompressBuffer(methods);
- compressorFactory = new CompressorFactory(PulsarApi.CompressionType.Zlib, () => new Compressor(CreateCompressor(compressBuffer)));
- decompressorFactory = new DecompressorFactory(PulsarApi.CompressionType.Zlib, () => new Decompressor(CreateDecompressor(uncompressBuffer)));
- return true;
- }
- catch
- {
- // Ignore
- }
-
- compressorFactory = null;
- decompressorFactory = null;
-
- return false;
+ compressorFactory = new CompressorFactory(PulsarApi.CompressionType.Zlib, () => new Compressor(CreateCompressor(compressBuffer)));
+ decompressorFactory = new DecompressorFactory(PulsarApi.CompressionType.Zlib, () => new Decompressor(CreateDecompressor(uncompressBuffer)));
+ return true;
+ }
+ catch
+ {
+ // Ignore
}
- private static TypeInfo FindZlibStream(IEnumerable<TypeInfo> types)
- {
- const string fullName = "Ionic.Zlib.ZlibStream";
+ compressorFactory = null;
+ decompressorFactory = null;
- foreach (var type in types)
- {
- if (type.FullName is null || !type.FullName.Equals(fullName))
- continue;
-
- if (type.IsPublic && type.IsClass)
- return type;
-
- break;
- }
-
- throw new Exception($"{fullName} as a public class was not found");
- }
-
- private static CompressBuffer FindCompressBuffer(MethodInfo[] methods)
- {
- const string name = "CompressBuffer";
-
- foreach (var method in methods)
- {
- if (method.Name != name || method.ReturnType != typeof(byte[]))
- continue;
-
- var parameters = method.GetParameters();
- if (parameters.Length != 1)
- continue;
-
- if (parameters[0].ParameterType != typeof(byte[]))
- continue;
-
- return (CompressBuffer) method.CreateDelegate(typeof(CompressBuffer));
- }
-
- throw new Exception($"A method with the name '{name}' matching the delegate was not found");
- }
-
- private static UncompressBuffer FindUncompressBuffer(MethodInfo[] methods)
- {
- const string name = "UncompressBuffer";
-
- foreach (var method in methods)
- {
- if (method.Name != name || method.ReturnType != typeof(byte[]))
- continue;
-
- var parameters = method.GetParameters();
- if (parameters.Length != 1)
- continue;
-
- if (parameters[0].ParameterType != typeof(byte[]))
- continue;
-
- return (UncompressBuffer) method.CreateDelegate(typeof(UncompressBuffer));
- }
-
- throw new Exception($"A method with the name '{name}' matching the delegate was not found");
- }
-
- private static Func<ReadOnlySequence<byte>, int, ReadOnlySequence<byte>> CreateDecompressor(UncompressBuffer decompress)
- => (source, size) => new ReadOnlySequence<byte>(decompress(source.ToArray()));
-
- private static Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> CreateCompressor(CompressBuffer compress)
- => (source) => new ReadOnlySequence<byte>(compress(source.ToArray()));
+ return false;
}
+
+ private static TypeInfo FindZlibStream(IEnumerable<TypeInfo> types)
+ {
+ const string fullName = "Ionic.Zlib.ZlibStream";
+
+ foreach (var type in types)
+ {
+ if (type.FullName is null || !type.FullName.Equals(fullName))
+ continue;
+
+ if (type.IsPublic && type.IsClass)
+ return type;
+
+ break;
+ }
+
+ throw new Exception($"{fullName} as a public class was not found");
+ }
+
+ private static CompressBuffer FindCompressBuffer(MethodInfo[] methods)
+ {
+ const string name = "CompressBuffer";
+
+ foreach (var method in methods)
+ {
+ if (method.Name != name || method.ReturnType != typeof(byte[]))
+ continue;
+
+ var parameters = method.GetParameters();
+ if (parameters.Length != 1)
+ continue;
+
+ if (parameters[0].ParameterType != typeof(byte[]))
+ continue;
+
+ return (CompressBuffer) method.CreateDelegate(typeof(CompressBuffer));
+ }
+
+ throw new Exception($"A method with the name '{name}' matching the delegate was not found");
+ }
+
+ private static UncompressBuffer FindUncompressBuffer(MethodInfo[] methods)
+ {
+ const string name = "UncompressBuffer";
+
+ foreach (var method in methods)
+ {
+ if (method.Name != name || method.ReturnType != typeof(byte[]))
+ continue;
+
+ var parameters = method.GetParameters();
+ if (parameters.Length != 1)
+ continue;
+
+ if (parameters[0].ParameterType != typeof(byte[]))
+ continue;
+
+ return (UncompressBuffer) method.CreateDelegate(typeof(UncompressBuffer));
+ }
+
+ throw new Exception($"A method with the name '{name}' matching the delegate was not found");
+ }
+
+ private static Func<ReadOnlySequence<byte>, int, ReadOnlySequence<byte>> CreateDecompressor(UncompressBuffer decompress)
+ => (source, size) => new ReadOnlySequence<byte>(decompress(source.ToArray()));
+
+ private static Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> CreateCompressor(CompressBuffer compress)
+ => (source) => new ReadOnlySequence<byte>(compress(source.ToArray()));
}
diff --git a/src/DotPulsar/Internal/Compression/ZstdCompression.cs b/src/DotPulsar/Internal/Compression/ZstdCompression.cs
index c9f5f20..b9857d1 100644
--- a/src/DotPulsar/Internal/Compression/ZstdCompression.cs
+++ b/src/DotPulsar/Internal/Compression/ZstdCompression.cs
@@ -12,151 +12,150 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Compression
+namespace DotPulsar.Internal.Compression;
+
+using DotPulsar.Exceptions;
+using DotPulsar.Internal.Abstractions;
+using System;
+using System.Buffers;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+
+public static class ZstdCompression
{
- using DotPulsar.Exceptions;
- using DotPulsar.Internal.Abstractions;
- using System;
- using System.Buffers;
- using System.Collections.Generic;
- using System.Linq;
- using System.Reflection;
+ public delegate byte[] Wrap(byte[] src);
+ public delegate int Unwrap(byte[] src, byte[] dst, int offset, bool bufferSizePrecheck);
- public static class ZstdCompression
+ public static bool TryLoading(out ICompressorFactory? compressorFactory, out IDecompressorFactory? decompressorFactory)
{
- public delegate byte[] Wrap(byte[] src);
- public delegate int Unwrap(byte[] src, byte[] dst, int offset, bool bufferSizePrecheck);
-
- public static bool TryLoading(out ICompressorFactory? compressorFactory, out IDecompressorFactory? decompressorFactory)
+ try
{
- try
+ var assembly = Assembly.Load("ZstdNet");
+
+ var definedTypes = assembly.DefinedTypes.ToArray();
+
+ var decompressorType = Find(definedTypes, "ZstdNet.Decompressor");
+ var decompressorMethods = decompressorType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
+ var unwrapMethod = FindUnwrap(decompressorMethods);
+
+ var compressorType = Find(definedTypes, "ZstdNet.Compressor");
+ var compressorMethods = compressorType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
+ var wrapMethod = FindWrap(compressorMethods);
+
+ compressorFactory = new CompressorFactory(PulsarApi.CompressionType.Zstd, () =>
{
- var assembly = Assembly.Load("ZstdNet");
+ var compressor = Activator.CreateInstance(compressorType);
+ if (compressor is null)
+ throw new Exception($"Activator.CreateInstance returned null when trying to create a {compressorType.FullName}");
- var definedTypes = assembly.DefinedTypes.ToArray();
+ var wrap = (Wrap) wrapMethod.CreateDelegate(typeof(Wrap), compressor);
+ return new Compressor(CreateCompressor(wrap), (IDisposable) compressor);
+ });
- var decompressorType = Find(definedTypes, "ZstdNet.Decompressor");
- var decompressorMethods = decompressorType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
- var unwrapMethod = FindUnwrap(decompressorMethods);
-
- var compressorType = Find(definedTypes, "ZstdNet.Compressor");
- var compressorMethods = compressorType.GetMethods(BindingFlags.Public | BindingFlags.Instance);
- var wrapMethod = FindWrap(compressorMethods);
-
- compressorFactory = new CompressorFactory(PulsarApi.CompressionType.Zstd, () =>
- {
- var compressor = Activator.CreateInstance(compressorType);
- if (compressor is null)
- throw new Exception($"Activator.CreateInstance returned null when trying to create a {compressorType.FullName}");
-
- var wrap = (Wrap) wrapMethod.CreateDelegate(typeof(Wrap), compressor);
- return new Compressor(CreateCompressor(wrap), (IDisposable) compressor);
- });
-
- decompressorFactory = new DecompressorFactory(PulsarApi.CompressionType.Zstd, () =>
- {
- var decompressor = Activator.CreateInstance(decompressorType);
- if (decompressor is null)
- throw new Exception($"Activator.CreateInstance returned null when trying to create a {decompressorType.FullName}");
-
- var unwrap = (Unwrap) unwrapMethod.CreateDelegate(typeof(Unwrap), decompressor);
- return new Decompressor(CreateDecompressor(unwrap), (IDisposable) decompressor);
- });
-
- return true;
- }
- catch
+ decompressorFactory = new DecompressorFactory(PulsarApi.CompressionType.Zstd, () =>
{
- // Ignore
- }
+ var decompressor = Activator.CreateInstance(decompressorType);
+ if (decompressor is null)
+ throw new Exception($"Activator.CreateInstance returned null when trying to create a {decompressorType.FullName}");
- compressorFactory = null;
- decompressorFactory = null;
+ var unwrap = (Unwrap) unwrapMethod.CreateDelegate(typeof(Unwrap), decompressor);
+ return new Decompressor(CreateDecompressor(unwrap), (IDisposable) decompressor);
+ });
- return false;
+ return true;
+ }
+ catch
+ {
+ // Ignore
}
- private static TypeInfo Find(IEnumerable<TypeInfo> types, string fullName)
- {
- foreach (var type in types)
- {
- if (type.FullName is null || !type.FullName.Equals(fullName))
- continue;
+ compressorFactory = null;
+ decompressorFactory = null;
- if (type.IsPublic &&
- type.IsClass &&
- !type.IsAbstract &&
- type.ImplementedInterfaces.Contains(typeof(IDisposable)) &&
- type.GetConstructor(Type.EmptyTypes) is not null)
- return type;
-
- break;
- }
-
- throw new Exception($"{fullName} as a public class with an empty public constructor and implementing IDisposable was not found");
- }
-
- private static MethodInfo FindWrap(MethodInfo[] methods)
- {
- const string name = "Wrap";
-
- foreach (var method in methods)
- {
- if (method.Name != name || method.ReturnType != typeof(byte[]))
- continue;
-
- var parameters = method.GetParameters();
- if (parameters.Length != 1)
- continue;
-
- if (parameters[0].ParameterType != typeof(byte[]))
- continue;
-
- return method;
- }
-
- throw new Exception($"A method with the name '{name}' matching the delegate was not found");
- }
-
- private static MethodInfo FindUnwrap(MethodInfo[] methods)
- {
- const string name = "Unwrap";
-
- foreach (var method in methods)
- {
- if (method.Name != name || method.ReturnType != typeof(int))
- continue;
-
- var parameters = method.GetParameters();
- if (parameters.Length != 4)
- continue;
-
- if (parameters[0].ParameterType != typeof(byte[]) ||
- parameters[1].ParameterType != typeof(byte[]) ||
- parameters[2].ParameterType != typeof(int) ||
- parameters[3].ParameterType != typeof(bool))
- continue;
-
- return method;
- }
-
- throw new Exception($"A method with the name '{name}' matching the delegate was not found");
- }
-
- private static Func<ReadOnlySequence<byte>, int, ReadOnlySequence<byte>> CreateDecompressor(Unwrap decompress)
- {
- return (source, size) =>
- {
- var decompressed = new byte[size];
- var bytesDecompressed = decompress(source.ToArray(), decompressed, 0, false);
- if (size == bytesDecompressed)
- return new ReadOnlySequence<byte>(decompressed);
-
- throw new CompressionException($"ZstdNet.Decompressor returned {bytesDecompressed} but expected {size}");
- };
- }
-
- private static Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> CreateCompressor(Wrap compress)
- => (source) => new ReadOnlySequence<byte>(compress(source.ToArray()));
+ return false;
}
+
+ private static TypeInfo Find(IEnumerable<TypeInfo> types, string fullName)
+ {
+ foreach (var type in types)
+ {
+ if (type.FullName is null || !type.FullName.Equals(fullName))
+ continue;
+
+ if (type.IsPublic &&
+ type.IsClass &&
+ !type.IsAbstract &&
+ type.ImplementedInterfaces.Contains(typeof(IDisposable)) &&
+ type.GetConstructor(Type.EmptyTypes) is not null)
+ return type;
+
+ break;
+ }
+
+ throw new Exception($"{fullName} as a public class with an empty public constructor and implementing IDisposable was not found");
+ }
+
+ private static MethodInfo FindWrap(MethodInfo[] methods)
+ {
+ const string name = "Wrap";
+
+ foreach (var method in methods)
+ {
+ if (method.Name != name || method.ReturnType != typeof(byte[]))
+ continue;
+
+ var parameters = method.GetParameters();
+ if (parameters.Length != 1)
+ continue;
+
+ if (parameters[0].ParameterType != typeof(byte[]))
+ continue;
+
+ return method;
+ }
+
+ throw new Exception($"A method with the name '{name}' matching the delegate was not found");
+ }
+
+ private static MethodInfo FindUnwrap(MethodInfo[] methods)
+ {
+ const string name = "Unwrap";
+
+ foreach (var method in methods)
+ {
+ if (method.Name != name || method.ReturnType != typeof(int))
+ continue;
+
+ var parameters = method.GetParameters();
+ if (parameters.Length != 4)
+ continue;
+
+ if (parameters[0].ParameterType != typeof(byte[]) ||
+ parameters[1].ParameterType != typeof(byte[]) ||
+ parameters[2].ParameterType != typeof(int) ||
+ parameters[3].ParameterType != typeof(bool))
+ continue;
+
+ return method;
+ }
+
+ throw new Exception($"A method with the name '{name}' matching the delegate was not found");
+ }
+
+ private static Func<ReadOnlySequence<byte>, int, ReadOnlySequence<byte>> CreateDecompressor(Unwrap decompress)
+ {
+ return (source, size) =>
+ {
+ var decompressed = new byte[size];
+ var bytesDecompressed = decompress(source.ToArray(), decompressed, 0, false);
+ if (size == bytesDecompressed)
+ return new ReadOnlySequence<byte>(decompressed);
+
+ throw new CompressionException($"ZstdNet.Decompressor returned {bytesDecompressed} but expected {size}");
+ };
+ }
+
+ private static Func<ReadOnlySequence<byte>, ReadOnlySequence<byte>> CreateCompressor(Wrap compress)
+ => (source) => new ReadOnlySequence<byte>(compress(source.ToArray()));
}
diff --git a/src/DotPulsar/Internal/Connection.cs b/src/DotPulsar/Internal/Connection.cs
index 7534981..1ee72e3 100644
--- a/src/DotPulsar/Internal/Connection.cs
+++ b/src/DotPulsar/Internal/Connection.cs
@@ -12,303 +12,302 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using Abstractions;
+using Exceptions;
+using Extensions;
+using PulsarApi;
+using System;
+using System.Buffers;
+using System.Threading;
+using System.Threading.Tasks;
+
+public sealed class Connection : IConnection
{
- using Abstractions;
- using Exceptions;
- using Extensions;
- using PulsarApi;
- using System;
- using System.Buffers;
- using System.Threading;
- using System.Threading.Tasks;
+ private readonly AsyncLock _lock;
+ private readonly ChannelManager _channelManager;
+ private readonly PingPongHandler _pingPongHandler;
+ private readonly IPulsarStream _stream;
+ private int _isDisposed;
- public sealed class Connection : IConnection
+ public Connection(IPulsarStream stream, TimeSpan keepAliveInterval)
{
- private readonly AsyncLock _lock;
- private readonly ChannelManager _channelManager;
- private readonly PingPongHandler _pingPongHandler;
- private readonly IPulsarStream _stream;
- private int _isDisposed;
+ _lock = new AsyncLock();
+ _channelManager = new ChannelManager();
+ _pingPongHandler = new PingPongHandler(this, keepAliveInterval);
+ _stream = stream;
+ }
- public Connection(IPulsarStream stream, TimeSpan keepAliveInterval)
+ public async ValueTask<bool> HasChannels(CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
{
- _lock = new AsyncLock();
- _channelManager = new ChannelManager();
- _pingPongHandler = new PingPongHandler(this, keepAliveInterval);
- _stream = stream;
+ return _channelManager.HasChannels();
+ }
+ }
+
+ public async Task<ProducerResponse> Send(CommandProducer command, IChannel channel, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ Task<ProducerResponse>? responseTask;
+
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ responseTask = _channelManager.Outgoing(command, channel);
+ var sequence = Serializer.Serialize(command.AsBaseCommand());
+ await _stream.Send(sequence).ConfigureAwait(false);
}
- public async ValueTask<bool> HasChannels(CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
+ return await responseTask.ConfigureAwait(false);
+ }
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ public async Task<SubscribeResponse> Send(CommandSubscribe command, IChannel channel, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ Task<SubscribeResponse>? responseTask;
+
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ responseTask = _channelManager.Outgoing(command, channel);
+ var sequence = Serializer.Serialize(command.AsBaseCommand());
+ await _stream.Send(sequence).ConfigureAwait(false);
+ }
+
+ return await responseTask.ConfigureAwait(false);
+ }
+
+ public Task Send(CommandPing command, CancellationToken cancellationToken)
+ => Send(command.AsBaseCommand(), cancellationToken);
+
+ public Task Send(CommandPong command, CancellationToken cancellationToken)
+ => Send(command.AsBaseCommand(), cancellationToken);
+
+ public Task Send(CommandAck command, CancellationToken cancellationToken)
+ => Send(command.AsBaseCommand(), cancellationToken);
+
+ public Task Send(CommandFlow command, CancellationToken cancellationToken)
+ => Send(command.AsBaseCommand(), cancellationToken);
+
+ public Task Send(CommandRedeliverUnacknowledgedMessages command, CancellationToken cancellationToken)
+ => Send(command.AsBaseCommand(), cancellationToken);
+
+ public async Task<BaseCommand> Send(CommandUnsubscribe command, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ Task<BaseCommand>? responseTask;
+
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ responseTask = _channelManager.Outgoing(command);
+ var sequence = Serializer.Serialize(command.AsBaseCommand());
+ await _stream.Send(sequence).ConfigureAwait(false);
+ }
+
+ return await responseTask.ConfigureAwait(false);
+ }
+
+ public async Task<BaseCommand> Send(CommandConnect command, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ Task<BaseCommand>? responseTask;
+
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ responseTask = _channelManager.Outgoing(command);
+ var sequence = Serializer.Serialize(command.AsBaseCommand());
+ await _stream.Send(sequence).ConfigureAwait(false);
+ }
+
+ return await responseTask.ConfigureAwait(false);
+ }
+
+ public async Task<BaseCommand> Send(CommandLookupTopic command, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ Task<BaseCommand>? responseTask;
+
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ responseTask = _channelManager.Outgoing(command);
+ var sequence = Serializer.Serialize(command.AsBaseCommand());
+ await _stream.Send(sequence).ConfigureAwait(false);
+ }
+
+ return await responseTask.ConfigureAwait(false);
+ }
+
+ public async Task<BaseCommand> Send(CommandSeek command, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ Task<BaseCommand>? responseTask;
+
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ responseTask = _channelManager.Outgoing(command);
+ var sequence = Serializer.Serialize(command.AsBaseCommand());
+ await _stream.Send(sequence).ConfigureAwait(false);
+ }
+
+ return await responseTask.ConfigureAwait(false);
+ }
+
+ public async Task<BaseCommand> Send(CommandGetLastMessageId command, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ Task<BaseCommand>? responseTask;
+
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ responseTask = _channelManager.Outgoing(command);
+ var sequence = Serializer.Serialize(command.AsBaseCommand());
+ await _stream.Send(sequence).ConfigureAwait(false);
+ }
+
+ return await responseTask.ConfigureAwait(false);
+ }
+
+ public async Task<BaseCommand> Send(CommandCloseProducer command, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ Task<BaseCommand>? responseTask;
+
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ responseTask = _channelManager.Outgoing(command);
+ var sequence = Serializer.Serialize(command.AsBaseCommand());
+ await _stream.Send(sequence).ConfigureAwait(false);
+ }
+
+ return await responseTask.ConfigureAwait(false);
+ }
+
+ public async Task<BaseCommand> Send(CommandCloseConsumer command, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ Task<BaseCommand>? responseTask;
+
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ responseTask = _channelManager.Outgoing(command);
+ var sequence = Serializer.Serialize(command.AsBaseCommand());
+ await _stream.Send(sequence).ConfigureAwait(false);
+ }
+
+ return await responseTask.ConfigureAwait(false);
+ }
+
+ public async Task<BaseCommand> Send(SendPackage command, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ Task<BaseCommand>? responseTask;
+
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ responseTask = _channelManager.Outgoing(command.Command!);
+ var sequence = Serializer.Serialize(command.Command!.AsBaseCommand(), command.Metadata!, command.Payload);
+ await _stream.Send(sequence).ConfigureAwait(false);
+ }
+
+ return await responseTask.ConfigureAwait(false);
+ }
+
+ public async Task<BaseCommand> Send(CommandGetOrCreateSchema command, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ Task<BaseCommand>? responseTask;
+
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ responseTask = _channelManager.Outgoing(command);
+ var sequence = Serializer.Serialize(command.AsBaseCommand());
+ await _stream.Send(sequence).ConfigureAwait(false);
+ }
+
+ return await responseTask.ConfigureAwait(false);
+ }
+
+ public async Task<BaseCommand> Send(CommandPartitionedTopicMetadata command, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ Task<BaseCommand>? responseTask;
+
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ responseTask = _channelManager.Outgoing(command);
+ var sequence = Serializer.Serialize(command.AsBaseCommand());
+ await _stream.Send(sequence).ConfigureAwait(false);
+ }
+
+ return await responseTask.ConfigureAwait(false);
+ }
+
+ private async Task Send(BaseCommand command, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ var sequence = Serializer.Serialize(command);
+
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ await _stream.Send(sequence).ConfigureAwait(false);
+ }
+ }
+
+ public async Task ProcessIncommingFrames()
+ {
+ await Task.Yield();
+
+ try
+ {
+ await foreach (var frame in _stream.Frames())
{
- return _channelManager.HasChannels();
+ var commandSize = frame.ReadUInt32(0, true);
+ var command = Serializer.Deserialize<BaseCommand>(frame.Slice(4, commandSize));
+
+ if (_pingPongHandler.Incoming(command.CommandType))
+ continue;
+
+ if (command.CommandType == BaseCommand.Type.Message)
+ _channelManager.Incoming(command.Message, new ReadOnlySequence<byte>(frame.Slice(commandSize + 4).ToArray()));
+ else
+ _channelManager.Incoming(command);
}
}
-
- public async Task<ProducerResponse> Send(CommandProducer command, IChannel channel, CancellationToken cancellationToken)
+ catch
{
- ThrowIfDisposed();
-
- Task<ProducerResponse>? responseTask;
-
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
- {
- responseTask = _channelManager.Outgoing(command, channel);
- var sequence = Serializer.Serialize(command.AsBaseCommand());
- await _stream.Send(sequence).ConfigureAwait(false);
- }
-
- return await responseTask.ConfigureAwait(false);
+ // ignored
}
+ }
- public async Task<SubscribeResponse> Send(CommandSubscribe command, IChannel channel, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
+ public async ValueTask DisposeAsync()
+ {
+ if (Interlocked.Exchange(ref _isDisposed, 1) != 0)
+ return;
- Task<SubscribeResponse>? responseTask;
+ await _pingPongHandler.DisposeAsync().ConfigureAwait(false);
+ await _lock.DisposeAsync().ConfigureAwait(false);
+ _channelManager.Dispose();
+ await _stream.DisposeAsync().ConfigureAwait(false);
+ }
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
- {
- responseTask = _channelManager.Outgoing(command, channel);
- var sequence = Serializer.Serialize(command.AsBaseCommand());
- await _stream.Send(sequence).ConfigureAwait(false);
- }
-
- return await responseTask.ConfigureAwait(false);
- }
-
- public Task Send(CommandPing command, CancellationToken cancellationToken)
- => Send(command.AsBaseCommand(), cancellationToken);
-
- public Task Send(CommandPong command, CancellationToken cancellationToken)
- => Send(command.AsBaseCommand(), cancellationToken);
-
- public Task Send(CommandAck command, CancellationToken cancellationToken)
- => Send(command.AsBaseCommand(), cancellationToken);
-
- public Task Send(CommandFlow command, CancellationToken cancellationToken)
- => Send(command.AsBaseCommand(), cancellationToken);
-
- public Task Send(CommandRedeliverUnacknowledgedMessages command, CancellationToken cancellationToken)
- => Send(command.AsBaseCommand(), cancellationToken);
-
- public async Task<BaseCommand> Send(CommandUnsubscribe command, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- Task<BaseCommand>? responseTask;
-
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
- {
- responseTask = _channelManager.Outgoing(command);
- var sequence = Serializer.Serialize(command.AsBaseCommand());
- await _stream.Send(sequence).ConfigureAwait(false);
- }
-
- return await responseTask.ConfigureAwait(false);
- }
-
- public async Task<BaseCommand> Send(CommandConnect command, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- Task<BaseCommand>? responseTask;
-
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
- {
- responseTask = _channelManager.Outgoing(command);
- var sequence = Serializer.Serialize(command.AsBaseCommand());
- await _stream.Send(sequence).ConfigureAwait(false);
- }
-
- return await responseTask.ConfigureAwait(false);
- }
-
- public async Task<BaseCommand> Send(CommandLookupTopic command, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- Task<BaseCommand>? responseTask;
-
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
- {
- responseTask = _channelManager.Outgoing(command);
- var sequence = Serializer.Serialize(command.AsBaseCommand());
- await _stream.Send(sequence).ConfigureAwait(false);
- }
-
- return await responseTask.ConfigureAwait(false);
- }
-
- public async Task<BaseCommand> Send(CommandSeek command, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- Task<BaseCommand>? responseTask;
-
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
- {
- responseTask = _channelManager.Outgoing(command);
- var sequence = Serializer.Serialize(command.AsBaseCommand());
- await _stream.Send(sequence).ConfigureAwait(false);
- }
-
- return await responseTask.ConfigureAwait(false);
- }
-
- public async Task<BaseCommand> Send(CommandGetLastMessageId command, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- Task<BaseCommand>? responseTask;
-
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
- {
- responseTask = _channelManager.Outgoing(command);
- var sequence = Serializer.Serialize(command.AsBaseCommand());
- await _stream.Send(sequence).ConfigureAwait(false);
- }
-
- return await responseTask.ConfigureAwait(false);
- }
-
- public async Task<BaseCommand> Send(CommandCloseProducer command, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- Task<BaseCommand>? responseTask;
-
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
- {
- responseTask = _channelManager.Outgoing(command);
- var sequence = Serializer.Serialize(command.AsBaseCommand());
- await _stream.Send(sequence).ConfigureAwait(false);
- }
-
- return await responseTask.ConfigureAwait(false);
- }
-
- public async Task<BaseCommand> Send(CommandCloseConsumer command, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- Task<BaseCommand>? responseTask;
-
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
- {
- responseTask = _channelManager.Outgoing(command);
- var sequence = Serializer.Serialize(command.AsBaseCommand());
- await _stream.Send(sequence).ConfigureAwait(false);
- }
-
- return await responseTask.ConfigureAwait(false);
- }
-
- public async Task<BaseCommand> Send(SendPackage command, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- Task<BaseCommand>? responseTask;
-
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
- {
- responseTask = _channelManager.Outgoing(command.Command!);
- var sequence = Serializer.Serialize(command.Command!.AsBaseCommand(), command.Metadata!, command.Payload);
- await _stream.Send(sequence).ConfigureAwait(false);
- }
-
- return await responseTask.ConfigureAwait(false);
- }
-
- public async Task<BaseCommand> Send(CommandGetOrCreateSchema command, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- Task<BaseCommand>? responseTask;
-
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
- {
- responseTask = _channelManager.Outgoing(command);
- var sequence = Serializer.Serialize(command.AsBaseCommand());
- await _stream.Send(sequence).ConfigureAwait(false);
- }
-
- return await responseTask.ConfigureAwait(false);
- }
-
- public async Task<BaseCommand> Send(CommandPartitionedTopicMetadata command, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- Task<BaseCommand>? responseTask;
-
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
- {
- responseTask = _channelManager.Outgoing(command);
- var sequence = Serializer.Serialize(command.AsBaseCommand());
- await _stream.Send(sequence).ConfigureAwait(false);
- }
-
- return await responseTask.ConfigureAwait(false);
- }
-
- private async Task Send(BaseCommand command, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- var sequence = Serializer.Serialize(command);
-
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
- {
- await _stream.Send(sequence).ConfigureAwait(false);
- }
- }
-
- public async Task ProcessIncommingFrames()
- {
- await Task.Yield();
-
- try
- {
- await foreach (var frame in _stream.Frames())
- {
- var commandSize = frame.ReadUInt32(0, true);
- var command = Serializer.Deserialize<BaseCommand>(frame.Slice(4, commandSize));
-
- if (_pingPongHandler.Incoming(command.CommandType))
- continue;
-
- if (command.CommandType == BaseCommand.Type.Message)
- _channelManager.Incoming(command.Message, new ReadOnlySequence<byte>(frame.Slice(commandSize + 4).ToArray()));
- else
- _channelManager.Incoming(command);
- }
- }
- catch
- {
- // ignored
- }
- }
-
- public async ValueTask DisposeAsync()
- {
- if (Interlocked.Exchange(ref _isDisposed, 1) != 0)
- return;
-
- await _pingPongHandler.DisposeAsync().ConfigureAwait(false);
- await _lock.DisposeAsync().ConfigureAwait(false);
- _channelManager.Dispose();
- await _stream.DisposeAsync().ConfigureAwait(false);
- }
-
- private void ThrowIfDisposed()
- {
- if (_isDisposed != 0)
- throw new ConnectionDisposedException();
- }
+ private void ThrowIfDisposed()
+ {
+ if (_isDisposed != 0)
+ throw new ConnectionDisposedException();
}
}
diff --git a/src/DotPulsar/Internal/ConnectionPool.cs b/src/DotPulsar/Internal/ConnectionPool.cs
index 1eaf96f..14ab85f 100644
--- a/src/DotPulsar/Internal/ConnectionPool.cs
+++ b/src/DotPulsar/Internal/ConnectionPool.cs
@@ -12,253 +12,252 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using Abstractions;
+using DotPulsar.Exceptions;
+using Extensions;
+using PulsarApi;
+using System;
+using System.Collections.Concurrent;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+public sealed class ConnectionPool : IConnectionPool
{
- using Abstractions;
- using DotPulsar.Exceptions;
- using Extensions;
- using PulsarApi;
- using System;
- using System.Collections.Concurrent;
- using System.Linq;
- using System.Threading;
- using System.Threading.Tasks;
+ private readonly AsyncLock _lock;
+ private readonly CommandConnect _commandConnect;
+ private readonly Uri _serviceUrl;
+ private readonly Connector _connector;
+ private readonly EncryptionPolicy _encryptionPolicy;
+ private readonly ConcurrentDictionary<PulsarUrl, Connection> _connections;
+ private readonly CancellationTokenSource _cancellationTokenSource;
+ private readonly Task _closeInactiveConnections;
+ private readonly string? _listenerName;
+ private readonly TimeSpan _keepAliveInterval;
- public sealed class ConnectionPool : IConnectionPool
+ public ConnectionPool(
+ CommandConnect commandConnect,
+ Uri serviceUrl,
+ Connector connector,
+ EncryptionPolicy encryptionPolicy,
+ TimeSpan closeInactiveConnectionsInterval,
+ string? listenerName,
+ TimeSpan keepAliveInterval)
{
- private readonly AsyncLock _lock;
- private readonly CommandConnect _commandConnect;
- private readonly Uri _serviceUrl;
- private readonly Connector _connector;
- private readonly EncryptionPolicy _encryptionPolicy;
- private readonly ConcurrentDictionary<PulsarUrl, Connection> _connections;
- private readonly CancellationTokenSource _cancellationTokenSource;
- private readonly Task _closeInactiveConnections;
- private readonly string? _listenerName;
- private readonly TimeSpan _keepAliveInterval;
+ _lock = new AsyncLock();
+ _commandConnect = commandConnect;
+ _serviceUrl = serviceUrl;
+ _connector = connector;
+ _encryptionPolicy = encryptionPolicy;
+ _listenerName = listenerName;
+ _connections = new ConcurrentDictionary<PulsarUrl, Connection>();
+ _cancellationTokenSource = new CancellationTokenSource();
+ _closeInactiveConnections = CloseInactiveConnections(closeInactiveConnectionsInterval, _cancellationTokenSource.Token);
+ _keepAliveInterval = keepAliveInterval;
+ }
- public ConnectionPool(
- CommandConnect commandConnect,
- Uri serviceUrl,
- Connector connector,
- EncryptionPolicy encryptionPolicy,
- TimeSpan closeInactiveConnectionsInterval,
- string? listenerName,
- TimeSpan keepAliveInterval)
+ public async ValueTask DisposeAsync()
+ {
+ _cancellationTokenSource.Cancel();
+
+ await _closeInactiveConnections.ConfigureAwait(false);
+
+ await _lock.DisposeAsync().ConfigureAwait(false);
+
+ foreach (var serviceUrl in _connections.Keys.ToArray())
{
- _lock = new AsyncLock();
- _commandConnect = commandConnect;
- _serviceUrl = serviceUrl;
- _connector = connector;
- _encryptionPolicy = encryptionPolicy;
- _listenerName = listenerName;
- _connections = new ConcurrentDictionary<PulsarUrl, Connection>();
- _cancellationTokenSource = new CancellationTokenSource();
- _closeInactiveConnections = CloseInactiveConnections(closeInactiveConnectionsInterval, _cancellationTokenSource.Token);
- _keepAliveInterval = keepAliveInterval;
+ await DisposeConnection(serviceUrl).ConfigureAwait(false);
}
+ }
- public async ValueTask DisposeAsync()
+ public async ValueTask<IConnection> FindConnectionForTopic(string topic, CancellationToken cancellationToken)
+ {
+ var lookup = new CommandLookupTopic
{
- _cancellationTokenSource.Cancel();
+ Topic = topic,
+ Authoritative = false,
+ AdvertisedListenerName = _listenerName
+ };
- await _closeInactiveConnections.ConfigureAwait(false);
+ var physicalUrl = _serviceUrl;
- await _lock.DisposeAsync().ConfigureAwait(false);
+ while (true)
+ {
+ var connection = await GetConnection(physicalUrl, cancellationToken).ConfigureAwait(false);
+ var response = await connection.Send(lookup, cancellationToken).ConfigureAwait(false);
- foreach (var serviceUrl in _connections.Keys.ToArray())
+ response.Expect(BaseCommand.Type.LookupResponse);
+
+ if (response.LookupTopicResponse.Response == CommandLookupTopicResponse.LookupType.Failed)
+ response.LookupTopicResponse.Throw();
+
+ lookup.Authoritative = response.LookupTopicResponse.Authoritative;
+
+ var lookupResponseServiceUrl = new Uri(GetBrokerServiceUrl(response.LookupTopicResponse));
+
+ if (response.LookupTopicResponse.Response == CommandLookupTopicResponse.LookupType.Redirect || !response.LookupTopicResponse.Authoritative)
{
- await DisposeConnection(serviceUrl).ConfigureAwait(false);
+ physicalUrl = lookupResponseServiceUrl;
+ continue;
}
+
+ if (response.LookupTopicResponse.ProxyThroughServiceUrl)
+ {
+ var url = new PulsarUrl(physicalUrl, lookupResponseServiceUrl);
+ return await GetConnection(url, cancellationToken).ConfigureAwait(false);
+ }
+
+ // LookupType is 'Connect', ServiceUrl is local and response is authoritative. Assume the Pulsar server is a standalone docker.
+ return lookupResponseServiceUrl.IsLoopback
+ ? connection
+ : await GetConnection(lookupResponseServiceUrl, cancellationToken).ConfigureAwait(false);
}
+ }
- public async ValueTask<IConnection> FindConnectionForTopic(string topic, CancellationToken cancellationToken)
+ private string GetBrokerServiceUrl(CommandLookupTopicResponse response)
+ {
+ var hasBrokerServiceUrl = !string.IsNullOrEmpty(response.BrokerServiceUrl);
+ var hasBrokerServiceUrlTls = !string.IsNullOrEmpty(response.BrokerServiceUrlTls);
+
+ switch (_encryptionPolicy)
{
- var lookup = new CommandLookupTopic
+ case EncryptionPolicy.EnforceEncrypted:
+ if (!hasBrokerServiceUrlTls)
+ throw new ConnectionSecurityException("Cannot enforce encrypted connections. The lookup topic response from broker gave no secure alternative.");
+ return response.BrokerServiceUrlTls;
+ case EncryptionPolicy.EnforceUnencrypted:
+ if (!hasBrokerServiceUrl)
+ throw new ConnectionSecurityException("Cannot enforce unencrypted connections. The lookup topic response from broker gave no unsecure alternative.");
+ return response.BrokerServiceUrl;
+ case EncryptionPolicy.PreferEncrypted:
+ return hasBrokerServiceUrlTls ? response.BrokerServiceUrlTls : response.BrokerServiceUrl;
+ default:
+ return hasBrokerServiceUrl ? response.BrokerServiceUrl : response.BrokerServiceUrlTls;
+ }
+ }
+
+ private ValueTask<Connection> GetConnection(Uri serviceUrl, CancellationToken cancellationToken)
+ {
+ return GetConnection(new PulsarUrl(serviceUrl, serviceUrl), cancellationToken);
+ }
+
+ private async ValueTask<Connection> GetConnection(PulsarUrl url, CancellationToken cancellationToken)
+ {
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ if (_connections.TryGetValue(url, out Connection? connection) && connection is not null)
+ return connection;
+
+ return await EstablishNewConnection(url, cancellationToken).ConfigureAwait(false);
+ }
+ }
+
+ private async Task<Connection> EstablishNewConnection(PulsarUrl url, CancellationToken cancellationToken)
+ {
+ var stream = await _connector.Connect(url.Physical).ConfigureAwait(false);
+ var connection = new Connection(new PulsarStream(stream), _keepAliveInterval);
+ DotPulsarEventSource.Log.ConnectionCreated();
+ _connections[url] = connection;
+ _ = connection.ProcessIncommingFrames().ContinueWith(t => DisposeConnection(url));
+ var commandConnect = _commandConnect;
+
+ if (url.ProxyThroughServiceUrl)
+ commandConnect = WithProxyToBroker(_commandConnect, url.Logical);
+
+ var response = await connection.Send(commandConnect, cancellationToken).ConfigureAwait(false);
+ response.Expect(BaseCommand.Type.Connected);
+ return connection;
+ }
+
+ private async ValueTask DisposeConnection(PulsarUrl serviceUrl)
+ {
+ if (_connections.TryRemove(serviceUrl, out Connection? connection) && connection is not null)
+ {
+ await connection.DisposeAsync().ConfigureAwait(false);
+ DotPulsarEventSource.Log.ConnectionDisposed();
+ }
+ }
+
+ private static CommandConnect WithProxyToBroker(CommandConnect commandConnect, Uri logicalUrl)
+ {
+ return new CommandConnect
+ {
+ AuthData = commandConnect.AuthData,
+ AuthMethod = commandConnect.AuthMethod,
+ AuthMethodName = commandConnect.AuthMethodName,
+ ClientVersion = commandConnect.ClientVersion,
+ OriginalPrincipal = commandConnect.OriginalPrincipal,
+ ProtocolVersion = commandConnect.ProtocolVersion,
+ OriginalAuthData = commandConnect.OriginalAuthData,
+ OriginalAuthMethod = commandConnect.OriginalAuthMethod,
+ ProxyToBrokerUrl = $"{logicalUrl.Host}:{logicalUrl.Port}"
+ };
+ }
+
+ private async Task CloseInactiveConnections(TimeSpan interval, CancellationToken cancellationToken)
+ {
+ while (!cancellationToken.IsCancellationRequested)
+ {
+ try
{
- Topic = topic,
- Authoritative = false,
- AdvertisedListenerName = _listenerName
- };
+ await Task.Delay(interval, cancellationToken).ConfigureAwait(false);
- var physicalUrl = _serviceUrl;
-
- while (true)
- {
- var connection = await GetConnection(physicalUrl, cancellationToken).ConfigureAwait(false);
- var response = await connection.Send(lookup, cancellationToken).ConfigureAwait(false);
-
- response.Expect(BaseCommand.Type.LookupResponse);
-
- if (response.LookupTopicResponse.Response == CommandLookupTopicResponse.LookupType.Failed)
- response.LookupTopicResponse.Throw();
-
- lookup.Authoritative = response.LookupTopicResponse.Authoritative;
-
- var lookupResponseServiceUrl = new Uri(GetBrokerServiceUrl(response.LookupTopicResponse));
-
- if (response.LookupTopicResponse.Response == CommandLookupTopicResponse.LookupType.Redirect || !response.LookupTopicResponse.Authoritative)
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
{
- physicalUrl = lookupResponseServiceUrl;
- continue;
- }
-
- if (response.LookupTopicResponse.ProxyThroughServiceUrl)
- {
- var url = new PulsarUrl(physicalUrl, lookupResponseServiceUrl);
- return await GetConnection(url, cancellationToken).ConfigureAwait(false);
- }
-
- // LookupType is 'Connect', ServiceUrl is local and response is authoritative. Assume the Pulsar server is a standalone docker.
- return lookupResponseServiceUrl.IsLoopback
- ? connection
- : await GetConnection(lookupResponseServiceUrl, cancellationToken).ConfigureAwait(false);
- }
- }
-
- private string GetBrokerServiceUrl(CommandLookupTopicResponse response)
- {
- var hasBrokerServiceUrl = !string.IsNullOrEmpty(response.BrokerServiceUrl);
- var hasBrokerServiceUrlTls = !string.IsNullOrEmpty(response.BrokerServiceUrlTls);
-
- switch (_encryptionPolicy)
- {
- case EncryptionPolicy.EnforceEncrypted:
- if (!hasBrokerServiceUrlTls)
- throw new ConnectionSecurityException("Cannot enforce encrypted connections. The lookup topic response from broker gave no secure alternative.");
- return response.BrokerServiceUrlTls;
- case EncryptionPolicy.EnforceUnencrypted:
- if (!hasBrokerServiceUrl)
- throw new ConnectionSecurityException("Cannot enforce unencrypted connections. The lookup topic response from broker gave no unsecure alternative.");
- return response.BrokerServiceUrl;
- case EncryptionPolicy.PreferEncrypted:
- return hasBrokerServiceUrlTls ? response.BrokerServiceUrlTls : response.BrokerServiceUrl;
- default:
- return hasBrokerServiceUrl ? response.BrokerServiceUrl : response.BrokerServiceUrlTls;
- }
- }
-
- private ValueTask<Connection> GetConnection(Uri serviceUrl, CancellationToken cancellationToken)
- {
- return GetConnection(new PulsarUrl(serviceUrl, serviceUrl), cancellationToken);
- }
-
- private async ValueTask<Connection> GetConnection(PulsarUrl url, CancellationToken cancellationToken)
- {
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
- {
- if (_connections.TryGetValue(url, out Connection? connection) && connection is not null)
- return connection;
-
- return await EstablishNewConnection(url, cancellationToken).ConfigureAwait(false);
- }
- }
-
- private async Task<Connection> EstablishNewConnection(PulsarUrl url, CancellationToken cancellationToken)
- {
- var stream = await _connector.Connect(url.Physical).ConfigureAwait(false);
- var connection = new Connection(new PulsarStream(stream), _keepAliveInterval);
- DotPulsarEventSource.Log.ConnectionCreated();
- _connections[url] = connection;
- _ = connection.ProcessIncommingFrames().ContinueWith(t => DisposeConnection(url));
- var commandConnect = _commandConnect;
-
- if (url.ProxyThroughServiceUrl)
- commandConnect = WithProxyToBroker(_commandConnect, url.Logical);
-
- var response = await connection.Send(commandConnect, cancellationToken).ConfigureAwait(false);
- response.Expect(BaseCommand.Type.Connected);
- return connection;
- }
-
- private async ValueTask DisposeConnection(PulsarUrl serviceUrl)
- {
- if (_connections.TryRemove(serviceUrl, out Connection? connection) && connection is not null)
- {
- await connection.DisposeAsync().ConfigureAwait(false);
- DotPulsarEventSource.Log.ConnectionDisposed();
- }
- }
-
- private static CommandConnect WithProxyToBroker(CommandConnect commandConnect, Uri logicalUrl)
- {
- return new CommandConnect
- {
- AuthData = commandConnect.AuthData,
- AuthMethod = commandConnect.AuthMethod,
- AuthMethodName = commandConnect.AuthMethodName,
- ClientVersion = commandConnect.ClientVersion,
- OriginalPrincipal = commandConnect.OriginalPrincipal,
- ProtocolVersion = commandConnect.ProtocolVersion,
- OriginalAuthData = commandConnect.OriginalAuthData,
- OriginalAuthMethod = commandConnect.OriginalAuthMethod,
- ProxyToBrokerUrl = $"{logicalUrl.Host}:{logicalUrl.Port}"
- };
- }
-
- private async Task CloseInactiveConnections(TimeSpan interval, CancellationToken cancellationToken)
- {
- while (!cancellationToken.IsCancellationRequested)
- {
- try
- {
- await Task.Delay(interval, cancellationToken).ConfigureAwait(false);
-
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ var serviceUrls = _connections.Keys;
+ foreach (var serviceUrl in serviceUrls)
{
- var serviceUrls = _connections.Keys;
- foreach (var serviceUrl in serviceUrls)
- {
- var connection = _connections[serviceUrl];
- if (connection is null)
- continue;
+ var connection = _connections[serviceUrl];
+ if (connection is null)
+ continue;
- if (!await connection.HasChannels(cancellationToken).ConfigureAwait(false))
- await DisposeConnection(serviceUrl).ConfigureAwait(false);
- }
+ if (!await connection.HasChannels(cancellationToken).ConfigureAwait(false))
+ await DisposeConnection(serviceUrl).ConfigureAwait(false);
}
}
- catch
- {
- // ignored
- }
+ }
+ catch
+ {
+ // ignored
}
}
+ }
- private sealed class PulsarUrl : IEquatable<PulsarUrl>
+ private sealed class PulsarUrl : IEquatable<PulsarUrl>
+ {
+ public PulsarUrl(Uri physical, Uri logical)
{
- public PulsarUrl(Uri physical, Uri logical)
- {
- Physical = physical;
- Logical = logical;
- ProxyThroughServiceUrl = physical != logical;
- }
-
- public Uri Physical { get; }
-
- public Uri Logical { get; }
-
- public bool ProxyThroughServiceUrl { get; }
-
- public bool Equals(PulsarUrl? other)
- {
- if (other is null)
- return false;
-
- if (ReferenceEquals(this, other))
- return true;
-
- return Physical.Equals(other.Physical) && Logical.Equals(other.Logical);
- }
-
- public override bool Equals(object? obj)
- => obj is PulsarUrl url && Equals(url);
-
- public override int GetHashCode()
- => HashCode.Combine(Physical, Logical);
-
- public override string ToString()
- => $"{nameof(Physical)}: {Physical}, {nameof(Logical)}: {Logical}, {nameof(ProxyThroughServiceUrl)}: {ProxyThroughServiceUrl}";
+ Physical = physical;
+ Logical = logical;
+ ProxyThroughServiceUrl = physical != logical;
}
+
+ public Uri Physical { get; }
+
+ public Uri Logical { get; }
+
+ public bool ProxyThroughServiceUrl { get; }
+
+ public bool Equals(PulsarUrl? other)
+ {
+ if (other is null)
+ return false;
+
+ if (ReferenceEquals(this, other))
+ return true;
+
+ return Physical.Equals(other.Physical) && Logical.Equals(other.Logical);
+ }
+
+ public override bool Equals(object? obj)
+ => obj is PulsarUrl url && Equals(url);
+
+ public override int GetHashCode()
+ => HashCode.Combine(Physical, Logical);
+
+ public override string ToString()
+ => $"{nameof(Physical)}: {Physical}, {nameof(Logical)}: {Logical}, {nameof(ProxyThroughServiceUrl)}: {ProxyThroughServiceUrl}";
}
}
diff --git a/src/DotPulsar/Internal/Connector.cs b/src/DotPulsar/Internal/Connector.cs
index 52b2774..99f761f 100644
--- a/src/DotPulsar/Internal/Connector.cs
+++ b/src/DotPulsar/Internal/Connector.cs
@@ -12,132 +12,131 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using System;
+using System.IO;
+using System.Net;
+using System.Net.Security;
+using System.Net.Sockets;
+using System.Security.Authentication;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading.Tasks;
+
+public sealed class Connector
{
- using System;
- using System.IO;
- using System.Net;
- using System.Net.Security;
- using System.Net.Sockets;
- using System.Security.Authentication;
- using System.Security.Cryptography.X509Certificates;
- using System.Threading.Tasks;
+ private readonly X509Certificate2Collection _clientCertificates;
+ private readonly X509Certificate2? _trustedCertificateAuthority;
+ private readonly bool _verifyCertificateAuthority;
+ private readonly bool _verifyCertificateName;
- public sealed class Connector
+ public Connector(
+ X509Certificate2Collection clientCertificates,
+ X509Certificate2? trustedCertificateAuthority,
+ bool verifyCertificateAuthority,
+ bool verifyCertificateName)
{
- private readonly X509Certificate2Collection _clientCertificates;
- private readonly X509Certificate2? _trustedCertificateAuthority;
- private readonly bool _verifyCertificateAuthority;
- private readonly bool _verifyCertificateName;
+ _clientCertificates = clientCertificates;
+ _trustedCertificateAuthority = trustedCertificateAuthority;
+ _verifyCertificateAuthority = verifyCertificateAuthority;
+ _verifyCertificateName = verifyCertificateName;
+ }
- public Connector(
- X509Certificate2Collection clientCertificates,
- X509Certificate2? trustedCertificateAuthority,
- bool verifyCertificateAuthority,
- bool verifyCertificateName)
+ public async Task<Stream> Connect(Uri serviceUrl)
+ {
+ var scheme = serviceUrl.Scheme;
+ var host = serviceUrl.Host;
+ var port = serviceUrl.Port;
+ var encrypt = scheme == Constants.PulsarSslScheme;
+
+ if (port == -1)
+ port = encrypt ? Constants.DefaultPulsarSSLPort : Constants.DefaultPulsarPort;
+
+ var stream = await GetStream(host, port).ConfigureAwait(false);
+
+ if (encrypt)
+ stream = await EncryptStream(stream, host).ConfigureAwait(false);
+
+ return stream;
+ }
+
+ private static async Task<Stream> GetStream(string host, int port)
+ {
+ var tcpClient = new TcpClient();
+
+ try
{
- _clientCertificates = clientCertificates;
- _trustedCertificateAuthority = trustedCertificateAuthority;
- _verifyCertificateAuthority = verifyCertificateAuthority;
- _verifyCertificateName = verifyCertificateName;
+ var type = Uri.CheckHostName(host);
+
+ if (type == UriHostNameType.IPv4 || type == UriHostNameType.IPv6)
+ await tcpClient.ConnectAsync(IPAddress.Parse(host), port).ConfigureAwait(false);
+ else
+ await tcpClient.ConnectAsync(host, port).ConfigureAwait(false);
+
+ return tcpClient.GetStream();
}
-
- public async Task<Stream> Connect(Uri serviceUrl)
+ catch
{
- var scheme = serviceUrl.Scheme;
- var host = serviceUrl.Host;
- var port = serviceUrl.Port;
- var encrypt = scheme == Constants.PulsarSslScheme;
-
- if (port == -1)
- port = encrypt ? Constants.DefaultPulsarSSLPort : Constants.DefaultPulsarPort;
-
- var stream = await GetStream(host, port).ConfigureAwait(false);
-
- if (encrypt)
- stream = await EncryptStream(stream, host).ConfigureAwait(false);
-
- return stream;
+ tcpClient.Dispose();
+ throw;
}
+ }
- private static async Task<Stream> GetStream(string host, int port)
+ private async Task<Stream> EncryptStream(Stream stream, string host)
+ {
+ SslStream? sslStream = null;
+
+ try
{
- var tcpClient = new TcpClient();
-
- try
- {
- var type = Uri.CheckHostName(host);
-
- if (type == UriHostNameType.IPv4 || type == UriHostNameType.IPv6)
- await tcpClient.ConnectAsync(IPAddress.Parse(host), port).ConfigureAwait(false);
- else
- await tcpClient.ConnectAsync(host, port).ConfigureAwait(false);
-
- return tcpClient.GetStream();
- }
- catch
- {
- tcpClient.Dispose();
- throw;
- }
+ sslStream = new SslStream(stream, false, ValidateServerCertificate, null);
+ await sslStream.AuthenticateAsClientAsync(host, _clientCertificates, SslProtocols.None, true).ConfigureAwait(false);
+ return sslStream;
}
-
- private async Task<Stream> EncryptStream(Stream stream, string host)
+ catch
{
- SslStream? sslStream = null;
-
- try
- {
- sslStream = new SslStream(stream, false, ValidateServerCertificate, null);
- await sslStream.AuthenticateAsClientAsync(host, _clientCertificates, SslProtocols.None, true).ConfigureAwait(false);
- return sslStream;
- }
- catch
- {
#if NETSTANDARD2_0
- if (sslStream is null)
- stream.Dispose();
- else
- sslStream.Dispose();
+ if (sslStream is null)
+ stream.Dispose();
+ else
+ sslStream.Dispose();
#else
if (sslStream is null)
await stream.DisposeAsync().ConfigureAwait(false);
else
await sslStream.DisposeAsync().ConfigureAwait(false);
#endif
- throw;
- }
+ throw;
}
+ }
- private bool ValidateServerCertificate(object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors)
- {
- if (sslPolicyErrors == SslPolicyErrors.None)
- return true;
-
- if (sslPolicyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNotAvailable))
- return false;
-
- if (sslPolicyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch) && _verifyCertificateName)
- return false;
-
- if (sslPolicyErrors.HasFlag(SslPolicyErrors.RemoteCertificateChainErrors) && _verifyCertificateAuthority)
- {
- if (_trustedCertificateAuthority is null || chain is null || certificate is null)
- return false;
-
- chain.ChainPolicy.ExtraStore.Add(_trustedCertificateAuthority);
- _ = chain.Build((X509Certificate2) certificate);
-
- for (var i = 0; i < chain.ChainElements.Count; i++)
- {
- if (chain.ChainElements[i].Certificate.Thumbprint == _trustedCertificateAuthority.Thumbprint)
- return true;
- }
-
- return false;
- }
-
+ private bool ValidateServerCertificate(object sender, X509Certificate? certificate, X509Chain? chain, SslPolicyErrors sslPolicyErrors)
+ {
+ if (sslPolicyErrors == SslPolicyErrors.None)
return true;
+
+ if (sslPolicyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNotAvailable))
+ return false;
+
+ if (sslPolicyErrors.HasFlag(SslPolicyErrors.RemoteCertificateNameMismatch) && _verifyCertificateName)
+ return false;
+
+ if (sslPolicyErrors.HasFlag(SslPolicyErrors.RemoteCertificateChainErrors) && _verifyCertificateAuthority)
+ {
+ if (_trustedCertificateAuthority is null || chain is null || certificate is null)
+ return false;
+
+ chain.ChainPolicy.ExtraStore.Add(_trustedCertificateAuthority);
+ _ = chain.Build((X509Certificate2) certificate);
+
+ for (var i = 0; i < chain.ChainElements.Count; i++)
+ {
+ if (chain.ChainElements[i].Certificate.Thumbprint == _trustedCertificateAuthority.Thumbprint)
+ return true;
+ }
+
+ return false;
}
+
+ return true;
}
}
diff --git a/src/DotPulsar/Internal/Constants.cs b/src/DotPulsar/Internal/Constants.cs
index 9ee752b..0630812 100644
--- a/src/DotPulsar/Internal/Constants.cs
+++ b/src/DotPulsar/Internal/Constants.cs
@@ -12,44 +12,43 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using System;
+
+public static class Constants
{
- using System;
-
- public static class Constants
+ static Constants()
{
- static Constants()
- {
- var assembly = typeof(Constants).Assembly;
- var assemblyName = assembly.GetName();
- if (assemblyName.Name is null)
- throw new Exception($"Assembly name of {assembly.FullName} is null");
+ var assembly = typeof(Constants).Assembly;
+ var assemblyName = assembly.GetName();
+ if (assemblyName.Name is null)
+ throw new Exception($"Assembly name of {assembly.FullName} is null");
- var assemblyVersion = assemblyName.Version;
- if (assemblyVersion is null)
- throw new Exception($"Assembly version of {assembly.FullName} is null");
+ var assemblyVersion = assemblyName.Version;
+ if (assemblyVersion is null)
+ throw new Exception($"Assembly version of {assembly.FullName} is null");
- ClientName = assemblyName.Name;
- ClientVersion = assemblyVersion.ToString(3);
- ProtocolVersion = 14;
- PulsarScheme = "pulsar";
- PulsarSslScheme = "pulsar+ssl";
- DefaultPulsarPort = 6650;
- DefaultPulsarSSLPort = 6651;
- MagicNumber = new byte[] { 0x0e, 0x01 };
- MetadataSizeOffset = 6;
- MetadataOffset = 10;
- }
-
- public static string ClientName { get; }
- public static string ClientVersion { get; }
- public static int ProtocolVersion { get; }
- public static string PulsarScheme { get; }
- public static string PulsarSslScheme { get; }
- public static int DefaultPulsarPort { get; }
- public static int DefaultPulsarSSLPort { get; }
- public static byte[] MagicNumber { get; }
- public static int MetadataSizeOffset { get; }
- public static int MetadataOffset { get; }
+ ClientName = assemblyName.Name;
+ ClientVersion = assemblyVersion.ToString(3);
+ ProtocolVersion = 14;
+ PulsarScheme = "pulsar";
+ PulsarSslScheme = "pulsar+ssl";
+ DefaultPulsarPort = 6650;
+ DefaultPulsarSSLPort = 6651;
+ MagicNumber = new byte[] { 0x0e, 0x01 };
+ MetadataSizeOffset = 6;
+ MetadataOffset = 10;
}
+
+ public static string ClientName { get; }
+ public static string ClientVersion { get; }
+ public static int ProtocolVersion { get; }
+ public static string PulsarScheme { get; }
+ public static string PulsarSslScheme { get; }
+ public static int DefaultPulsarPort { get; }
+ public static int DefaultPulsarSSLPort { get; }
+ public static byte[] MagicNumber { get; }
+ public static int MetadataSizeOffset { get; }
+ public static int MetadataOffset { get; }
}
diff --git a/src/DotPulsar/Internal/Consumer.cs b/src/DotPulsar/Internal/Consumer.cs
index 3d50ead..a81b3ee 100644
--- a/src/DotPulsar/Internal/Consumer.cs
+++ b/src/DotPulsar/Internal/Consumer.cs
@@ -12,195 +12,194 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using Abstractions;
+using DotPulsar.Abstractions;
+using DotPulsar.Exceptions;
+using DotPulsar.Internal.Extensions;
+using Events;
+using Microsoft.Extensions.ObjectPool;
+using PulsarApi;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+public sealed class Consumer<TMessage> : IEstablishNewChannel, IConsumer<TMessage>
{
- using Abstractions;
- using DotPulsar.Abstractions;
- using DotPulsar.Exceptions;
- using DotPulsar.Internal.Extensions;
- using Events;
- using Microsoft.Extensions.ObjectPool;
- using PulsarApi;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
- using System.Threading.Tasks;
+ private readonly Guid _correlationId;
+ private readonly IRegisterEvent _eventRegister;
+ private IConsumerChannel<TMessage> _channel;
+ private readonly ObjectPool<CommandAck> _commandAckPool;
+ private readonly IExecute _executor;
+ private readonly IStateChanged<ConsumerState> _state;
+ private readonly IConsumerChannelFactory<TMessage> _factory;
+ private int _isDisposed;
- public sealed class Consumer<TMessage> : IEstablishNewChannel, IConsumer<TMessage>
+ public Uri ServiceUrl { get; }
+ public string SubscriptionName { get; }
+ public string Topic { get; }
+
+ public Consumer(
+ Guid correlationId,
+ Uri serviceUrl,
+ string subscriptionName,
+ string topic,
+ IRegisterEvent eventRegister,
+ IConsumerChannel<TMessage> initialChannel,
+ IExecute executor,
+ IStateChanged<ConsumerState> state,
+ IConsumerChannelFactory<TMessage> factory)
{
- private readonly Guid _correlationId;
- private readonly IRegisterEvent _eventRegister;
- private IConsumerChannel<TMessage> _channel;
- private readonly ObjectPool<CommandAck> _commandAckPool;
- private readonly IExecute _executor;
- private readonly IStateChanged<ConsumerState> _state;
- private readonly IConsumerChannelFactory<TMessage> _factory;
- private int _isDisposed;
+ _correlationId = correlationId;
+ ServiceUrl = serviceUrl;
+ SubscriptionName = subscriptionName;
+ Topic = topic;
+ _eventRegister = eventRegister;
+ _channel = initialChannel;
+ _executor = executor;
+ _state = state;
+ _factory = factory;
+ _commandAckPool = new DefaultObjectPool<CommandAck>(new DefaultPooledObjectPolicy<CommandAck>());
+ _isDisposed = 0;
- public Uri ServiceUrl { get; }
- public string SubscriptionName { get; }
- public string Topic { get; }
+ _eventRegister.Register(new ConsumerCreated(_correlationId));
+ }
- public Consumer(
- Guid correlationId,
- Uri serviceUrl,
- string subscriptionName,
- string topic,
- IRegisterEvent eventRegister,
- IConsumerChannel<TMessage> initialChannel,
- IExecute executor,
- IStateChanged<ConsumerState> state,
- IConsumerChannelFactory<TMessage> factory)
+ public async ValueTask<ConsumerState> OnStateChangeTo(ConsumerState state, CancellationToken cancellationToken)
+ => await _state.StateChangedTo(state, cancellationToken).ConfigureAwait(false);
+
+ public async ValueTask<ConsumerState> OnStateChangeFrom(ConsumerState state, CancellationToken cancellationToken)
+ => await _state.StateChangedFrom(state, cancellationToken).ConfigureAwait(false);
+
+ public bool IsFinalState()
+ => _state.IsFinalState();
+
+ public bool IsFinalState(ConsumerState state)
+ => _state.IsFinalState(state);
+
+ public async ValueTask DisposeAsync()
+ {
+ if (Interlocked.Exchange(ref _isDisposed, 1) != 0)
+ return;
+
+ _eventRegister.Register(new ConsumerDisposed(_correlationId));
+ await _channel.ClosedByClient(CancellationToken.None).ConfigureAwait(false);
+ await _channel.DisposeAsync().ConfigureAwait(false);
+ }
+
+ public async ValueTask<IMessage<TMessage>> Receive(CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ return await _executor.Execute(() => ReceiveMessage(cancellationToken), cancellationToken).ConfigureAwait(false);
+ }
+
+ private async ValueTask<IMessage<TMessage>> ReceiveMessage(CancellationToken cancellationToken)
+ => await _channel.Receive(cancellationToken).ConfigureAwait(false);
+
+ public async ValueTask Acknowledge(MessageId messageId, CancellationToken cancellationToken)
+ => await Acknowledge(messageId, CommandAck.AckType.Individual, cancellationToken).ConfigureAwait(false);
+
+ public async ValueTask AcknowledgeCumulative(MessageId messageId, CancellationToken cancellationToken)
+ => await Acknowledge(messageId, CommandAck.AckType.Cumulative, cancellationToken).ConfigureAwait(false);
+
+ public async ValueTask RedeliverUnacknowledgedMessages(IEnumerable<MessageId> messageIds, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ var command = new CommandRedeliverUnacknowledgedMessages();
+ command.MessageIds.AddRange(messageIds.Select(messageId => messageId.ToMessageIdData()));
+ await _executor.Execute(() => RedeliverUnacknowledgedMessages(command, cancellationToken), cancellationToken).ConfigureAwait(false);
+ }
+
+ public async ValueTask RedeliverUnacknowledgedMessages(CancellationToken cancellationToken)
+ => await RedeliverUnacknowledgedMessages(Enumerable.Empty<MessageId>(), cancellationToken).ConfigureAwait(false);
+
+ public async ValueTask Unsubscribe(CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ var unsubscribe = new CommandUnsubscribe();
+ await _executor.Execute(() => Unsubscribe(unsubscribe, cancellationToken), cancellationToken).ConfigureAwait(false);
+ }
+
+ private async ValueTask Unsubscribe(CommandUnsubscribe command, CancellationToken cancellationToken)
+ => await _channel.Send(command, cancellationToken).ConfigureAwait(false);
+
+ public async ValueTask Seek(MessageId messageId, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ var seek = new CommandSeek { MessageId = messageId.ToMessageIdData() };
+ await _executor.Execute(() => Seek(seek, cancellationToken), cancellationToken).ConfigureAwait(false);
+ }
+
+ public async ValueTask Seek(ulong publishTime, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ var seek = new CommandSeek { MessagePublishTime = publishTime };
+ await _executor.Execute(() => Seek(seek, cancellationToken), cancellationToken).ConfigureAwait(false);
+ }
+
+ public async ValueTask<MessageId> GetLastMessageId(CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ var getLastMessageId = new CommandGetLastMessageId();
+ return await _executor.Execute(() => GetLastMessageId(getLastMessageId, cancellationToken), cancellationToken).ConfigureAwait(false);
+ }
+
+ private async ValueTask<MessageId> GetLastMessageId(CommandGetLastMessageId command, CancellationToken cancellationToken)
+ => await _channel.Send(command, cancellationToken).ConfigureAwait(false);
+
+ private async Task Seek(CommandSeek command, CancellationToken cancellationToken)
+ => await _channel.Send(command, cancellationToken).ConfigureAwait(false);
+
+ private async ValueTask Acknowledge(MessageId messageId, CommandAck.AckType ackType, CancellationToken cancellationToken)
+ {
+ ThrowIfDisposed();
+
+ var commandAck = _commandAckPool.Get();
+ commandAck.Type = ackType;
+ if (commandAck.MessageIds.Count == 0)
+ commandAck.MessageIds.Add(messageId.ToMessageIdData());
+ else
+ commandAck.MessageIds[0].MapFrom(messageId);
+
+ try
{
- _correlationId = correlationId;
- ServiceUrl = serviceUrl;
- SubscriptionName = subscriptionName;
- Topic = topic;
- _eventRegister = eventRegister;
- _channel = initialChannel;
- _executor = executor;
- _state = state;
- _factory = factory;
- _commandAckPool = new DefaultObjectPool<CommandAck>(new DefaultPooledObjectPolicy<CommandAck>());
- _isDisposed = 0;
-
- _eventRegister.Register(new ConsumerCreated(_correlationId));
+ await _executor.Execute(() => Acknowledge(commandAck, cancellationToken), cancellationToken).ConfigureAwait(false);
}
-
- public async ValueTask<ConsumerState> OnStateChangeTo(ConsumerState state, CancellationToken cancellationToken)
- => await _state.StateChangedTo(state, cancellationToken).ConfigureAwait(false);
-
- public async ValueTask<ConsumerState> OnStateChangeFrom(ConsumerState state, CancellationToken cancellationToken)
- => await _state.StateChangedFrom(state, cancellationToken).ConfigureAwait(false);
-
- public bool IsFinalState()
- => _state.IsFinalState();
-
- public bool IsFinalState(ConsumerState state)
- => _state.IsFinalState(state);
-
- public async ValueTask DisposeAsync()
+ finally
{
- if (Interlocked.Exchange(ref _isDisposed, 1) != 0)
- return;
-
- _eventRegister.Register(new ConsumerDisposed(_correlationId));
- await _channel.ClosedByClient(CancellationToken.None).ConfigureAwait(false);
- await _channel.DisposeAsync().ConfigureAwait(false);
+ _commandAckPool.Return(commandAck);
}
+ }
- public async ValueTask<IMessage<TMessage>> Receive(CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
+ private async ValueTask Acknowledge(CommandAck command, CancellationToken cancellationToken)
+ => await _channel.Send(command, cancellationToken).ConfigureAwait(false);
- return await _executor.Execute(() => ReceiveMessage(cancellationToken), cancellationToken).ConfigureAwait(false);
- }
+ private async ValueTask RedeliverUnacknowledgedMessages(CommandRedeliverUnacknowledgedMessages command, CancellationToken cancellationToken)
+ => await _channel.Send(command, cancellationToken).ConfigureAwait(false);
- private async ValueTask<IMessage<TMessage>> ReceiveMessage(CancellationToken cancellationToken)
- => await _channel.Receive(cancellationToken).ConfigureAwait(false);
+ private void ThrowIfDisposed()
+ {
+ if (_isDisposed != 0)
+ throw new ConsumerDisposedException(GetType().FullName!);
+ }
- public async ValueTask Acknowledge(MessageId messageId, CancellationToken cancellationToken)
- => await Acknowledge(messageId, CommandAck.AckType.Individual, cancellationToken).ConfigureAwait(false);
+ public async Task EstablishNewChannel(CancellationToken cancellationToken)
+ {
+ var channel = await _executor.Execute(() => _factory.Create(cancellationToken), cancellationToken).ConfigureAwait(false);
- public async ValueTask AcknowledgeCumulative(MessageId messageId, CancellationToken cancellationToken)
- => await Acknowledge(messageId, CommandAck.AckType.Cumulative, cancellationToken).ConfigureAwait(false);
+ var oldChannel = _channel;
+ _channel = channel;
- public async ValueTask RedeliverUnacknowledgedMessages(IEnumerable<MessageId> messageIds, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- var command = new CommandRedeliverUnacknowledgedMessages();
- command.MessageIds.AddRange(messageIds.Select(messageId => messageId.ToMessageIdData()));
- await _executor.Execute(() => RedeliverUnacknowledgedMessages(command, cancellationToken), cancellationToken).ConfigureAwait(false);
- }
-
- public async ValueTask RedeliverUnacknowledgedMessages(CancellationToken cancellationToken)
- => await RedeliverUnacknowledgedMessages(Enumerable.Empty<MessageId>(), cancellationToken).ConfigureAwait(false);
-
- public async ValueTask Unsubscribe(CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- var unsubscribe = new CommandUnsubscribe();
- await _executor.Execute(() => Unsubscribe(unsubscribe, cancellationToken), cancellationToken).ConfigureAwait(false);
- }
-
- private async ValueTask Unsubscribe(CommandUnsubscribe command, CancellationToken cancellationToken)
- => await _channel.Send(command, cancellationToken).ConfigureAwait(false);
-
- public async ValueTask Seek(MessageId messageId, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- var seek = new CommandSeek { MessageId = messageId.ToMessageIdData() };
- await _executor.Execute(() => Seek(seek, cancellationToken), cancellationToken).ConfigureAwait(false);
- }
-
- public async ValueTask Seek(ulong publishTime, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- var seek = new CommandSeek { MessagePublishTime = publishTime };
- await _executor.Execute(() => Seek(seek, cancellationToken), cancellationToken).ConfigureAwait(false);
- }
-
- public async ValueTask<MessageId> GetLastMessageId(CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- var getLastMessageId = new CommandGetLastMessageId();
- return await _executor.Execute(() => GetLastMessageId(getLastMessageId, cancellationToken), cancellationToken).ConfigureAwait(false);
- }
-
- private async ValueTask<MessageId> GetLastMessageId(CommandGetLastMessageId command, CancellationToken cancellationToken)
- => await _channel.Send(command, cancellationToken).ConfigureAwait(false);
-
- private async Task Seek(CommandSeek command, CancellationToken cancellationToken)
- => await _channel.Send(command, cancellationToken).ConfigureAwait(false);
-
- private async ValueTask Acknowledge(MessageId messageId, CommandAck.AckType ackType, CancellationToken cancellationToken)
- {
- ThrowIfDisposed();
-
- var commandAck = _commandAckPool.Get();
- commandAck.Type = ackType;
- if (commandAck.MessageIds.Count == 0)
- commandAck.MessageIds.Add(messageId.ToMessageIdData());
- else
- commandAck.MessageIds[0].MapFrom(messageId);
-
- try
- {
- await _executor.Execute(() => Acknowledge(commandAck, cancellationToken), cancellationToken).ConfigureAwait(false);
- }
- finally
- {
- _commandAckPool.Return(commandAck);
- }
- }
-
- private async ValueTask Acknowledge(CommandAck command, CancellationToken cancellationToken)
- => await _channel.Send(command, cancellationToken).ConfigureAwait(false);
-
- private async ValueTask RedeliverUnacknowledgedMessages(CommandRedeliverUnacknowledgedMessages command, CancellationToken cancellationToken)
- => await _channel.Send(command, cancellationToken).ConfigureAwait(false);
-
- private void ThrowIfDisposed()
- {
- if (_isDisposed != 0)
- throw new ConsumerDisposedException(GetType().FullName!);
- }
-
- public async Task EstablishNewChannel(CancellationToken cancellationToken)
- {
- var channel = await _executor.Execute(() => _factory.Create(cancellationToken), cancellationToken).ConfigureAwait(false);
-
- var oldChannel = _channel;
- _channel = channel;
-
- if (oldChannel is not null)
- await oldChannel.DisposeAsync().ConfigureAwait(false);
- }
+ if (oldChannel is not null)
+ await oldChannel.DisposeAsync().ConfigureAwait(false);
}
}
diff --git a/src/DotPulsar/Internal/ConsumerBuilder.cs b/src/DotPulsar/Internal/ConsumerBuilder.cs
index 3e48ece..bac10c2 100644
--- a/src/DotPulsar/Internal/ConsumerBuilder.cs
+++ b/src/DotPulsar/Internal/ConsumerBuilder.cs
@@ -12,110 +12,109 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using DotPulsar.Abstractions;
+using DotPulsar.Exceptions;
+
+public sealed class ConsumerBuilder<TMessage> : IConsumerBuilder<TMessage>
{
- using DotPulsar.Abstractions;
- using DotPulsar.Exceptions;
+ private readonly IPulsarClient _pulsarClient;
+ private readonly ISchema<TMessage> _schema;
+ private string? _consumerName;
+ private SubscriptionInitialPosition _initialPosition;
+ private int _priorityLevel;
+ private uint _messagePrefetchCount;
+ private bool _readCompacted;
+ private string? _subscriptionName;
+ private SubscriptionType _subscriptionType;
+ private string? _topic;
+ private IHandleStateChanged<ConsumerStateChanged>? _stateChangedHandler;
- public sealed class ConsumerBuilder<TMessage> : IConsumerBuilder<TMessage>
+ public ConsumerBuilder(IPulsarClient pulsarClient, ISchema<TMessage> schema)
{
- private readonly IPulsarClient _pulsarClient;
- private readonly ISchema<TMessage> _schema;
- private string? _consumerName;
- private SubscriptionInitialPosition _initialPosition;
- private int _priorityLevel;
- private uint _messagePrefetchCount;
- private bool _readCompacted;
- private string? _subscriptionName;
- private SubscriptionType _subscriptionType;
- private string? _topic;
- private IHandleStateChanged<ConsumerStateChanged>? _stateChangedHandler;
+ _schema = schema;
+ _pulsarClient = pulsarClient;
+ _initialPosition = ConsumerOptions<TMessage>.DefaultInitialPosition;
+ _priorityLevel = ConsumerOptions<TMessage>.DefaultPriorityLevel;
+ _messagePrefetchCount = ConsumerOptions<TMessage>.DefaultMessagePrefetchCount;
+ _readCompacted = ConsumerOptions<TMessage>.DefaultReadCompacted;
+ _subscriptionType = ConsumerOptions<TMessage>.DefaultSubscriptionType;
+ }
- public ConsumerBuilder(IPulsarClient pulsarClient, ISchema<TMessage> schema)
+ public IConsumerBuilder<TMessage> ConsumerName(string name)
+ {
+ _consumerName = name;
+ return this;
+ }
+
+ public IConsumerBuilder<TMessage> InitialPosition(SubscriptionInitialPosition initialPosition)
+ {
+ _initialPosition = initialPosition;
+ return this;
+ }
+
+ public IConsumerBuilder<TMessage> MessagePrefetchCount(uint count)
+ {
+ _messagePrefetchCount = count;
+ return this;
+ }
+
+ public IConsumerBuilder<TMessage> PriorityLevel(int priorityLevel)
+ {
+ _priorityLevel = priorityLevel;
+ return this;
+ }
+
+ public IConsumerBuilder<TMessage> ReadCompacted(bool readCompacted)
+ {
+ _readCompacted = readCompacted;
+ return this;
+ }
+
+ public IConsumerBuilder<TMessage> StateChangedHandler(IHandleStateChanged<ConsumerStateChanged> handler)
+ {
+ _stateChangedHandler = handler;
+ return this;
+ }
+
+ public IConsumerBuilder<TMessage> SubscriptionName(string name)
+ {
+ _subscriptionName = name;
+ return this;
+ }
+
+ public IConsumerBuilder<TMessage> SubscriptionType(SubscriptionType type)
+ {
+ _subscriptionType = type;
+ return this;
+ }
+
+ public IConsumerBuilder<TMessage> Topic(string topic)
+ {
+ _topic = topic;
+ return this;
+ }
+
+ public IConsumer<TMessage> Create()
+ {
+ if (string.IsNullOrEmpty(_subscriptionName))
+ throw new ConfigurationException("SubscriptionName may not be null or empty");
+
+ if (string.IsNullOrEmpty(_topic))
+ throw new ConfigurationException("Topic may not be null or empty");
+
+ var options = new ConsumerOptions<TMessage>(_subscriptionName!, _topic!, _schema)
{
- _schema = schema;
- _pulsarClient = pulsarClient;
- _initialPosition = ConsumerOptions<TMessage>.DefaultInitialPosition;
- _priorityLevel = ConsumerOptions<TMessage>.DefaultPriorityLevel;
- _messagePrefetchCount = ConsumerOptions<TMessage>.DefaultMessagePrefetchCount;
- _readCompacted = ConsumerOptions<TMessage>.DefaultReadCompacted;
- _subscriptionType = ConsumerOptions<TMessage>.DefaultSubscriptionType;
- }
+ ConsumerName = _consumerName,
+ InitialPosition = _initialPosition,
+ MessagePrefetchCount = _messagePrefetchCount,
+ PriorityLevel = _priorityLevel,
+ ReadCompacted = _readCompacted,
+ StateChangedHandler = _stateChangedHandler,
+ SubscriptionType = _subscriptionType
+ };
- public IConsumerBuilder<TMessage> ConsumerName(string name)
- {
- _consumerName = name;
- return this;
- }
-
- public IConsumerBuilder<TMessage> InitialPosition(SubscriptionInitialPosition initialPosition)
- {
- _initialPosition = initialPosition;
- return this;
- }
-
- public IConsumerBuilder<TMessage> MessagePrefetchCount(uint count)
- {
- _messagePrefetchCount = count;
- return this;
- }
-
- public IConsumerBuilder<TMessage> PriorityLevel(int priorityLevel)
- {
- _priorityLevel = priorityLevel;
- return this;
- }
-
- public IConsumerBuilder<TMessage> ReadCompacted(bool readCompacted)
- {
- _readCompacted = readCompacted;
- return this;
- }
-
- public IConsumerBuilder<TMessage> StateChangedHandler(IHandleStateChanged<ConsumerStateChanged> handler)
- {
- _stateChangedHandler = handler;
- return this;
- }
-
- public IConsumerBuilder<TMessage> SubscriptionName(string name)
- {
- _subscriptionName = name;
- return this;
- }
-
- public IConsumerBuilder<TMessage> SubscriptionType(SubscriptionType type)
- {
- _subscriptionType = type;
- return this;
- }
-
- public IConsumerBuilder<TMessage> Topic(string topic)
- {
- _topic = topic;
- return this;
- }
-
- public IConsumer<TMessage> Create()
- {
- if (string.IsNullOrEmpty(_subscriptionName))
- throw new ConfigurationException("SubscriptionName may not be null or empty");
-
- if (string.IsNullOrEmpty(_topic))
- throw new ConfigurationException("Topic may not be null or empty");
-
- var options = new ConsumerOptions<TMessage>(_subscriptionName!, _topic!, _schema)
- {
- ConsumerName = _consumerName,
- InitialPosition = _initialPosition,
- MessagePrefetchCount = _messagePrefetchCount,
- PriorityLevel = _priorityLevel,
- ReadCompacted = _readCompacted,
- StateChangedHandler = _stateChangedHandler,
- SubscriptionType = _subscriptionType
- };
-
- return _pulsarClient.CreateConsumer(options);
- }
+ return _pulsarClient.CreateConsumer(options);
}
}
diff --git a/src/DotPulsar/Internal/ConsumerChannel.cs b/src/DotPulsar/Internal/ConsumerChannel.cs
index 3dfe343..dadefa1 100644
--- a/src/DotPulsar/Internal/ConsumerChannel.cs
+++ b/src/DotPulsar/Internal/ConsumerChannel.cs
@@ -12,227 +12,226 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using Abstractions;
+using DotPulsar.Abstractions;
+using DotPulsar.Exceptions;
+using Extensions;
+using PulsarApi;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+public sealed class ConsumerChannel<TMessage> : IConsumerChannel<TMessage>
{
- using Abstractions;
- using DotPulsar.Abstractions;
- using DotPulsar.Exceptions;
- using Extensions;
- using PulsarApi;
- using System;
- using System.Collections.Generic;
- using System.Threading;
- using System.Threading.Tasks;
+ private readonly ulong _id;
+ private readonly AsyncQueue<MessagePackage> _queue;
+ private readonly IConnection _connection;
+ private readonly BatchHandler<TMessage> _batchHandler;
+ private readonly CommandFlow _cachedCommandFlow;
+ private readonly IMessageFactory<TMessage> _messageFactory;
+ private readonly IDecompress?[] _decompressors;
+ private readonly AsyncLock _lock;
+ private uint _sendWhenZero;
+ private bool _firstFlow;
- public sealed class ConsumerChannel<TMessage> : IConsumerChannel<TMessage>
+ public ConsumerChannel(
+ ulong id,
+ uint messagePrefetchCount,
+ AsyncQueue<MessagePackage> queue,
+ IConnection connection,
+ BatchHandler<TMessage> batchHandler,
+ IMessageFactory<TMessage> messageFactory,
+ IEnumerable<IDecompressorFactory> decompressorFactories)
{
- private readonly ulong _id;
- private readonly AsyncQueue<MessagePackage> _queue;
- private readonly IConnection _connection;
- private readonly BatchHandler<TMessage> _batchHandler;
- private readonly CommandFlow _cachedCommandFlow;
- private readonly IMessageFactory<TMessage> _messageFactory;
- private readonly IDecompress?[] _decompressors;
- private readonly AsyncLock _lock;
- private uint _sendWhenZero;
- private bool _firstFlow;
+ _id = id;
+ _queue = queue;
+ _connection = connection;
+ _batchHandler = batchHandler;
+ _messageFactory = messageFactory;
- public ConsumerChannel(
- ulong id,
- uint messagePrefetchCount,
- AsyncQueue<MessagePackage> queue,
- IConnection connection,
- BatchHandler<TMessage> batchHandler,
- IMessageFactory<TMessage> messageFactory,
- IEnumerable<IDecompressorFactory> decompressorFactories)
+ _decompressors = new IDecompress[5];
+
+ foreach (var decompressorFactory in decompressorFactories)
{
- _id = id;
- _queue = queue;
- _connection = connection;
- _batchHandler = batchHandler;
- _messageFactory = messageFactory;
-
- _decompressors = new IDecompress[5];
-
- foreach (var decompressorFactory in decompressorFactories)
- {
- _decompressors[(int) decompressorFactory.CompressionType] = decompressorFactory.Create();
- }
-
- _lock = new AsyncLock();
-
- _cachedCommandFlow = new CommandFlow
- {
- ConsumerId = id,
- MessagePermits = messagePrefetchCount
- };
-
- _sendWhenZero = 0;
- _firstFlow = true;
+ _decompressors[(int) decompressorFactory.CompressionType] = decompressorFactory.Create();
}
- public async ValueTask<IMessage<TMessage>> Receive(CancellationToken cancellationToken)
+ _lock = new AsyncLock();
+
+ _cachedCommandFlow = new CommandFlow
{
- using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ ConsumerId = id,
+ MessagePermits = messagePrefetchCount
+ };
+
+ _sendWhenZero = 0;
+ _firstFlow = true;
+ }
+
+ public async ValueTask<IMessage<TMessage>> Receive(CancellationToken cancellationToken)
+ {
+ using (await _lock.Lock(cancellationToken).ConfigureAwait(false))
+ {
+ while (true)
{
- while (true)
+ if (_sendWhenZero == 0)
+ await SendFlow(cancellationToken).ConfigureAwait(false);
+
+ _sendWhenZero--;
+
+ var message = _batchHandler.GetNext();
+
+ if (message is not null)
+ return message;
+
+ var messagePackage = await _queue.Dequeue(cancellationToken).ConfigureAwait(false);
+
+ if (!messagePackage.ValidateMagicNumberAndChecksum())
{
- if (_sendWhenZero == 0)
- await SendFlow(cancellationToken).ConfigureAwait(false);
+ await RejectPackage(messagePackage, CommandAck.ValidationErrorType.ChecksumMismatch, cancellationToken).ConfigureAwait(false);
+ continue;
+ }
- _sendWhenZero--;
+ var metadataSize = messagePackage.GetMetadataSize();
+ var metadata = messagePackage.ExtractMetadata(metadataSize);
+ var data = messagePackage.ExtractData(metadataSize);
- var message = _batchHandler.GetNext();
+ if (metadata.Compression != CompressionType.None)
+ {
+ var decompressor = _decompressors[(int) metadata.Compression];
+ if (decompressor is null)
+ throw new CompressionException($"Support for {metadata.Compression} compression was not found");
- if (message is not null)
- return message;
-
- var messagePackage = await _queue.Dequeue(cancellationToken).ConfigureAwait(false);
-
- if (!messagePackage.ValidateMagicNumberAndChecksum())
+ try
{
- await RejectPackage(messagePackage, CommandAck.ValidationErrorType.ChecksumMismatch, cancellationToken).ConfigureAwait(false);
+ data = decompressor.Decompress(data, (int) metadata.UncompressedSize);
+ }
+ catch
+ {
+ await RejectPackage(messagePackage, CommandAck.ValidationErrorType.DecompressionError, cancellationToken).ConfigureAwait(false);
continue;
}
-
- var metadataSize = messagePackage.GetMetadataSize();
- var metadata = messagePackage.ExtractMetadata(metadataSize);
- var data = messagePackage.ExtractData(metadataSize);
-
- if (metadata.Compression != CompressionType.None)
- {
- var decompressor = _decompressors[(int) metadata.Compression];
- if (decompressor is null)
- throw new CompressionException($"Support for {metadata.Compression} compression was not found");
-
- try
- {
- data = decompressor.Decompress(data, (int) metadata.UncompressedSize);
- }
- catch
- {
- await RejectPackage(messagePackage, CommandAck.ValidationErrorType.DecompressionError, cancellationToken).ConfigureAwait(false);
- continue;
- }
- }
-
- var messageId = messagePackage.MessageId;
- var redeliveryCount = messagePackage.RedeliveryCount;
-
- if (metadata.ShouldSerializeNumMessagesInBatch())
- {
- try
- {
- return _batchHandler.Add(messageId, redeliveryCount, metadata, data);
- }
- catch
- {
- await RejectPackage(messagePackage, CommandAck.ValidationErrorType.BatchDeSerializeError, cancellationToken).ConfigureAwait(false);
- continue;
- }
- }
-
- return _messageFactory.Create(messageId.ToMessageId(), redeliveryCount, data, metadata);
}
+
+ var messageId = messagePackage.MessageId;
+ var redeliveryCount = messagePackage.RedeliveryCount;
+
+ if (metadata.ShouldSerializeNumMessagesInBatch())
+ {
+ try
+ {
+ return _batchHandler.Add(messageId, redeliveryCount, metadata, data);
+ }
+ catch
+ {
+ await RejectPackage(messagePackage, CommandAck.ValidationErrorType.BatchDeSerializeError, cancellationToken).ConfigureAwait(false);
+ continue;
+ }
+ }
+
+ return _messageFactory.Create(messageId.ToMessageId(), redeliveryCount, data, metadata);
}
}
+ }
- public async Task Send(CommandAck command, CancellationToken cancellationToken)
+ public async Task Send(CommandAck command, CancellationToken cancellationToken)
+ {
+ var messageId = command.MessageIds[0];
+
+ if (messageId.BatchIndex != -1)
{
- var messageId = command.MessageIds[0];
+ var batchMessageId = _batchHandler.Acknowledge(messageId);
- if (messageId.BatchIndex != -1)
- {
- var batchMessageId = _batchHandler.Acknowledge(messageId);
+ if (batchMessageId is null)
+ return;
- if (batchMessageId is null)
- return;
-
- command.MessageIds[0] = batchMessageId;
- }
-
- command.ConsumerId = _id;
- await _connection.Send(command, cancellationToken).ConfigureAwait(false);
+ command.MessageIds[0] = batchMessageId;
}
- public async Task Send(CommandRedeliverUnacknowledgedMessages command, CancellationToken cancellationToken)
+ command.ConsumerId = _id;
+ await _connection.Send(command, cancellationToken).ConfigureAwait(false);
+ }
+
+ public async Task Send(CommandRedeliverUnacknowledgedMessages command, CancellationToken cancellationToken)
+ {
+ command.ConsumerId = _id;
+ await _connection.Send(command, cancellationToken).ConfigureAwait(false);
+ }
+
+ public async Task Send(CommandUnsubscribe command, CancellationToken cancellationToken)
+ {
+ command.ConsumerId = _id;
+ var response = await _connection.Send(command, cancellationToken).ConfigureAwait(false);
+ response.Expect(BaseCommand.Type.Success);
+ }
+
+ public async Task Send(CommandSeek command, CancellationToken cancellationToken)
+ {
+ command.ConsumerId = _id;
+ var response = await _connection.Send(command, cancellationToken).ConfigureAwait(false);
+ response.Expect(BaseCommand.Type.Success);
+ _batchHandler.Clear();
+ }
+
+ public async Task<MessageId> Send(CommandGetLastMessageId command, CancellationToken cancellationToken)
+ {
+ command.ConsumerId = _id;
+ var response = await _connection.Send(command, cancellationToken).ConfigureAwait(false);
+ response.Expect(BaseCommand.Type.GetLastMessageIdResponse);
+ return response.GetLastMessageIdResponse.LastMessageId.ToMessageId();
+ }
+
+ public async ValueTask DisposeAsync()
+ {
+ _queue.Dispose();
+
+ for (var i = 0; i < _decompressors.Length; ++i)
{
- command.ConsumerId = _id;
- await _connection.Send(command, cancellationToken).ConfigureAwait(false);
+ _decompressors[i]?.Dispose();
}
- public async Task Send(CommandUnsubscribe command, CancellationToken cancellationToken)
+ await _lock.DisposeAsync().ConfigureAwait(false);
+ }
+
+ private async ValueTask SendFlow(CancellationToken cancellationToken)
+ {
+ await _connection.Send(_cachedCommandFlow, cancellationToken).ConfigureAwait(false);
+
+ if (_firstFlow)
{
- command.ConsumerId = _id;
- var response = await _connection.Send(command, cancellationToken).ConfigureAwait(false);
- response.Expect(BaseCommand.Type.Success);
+ _cachedCommandFlow.MessagePermits = (uint) Math.Ceiling(_cachedCommandFlow.MessagePermits * 0.5);
+ _firstFlow = false;
}
- public async Task Send(CommandSeek command, CancellationToken cancellationToken)
+ _sendWhenZero = _cachedCommandFlow.MessagePermits;
+ }
+
+ private async Task RejectPackage(MessagePackage messagePackage, CommandAck.ValidationErrorType validationErrorType, CancellationToken cancellationToken)
+ {
+ var ack = new CommandAck
{
- command.ConsumerId = _id;
- var response = await _connection.Send(command, cancellationToken).ConfigureAwait(false);
- response.Expect(BaseCommand.Type.Success);
- _batchHandler.Clear();
+ Type = CommandAck.AckType.Individual,
+ ValidationError = validationErrorType
+ };
+
+ ack.MessageIds.Add(messagePackage.MessageId);
+
+ await Send(ack, cancellationToken).ConfigureAwait(false);
+ }
+
+ public async ValueTask ClosedByClient(CancellationToken cancellationToken)
+ {
+ try
+ {
+ var closeConsumer = new CommandCloseConsumer { ConsumerId = _id };
+ await _connection.Send(closeConsumer, cancellationToken).ConfigureAwait(false);
}
-
- public async Task<MessageId> Send(CommandGetLastMessageId command, CancellationToken cancellationToken)
+ catch
{
- command.ConsumerId = _id;
- var response = await _connection.Send(command, cancellationToken).ConfigureAwait(false);
- response.Expect(BaseCommand.Type.GetLastMessageIdResponse);
- return response.GetLastMessageIdResponse.LastMessageId.ToMessageId();
- }
-
- public async ValueTask DisposeAsync()
- {
- _queue.Dispose();
-
- for (var i = 0; i < _decompressors.Length; ++i)
- {
- _decompressors[i]?.Dispose();
- }
-
- await _lock.DisposeAsync().ConfigureAwait(false);
- }
-
- private async ValueTask SendFlow(CancellationToken cancellationToken)
- {
- await _connection.Send(_cachedCommandFlow, cancellationToken).ConfigureAwait(false);
-
- if (_firstFlow)
- {
- _cachedCommandFlow.MessagePermits = (uint) Math.Ceiling(_cachedCommandFlow.MessagePermits * 0.5);
- _firstFlow = false;
- }
-
- _sendWhenZero = _cachedCommandFlow.MessagePermits;
- }
-
- private async Task RejectPackage(MessagePackage messagePackage, CommandAck.ValidationErrorType validationErrorType, CancellationToken cancellationToken)
- {
- var ack = new CommandAck
- {
- Type = CommandAck.AckType.Individual,
- ValidationError = validationErrorType
- };
-
- ack.MessageIds.Add(messagePackage.MessageId);
-
- await Send(ack, cancellationToken).ConfigureAwait(false);
- }
-
- public async ValueTask ClosedByClient(CancellationToken cancellationToken)
- {
- try
- {
- var closeConsumer = new CommandCloseConsumer { ConsumerId = _id };
- await _connection.Send(closeConsumer, cancellationToken).ConfigureAwait(false);
- }
- catch
- {
- // Ignore
- }
+ // Ignore
}
}
}
diff --git a/src/DotPulsar/Internal/ConsumerChannelFactory.cs b/src/DotPulsar/Internal/ConsumerChannelFactory.cs
index 24954f7..69de5ac 100644
--- a/src/DotPulsar/Internal/ConsumerChannelFactory.cs
+++ b/src/DotPulsar/Internal/ConsumerChannelFactory.cs
@@ -12,53 +12,52 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using Abstractions;
+using PulsarApi;
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+public sealed class ConsumerChannelFactory<TMessage> : IConsumerChannelFactory<TMessage>
{
- using Abstractions;
- using PulsarApi;
- using System;
- using System.Collections.Generic;
- using System.Threading;
- using System.Threading.Tasks;
+ private readonly Guid _correlationId;
+ private readonly IRegisterEvent _eventRegister;
+ private readonly IConnectionPool _connectionPool;
+ private readonly CommandSubscribe _subscribe;
+ private readonly uint _messagePrefetchCount;
+ private readonly BatchHandler<TMessage> _batchHandler;
+ private readonly IMessageFactory<TMessage> _messageFactory;
+ private readonly IEnumerable<IDecompressorFactory> _decompressorFactories;
- public sealed class ConsumerChannelFactory<TMessage> : IConsumerChannelFactory<TMessage>
+ public ConsumerChannelFactory(
+ Guid correlationId,
+ IRegisterEvent eventRegister,
+ IConnectionPool connectionPool,
+ CommandSubscribe subscribe,
+ uint messagePrefetchCount,
+ BatchHandler<TMessage> batchHandler,
+ IMessageFactory<TMessage> messageFactory,
+ IEnumerable<IDecompressorFactory> decompressorFactories)
{
- private readonly Guid _correlationId;
- private readonly IRegisterEvent _eventRegister;
- private readonly IConnectionPool _connectionPool;
- private readonly CommandSubscribe _subscribe;
- private readonly uint _messagePrefetchCount;
- private readonly BatchHandler<TMessage> _batchHandler;
- private readonly IMessageFactory<TMessage> _messageFactory;
- private readonly IEnumerable<IDecompressorFactory> _decompressorFactories;
+ _correlationId = correlationId;
+ _eventRegister = eventRegister;
+ _connectionPool = connectionPool;
+ _subscribe = subscribe;
+ _messagePrefetchCount = messagePrefetchCount;
+ _batchHandler = batchHandler;
+ _messageFactory = messageFactory;
+ _decompressorFactories = decompressorFactories;
+ }
- public ConsumerChannelFactory(
- Guid correlationId,
- IRegisterEvent eventRegister,
- IConnectionPool connectionPool,
- CommandSubscribe subscribe,
- uint messagePrefetchCount,
- BatchHandler<TMessage> batchHandler,
- IMessageFactory<TMessage> messageFactory,
- IEnumerable<IDecompressorFactory> decompressorFactories)
- {
- _correlationId = correlationId;
- _eventRegister = eventRegister;
- _connectionPool = connectionPool;
- _subscribe = subscribe;
- _messagePrefetchCount = messagePrefetchCount;
- _batchHandler = batchHandler;
- _messageFactory = messageFactory;
- _decompressorFactories = decompressorFactories;
- }
-
- public async Task<IConsumerChannel<TMessage>> Create(CancellationToken cancellationToken)
- {
- var connection = await _connectionPool.FindConnectionForTopic(_subscribe.Topic, cancellationToken).ConfigureAwait(false);
- var messageQueue = new AsyncQueue<MessagePackage>();
- var channel = new Channel(_correlationId, _eventRegister, messageQueue);
- var response = await connection.Send(_subscribe, channel, cancellationToken).ConfigureAwait(false);
- return new ConsumerChannel<TMessage>(response.ConsumerId, _messagePrefetchCount, messageQueue, connection, _batchHandler, _messageFactory, _decompressorFactories);
- }
+ public async Task<IConsumerChannel<TMessage>> Create(CancellationToken cancellationToken)
+ {
+ var connection = await _connectionPool.FindConnectionForTopic(_subscribe.Topic, cancellationToken).ConfigureAwait(false);
+ var messageQueue = new AsyncQueue<MessagePackage>();
+ var channel = new Channel(_correlationId, _eventRegister, messageQueue);
+ var response = await connection.Send(_subscribe, channel, cancellationToken).ConfigureAwait(false);
+ return new ConsumerChannel<TMessage>(response.ConsumerId, _messagePrefetchCount, messageQueue, connection, _batchHandler, _messageFactory, _decompressorFactories);
}
}
diff --git a/src/DotPulsar/Internal/ConsumerProcess.cs b/src/DotPulsar/Internal/ConsumerProcess.cs
index f2296c2..af2ef22 100644
--- a/src/DotPulsar/Internal/ConsumerProcess.cs
+++ b/src/DotPulsar/Internal/ConsumerProcess.cs
@@ -12,71 +12,70 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using Abstractions;
+using System;
+using System.Threading.Tasks;
+
+public sealed class ConsumerProcess : Process
{
- using Abstractions;
- using System;
- using System.Threading.Tasks;
+ private readonly IStateManager<ConsumerState> _stateManager;
+ private readonly IEstablishNewChannel _consumer;
+ private readonly bool _isFailoverSubscription;
- public sealed class ConsumerProcess : Process
+ public ConsumerProcess(
+ Guid correlationId,
+ IStateManager<ConsumerState> stateManager,
+ IEstablishNewChannel consumer,
+ bool isFailoverSubscription) : base(correlationId)
{
- private readonly IStateManager<ConsumerState> _stateManager;
- private readonly IEstablishNewChannel _consumer;
- private readonly bool _isFailoverSubscription;
+ _stateManager = stateManager;
+ _consumer = consumer;
+ _isFailoverSubscription = isFailoverSubscription;
+ }
- public ConsumerProcess(
- Guid correlationId,
- IStateManager<ConsumerState> stateManager,
- IEstablishNewChannel consumer,
- bool isFailoverSubscription) : base(correlationId)
+ public override async ValueTask DisposeAsync()
+ {
+ _stateManager.SetState(ConsumerState.Closed);
+ CancellationTokenSource.Cancel();
+ await _consumer.DisposeAsync().ConfigureAwait(false);
+ }
+
+ protected override void CalculateState()
+ {
+ if (_stateManager.IsFinalState())
+ return;
+
+ if (ExecutorState == ExecutorState.Faulted)
{
- _stateManager = stateManager;
- _consumer = consumer;
- _isFailoverSubscription = isFailoverSubscription;
+ _stateManager.SetState(ConsumerState.Faulted);
+ return;
}
- public override async ValueTask DisposeAsync()
+ switch (ChannelState)
{
- _stateManager.SetState(ConsumerState.Closed);
- CancellationTokenSource.Cancel();
- await _consumer.DisposeAsync().ConfigureAwait(false);
- }
-
- protected override void CalculateState()
- {
- if (_stateManager.IsFinalState())
+ case ChannelState.Active:
+ _stateManager.SetState(ConsumerState.Active);
return;
-
- if (ExecutorState == ExecutorState.Faulted)
- {
- _stateManager.SetState(ConsumerState.Faulted);
+ case ChannelState.Inactive:
+ _stateManager.SetState(ConsumerState.Inactive);
return;
- }
-
- switch (ChannelState)
- {
- case ChannelState.Active:
+ case ChannelState.ClosedByServer:
+ case ChannelState.Disconnected:
+ _stateManager.SetState(ConsumerState.Disconnected);
+ _ = _consumer.EstablishNewChannel(CancellationTokenSource.Token);
+ return;
+ case ChannelState.Connected:
+ if (!_isFailoverSubscription)
_stateManager.SetState(ConsumerState.Active);
- return;
- case ChannelState.Inactive:
- _stateManager.SetState(ConsumerState.Inactive);
- return;
- case ChannelState.ClosedByServer:
- case ChannelState.Disconnected:
- _stateManager.SetState(ConsumerState.Disconnected);
- _ = _consumer.EstablishNewChannel(CancellationTokenSource.Token);
- return;
- case ChannelState.Connected:
- if (!_isFailoverSubscription)
- _stateManager.SetState(ConsumerState.Active);
- return;
- case ChannelState.ReachedEndOfTopic:
- _stateManager.SetState(ConsumerState.ReachedEndOfTopic);
- return;
- case ChannelState.Unsubscribed:
- _stateManager.SetState(ConsumerState.Unsubscribed);
- return;
- }
+ return;
+ case ChannelState.ReachedEndOfTopic:
+ _stateManager.SetState(ConsumerState.ReachedEndOfTopic);
+ return;
+ case ChannelState.Unsubscribed:
+ _stateManager.SetState(ConsumerState.Unsubscribed);
+ return;
}
}
}
diff --git a/src/DotPulsar/Internal/Crc32C.cs b/src/DotPulsar/Internal/Crc32C.cs
index 63d641a..fa82bca 100644
--- a/src/DotPulsar/Internal/Crc32C.cs
+++ b/src/DotPulsar/Internal/Crc32C.cs
@@ -12,82 +12,81 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using System.Buffers;
+
+public static class Crc32C
{
- using System.Buffers;
+ private const uint _generator = 0x82F63B78u;
- public static class Crc32C
+ private static readonly uint[] _lookup;
+
+ static Crc32C()
{
- private const uint _generator = 0x82F63B78u;
+ _lookup = new uint[16 * 256];
- private static readonly uint[] _lookup;
-
- static Crc32C()
+ for (uint i = 0; i < 256; i++)
{
- _lookup = new uint[16 * 256];
+ var entry = i;
- for (uint i = 0; i < 256; i++)
+ for (var j = 0; j < 16; j++)
{
- var entry = i;
+ for (var k = 0; k < 8; k++)
+ entry = (entry & 1) == 1 ? _generator ^ (entry >> 1) : entry >> 1;
- for (var j = 0; j < 16; j++)
+ _lookup[j * 256 + i] = entry;
+ }
+ }
+ }
+
+ public static uint Calculate(ReadOnlySequence<byte> sequence)
+ {
+ var block = new uint[16];
+ var checksum = uint.MaxValue;
+ var remaningBytes = sequence.Length;
+ var readingBlock = remaningBytes >= 16;
+ var offset = 15;
+
+ foreach (var memory in sequence)
+ {
+ var span = memory.Span;
+
+ for (var i = 0; i < span.Length; ++i)
+ {
+ var currentByte = span[i];
+
+ if (!readingBlock)
{
- for (var k = 0; k < 8; k++)
- entry = (entry & 1) == 1 ? _generator ^ (entry >> 1) : entry >> 1;
+ checksum = _lookup[(byte) (checksum ^ currentByte)] ^ (checksum >> 8);
+ continue;
+ }
- _lookup[j * 256 + i] = entry;
+ var offSetBase = offset * 256;
+
+ if (offset > 11)
+ block[offset] = _lookup[offSetBase + ((byte) (checksum >> (8 * (15 - offset))) ^ currentByte)];
+ else
+ block[offset] = _lookup[offSetBase + currentByte];
+
+ --remaningBytes;
+
+ if (offset == 0)
+ {
+ offset = 15;
+ readingBlock = remaningBytes >= 16;
+ checksum = 0;
+
+ for (var j = 0; j < block.Length; ++j)
+ checksum ^= block[j];
+ }
+ else
+ {
+ --offset;
}
}
}
- public static uint Calculate(ReadOnlySequence<byte> sequence)
- {
- var block = new uint[16];
- var checksum = uint.MaxValue;
- var remaningBytes = sequence.Length;
- var readingBlock = remaningBytes >= 16;
- var offset = 15;
-
- foreach (var memory in sequence)
- {
- var span = memory.Span;
-
- for (var i = 0; i < span.Length; ++i)
- {
- var currentByte = span[i];
-
- if (!readingBlock)
- {
- checksum = _lookup[(byte) (checksum ^ currentByte)] ^ (checksum >> 8);
- continue;
- }
-
- var offSetBase = offset * 256;
-
- if (offset > 11)
- block[offset] = _lookup[offSetBase + ((byte) (checksum >> (8 * (15 - offset))) ^ currentByte)];
- else
- block[offset] = _lookup[offSetBase + currentByte];
-
- --remaningBytes;
-
- if (offset == 0)
- {
- offset = 15;
- readingBlock = remaningBytes >= 16;
- checksum = 0;
-
- for (var j = 0; j < block.Length; ++j)
- checksum ^= block[j];
- }
- else
- {
- --offset;
- }
- }
- }
-
- return checksum ^ uint.MaxValue;
- }
+ return checksum ^ uint.MaxValue;
}
}
diff --git a/src/DotPulsar/Internal/DefaultExceptionHandler.cs b/src/DotPulsar/Internal/DefaultExceptionHandler.cs
index c064153..f143ead 100644
--- a/src/DotPulsar/Internal/DefaultExceptionHandler.cs
+++ b/src/DotPulsar/Internal/DefaultExceptionHandler.cs
@@ -12,55 +12,54 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using DotPulsar.Abstractions;
+using DotPulsar.Exceptions;
+using Exceptions;
+using System;
+using System.Net.Sockets;
+using System.Threading;
+using System.Threading.Tasks;
+
+public sealed class DefaultExceptionHandler : IHandleException
{
- using DotPulsar.Abstractions;
- using DotPulsar.Exceptions;
- using Exceptions;
- using System;
- using System.Net.Sockets;
- using System.Threading;
- using System.Threading.Tasks;
+ private readonly TimeSpan _retryInterval;
- public sealed class DefaultExceptionHandler : IHandleException
+ public DefaultExceptionHandler(TimeSpan retryInterval)
+ => _retryInterval = retryInterval;
+
+ public async ValueTask OnException(ExceptionContext exceptionContext)
{
- private readonly TimeSpan _retryInterval;
+ exceptionContext.Result = DetermineFaultAction(exceptionContext.Exception, exceptionContext.CancellationToken);
- public DefaultExceptionHandler(TimeSpan retryInterval)
- => _retryInterval = retryInterval;
+ if (exceptionContext.Result == FaultAction.Retry)
+ await Task.Delay(_retryInterval, exceptionContext.CancellationToken).ConfigureAwait(false);
- public async ValueTask OnException(ExceptionContext exceptionContext)
- {
- exceptionContext.Result = DetermineFaultAction(exceptionContext.Exception, exceptionContext.CancellationToken);
-
- if (exceptionContext.Result == FaultAction.Retry)
- await Task.Delay(_retryInterval, exceptionContext.CancellationToken).ConfigureAwait(false);
-
- exceptionContext.ExceptionHandled = true;
- }
-
- private static FaultAction DetermineFaultAction(Exception exception, CancellationToken cancellationToken)
- => exception switch
- {
- TooManyRequestsException _ => FaultAction.Retry,
- ChannelNotReadyException _ => FaultAction.Retry,
- ServiceNotReadyException _ => FaultAction.Retry,
- MetadataException _ => FaultAction.Rethrow,
- ConsumerNotFoundException _ => FaultAction.Retry,
- ConnectionDisposedException _ => FaultAction.Retry,
- AsyncLockDisposedException _ => FaultAction.Retry,
- PulsarStreamDisposedException _ => FaultAction.Retry,
- AsyncQueueDisposedException _ => FaultAction.Retry,
- OperationCanceledException _ => cancellationToken.IsCancellationRequested ? FaultAction.Rethrow : FaultAction.Retry,
- DotPulsarException _ => FaultAction.Rethrow,
- SocketException socketException => socketException.SocketErrorCode switch
- {
- SocketError.HostNotFound => FaultAction.Rethrow,
- SocketError.HostUnreachable => FaultAction.Rethrow,
- SocketError.NetworkUnreachable => FaultAction.Rethrow,
- _ => FaultAction.Retry
- },
- _ => FaultAction.Rethrow
- };
+ exceptionContext.ExceptionHandled = true;
}
+
+ private static FaultAction DetermineFaultAction(Exception exception, CancellationToken cancellationToken)
+ => exception switch
+ {
+ TooManyRequestsException _ => FaultAction.Retry,
+ ChannelNotReadyException _ => FaultAction.Retry,
+ ServiceNotReadyException _ => FaultAction.Retry,
+ MetadataException _ => FaultAction.Rethrow,
+ ConsumerNotFoundException _ => FaultAction.Retry,
+ ConnectionDisposedException _ => FaultAction.Retry,
+ AsyncLockDisposedException _ => FaultAction.Retry,
+ PulsarStreamDisposedException _ => FaultAction.Retry,
+ AsyncQueueDisposedException _ => FaultAction.Retry,
+ OperationCanceledException _ => cancellationToken.IsCancellationRequested ? FaultAction.Rethrow : FaultAction.Retry,
+ DotPulsarException _ => FaultAction.Rethrow,
+ SocketException socketException => socketException.SocketErrorCode switch
+ {
+ SocketError.HostNotFound => FaultAction.Rethrow,
+ SocketError.HostUnreachable => FaultAction.Rethrow,
+ SocketError.NetworkUnreachable => FaultAction.Rethrow,
+ _ => FaultAction.Retry
+ },
+ _ => FaultAction.Rethrow
+ };
}
diff --git a/src/DotPulsar/Internal/DotPulsarActivitySource.cs b/src/DotPulsar/Internal/DotPulsarActivitySource.cs
index 87e2c3e..4f4c163 100644
--- a/src/DotPulsar/Internal/DotPulsarActivitySource.cs
+++ b/src/DotPulsar/Internal/DotPulsarActivitySource.cs
@@ -12,72 +12,71 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using DotPulsar.Abstractions;
+using System.Collections.Generic;
+using System.Diagnostics;
+
+public static class DotPulsarActivitySource
{
- using DotPulsar.Abstractions;
- using System.Collections.Generic;
- using System.Diagnostics;
+ private const string _traceParent = "traceparent";
+ private const string _traceState = "tracestate";
- public static class DotPulsarActivitySource
+ static DotPulsarActivitySource()
{
- private const string _traceParent = "traceparent";
- private const string _traceState = "tracestate";
+ ActivitySource = new ActivitySource(Constants.ClientName, Constants.ClientVersion);
+ }
- static DotPulsarActivitySource()
+ public static ActivitySource ActivitySource { get; }
+
+ public static Activity? StartConsumerActivity(IMessage message, string operationName, KeyValuePair<string, object?>[] tags)
+ {
+ if (!ActivitySource.HasListeners())
+ return null;
+
+ var properties = message.Properties;
+
+ if (properties.TryGetValue(_traceParent, out var traceparent))
{
- ActivitySource = new ActivitySource(Constants.ClientName, Constants.ClientVersion);
+ var tracestate = properties.ContainsKey(_traceState) ? properties[_traceState] : null;
+ if (ActivityContext.TryParse(traceparent, tracestate, out var activityContext))
+ return ActivitySource.StartActivity(operationName, ActivityKind.Consumer, activityContext, tags);
}
- public static ActivitySource ActivitySource { get; }
+ var activity = ActivitySource.StartActivity(operationName, ActivityKind.Consumer);
- public static Activity? StartConsumerActivity(IMessage message, string operationName, KeyValuePair<string, object?>[] tags)
+ if (activity is not null && activity.IsAllDataRequested)
{
- if (!ActivitySource.HasListeners())
- return null;
-
- var properties = message.Properties;
-
- if (properties.TryGetValue(_traceParent, out var traceparent))
+ for (var i = 0; i < tags.Length; ++i)
{
- var tracestate = properties.ContainsKey(_traceState) ? properties[_traceState] : null;
- if (ActivityContext.TryParse(traceparent, tracestate, out var activityContext))
- return ActivitySource.StartActivity(operationName, ActivityKind.Consumer, activityContext, tags);
+ var tag = tags[i];
+ activity.SetTag(tag.Key, tag.Value);
}
-
- var activity = ActivitySource.StartActivity(operationName, ActivityKind.Consumer);
-
- if (activity is not null && activity.IsAllDataRequested)
- {
- for (var i = 0; i < tags.Length; ++i)
- {
- var tag = tags[i];
- activity.SetTag(tag.Key, tag.Value);
- }
- }
-
- return activity;
}
- public static Activity? StartProducerActivity(MessageMetadata metadata, string operationName, KeyValuePair<string, object?>[] tags)
+ return activity;
+ }
+
+ public static Activity? StartProducerActivity(MessageMetadata metadata, string operationName, KeyValuePair<string, object?>[] tags)
+ {
+ if (!ActivitySource.HasListeners())
+ return null;
+
+ var activity = ActivitySource.StartActivity(operationName, ActivityKind.Producer);
+
+ if (activity is not null && activity.IsAllDataRequested)
{
- if (!ActivitySource.HasListeners())
- return null;
+ metadata[_traceParent] = activity.TraceId.ToHexString();
+ metadata[_traceState] = activity.TraceStateString;
- var activity = ActivitySource.StartActivity(operationName, ActivityKind.Producer);
-
- if (activity is not null && activity.IsAllDataRequested)
+ for (var i = 0; i < tags.Length; ++i)
{
- metadata[_traceParent] = activity.TraceId.ToHexString();
- metadata[_traceState] = activity.TraceStateString;
-
- for (var i = 0; i < tags.Length; ++i)
- {
- var tag = tags[i];
- activity.SetTag(tag.Key, tag.Value);
- }
+ var tag = tags[i];
+ activity.SetTag(tag.Key, tag.Value);
}
-
- return activity;
}
+
+ return activity;
}
}
diff --git a/src/DotPulsar/Internal/DotPulsarEventSource.cs b/src/DotPulsar/Internal/DotPulsarEventSource.cs
index a988189..5547b07 100644
--- a/src/DotPulsar/Internal/DotPulsarEventSource.cs
+++ b/src/DotPulsar/Internal/DotPulsarEventSource.cs
@@ -12,186 +12,185 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
-{
+namespace DotPulsar.Internal;
+
#if NETSTANDARD2_0
- public sealed class DotPulsarEventSource
- {
- public static readonly DotPulsarEventSource Log = new();
+public sealed class DotPulsarEventSource
+{
+ public static readonly DotPulsarEventSource Log = new();
- public void ClientCreated() { }
+ public void ClientCreated() { }
- public void ClientDisposed() { }
+ public void ClientDisposed() { }
- public void ConnectionCreated() { }
+ public void ConnectionCreated() { }
- public void ConnectionDisposed() { }
+ public void ConnectionDisposed() { }
- public void ConsumerCreated() { }
+ public void ConsumerCreated() { }
- public void ConsumerDisposed() { }
+ public void ConsumerDisposed() { }
- public void ProducerCreated() { }
+ public void ProducerCreated() { }
- public void ProducerDisposed() { }
+ public void ProducerDisposed() { }
- public void ReaderCreated() { }
+ public void ReaderCreated() { }
- public void ReaderDisposed() { }
- }
+ public void ReaderDisposed() { }
+}
#else
- using System.Diagnostics.Tracing;
- using System.Threading;
+using System.Diagnostics.Tracing;
+using System.Threading;
- public sealed class DotPulsarEventSource : EventSource
- {
+public sealed class DotPulsarEventSource : EventSource
+{
#pragma warning disable IDE0052 // Remove unread private members
- private PollingCounter? _totalClientsCounter;
- private long _totalClients;
+ private PollingCounter? _totalClientsCounter;
+ private long _totalClients;
- private PollingCounter? _currentClientsCounter;
- private long _currentClients;
+ private PollingCounter? _currentClientsCounter;
+ private long _currentClients;
- private PollingCounter? _totalConnectionsCounter;
- private long _totalConnections;
+ private PollingCounter? _totalConnectionsCounter;
+ private long _totalConnections;
- private PollingCounter? _currentConnectionsCounter;
- private long _currentConnections;
+ private PollingCounter? _currentConnectionsCounter;
+ private long _currentConnections;
- private PollingCounter? _totalConsumersCounter;
- private long _totalConsumers;
+ private PollingCounter? _totalConsumersCounter;
+ private long _totalConsumers;
- private PollingCounter? _currentConsumersCounter;
- private long _currentConsumers;
+ private PollingCounter? _currentConsumersCounter;
+ private long _currentConsumers;
- private PollingCounter? _totalProducersCounter;
- private long _totalProducers;
+ private PollingCounter? _totalProducersCounter;
+ private long _totalProducers;
- private PollingCounter? _currentProducersCounter;
- private long _currentProducers;
+ private PollingCounter? _currentProducersCounter;
+ private long _currentProducers;
- private PollingCounter? _totalReadersCounter;
- private long _totalReaders;
+ private PollingCounter? _totalReadersCounter;
+ private long _totalReaders;
- private PollingCounter? _currentReadersCounter;
- private long _currentReaders;
+ private PollingCounter? _currentReadersCounter;
+ private long _currentReaders;
#pragma warning restore IDE0052 // Remove unread private members
- public static readonly DotPulsarEventSource Log = new();
+ public static readonly DotPulsarEventSource Log = new();
- public DotPulsarEventSource() : base("DotPulsar") { }
+ public DotPulsarEventSource() : base("DotPulsar") { }
- public void ClientCreated()
- {
- Interlocked.Increment(ref _totalClients);
- Interlocked.Increment(ref _currentClients);
- }
-
- public void ClientDisposed()
- {
- Interlocked.Decrement(ref _currentClients);
- }
-
- public void ConnectionCreated()
- {
- Interlocked.Increment(ref _totalConnections);
- Interlocked.Increment(ref _currentConnections);
- }
-
- public void ConnectionDisposed()
- {
- Interlocked.Decrement(ref _currentConnections);
- }
-
- public void ConsumerCreated()
- {
- Interlocked.Increment(ref _totalConsumers);
- Interlocked.Increment(ref _currentConsumers);
- }
-
- public void ConsumerDisposed()
- {
- Interlocked.Decrement(ref _currentConsumers);
- }
-
- public void ProducerCreated()
- {
- Interlocked.Increment(ref _totalProducers);
- Interlocked.Increment(ref _currentProducers);
- }
-
- public void ProducerDisposed()
- {
- Interlocked.Decrement(ref _currentProducers);
- }
-
- public void ReaderCreated()
- {
- Interlocked.Increment(ref _totalReaders);
- Interlocked.Increment(ref _currentReaders);
- }
-
- public void ReaderDisposed()
- {
- Interlocked.Decrement(ref _currentReaders);
- }
-
- protected override void OnEventCommand(EventCommandEventArgs command)
- {
- if (command.Command != EventCommand.Enable)
- return;
-
- _totalClientsCounter ??= new PollingCounter("total-clients", this, () => Volatile.Read(ref _totalClients))
- {
- DisplayName = "Total number of clients"
- };
-
- _currentClientsCounter ??= new PollingCounter("current-clients", this, () => Volatile.Read(ref _currentClients))
- {
- DisplayName = "Current number of clients"
- };
-
- _totalConnectionsCounter ??= new PollingCounter("total-connections", this, () => Volatile.Read(ref _totalConnections))
- {
- DisplayName = "Total number of connections"
- };
-
- _currentConnectionsCounter ??= new PollingCounter("current-connections", this, () => Volatile.Read(ref _currentConnections))
- {
- DisplayName = "Current number of connections"
- };
-
- _totalConsumersCounter ??= new PollingCounter("total-consumers", this, () => Volatile.Read(ref _totalConsumers))
- {
- DisplayName = "Total number of consumers"
- };
-
- _currentConsumersCounter ??= new PollingCounter("current-consumers", this, () => Volatile.Read(ref _currentConsumers))
- {
- DisplayName = "Current number of consumers"
- };
-
- _totalProducersCounter ??= new PollingCounter("total-producers", this, () => Volatile.Read(ref _totalProducers))
- {
- DisplayName = "Total number of producers"
- };
-
- _currentProducersCounter ??= new PollingCounter("current-producers", this, () => Volatile.Read(ref _currentProducers))
- {
- DisplayName = "Current number of producers"
- };
-
- _totalReadersCounter ??= new PollingCounter("total-readers", this, () => Volatile.Read(ref _totalReaders))
- {
- DisplayName = "Total number of readers"
- };
-
- _currentReadersCounter ??= new PollingCounter("current-readers", this, () => Volatile.Read(ref _currentReaders))
- {
- DisplayName = "Current number of readers"
- };
- }
+ public void ClientCreated()
+ {
+ Interlocked.Increment(ref _totalClients);
+ Interlocked.Increment(ref _currentClients);
}
-#endif
+
+ public void ClientDisposed()
+ {
+ Interlocked.Decrement(ref _currentClients);
+ }
+
+ public void ConnectionCreated()
+ {
+ Interlocked.Increment(ref _totalConnections);
+ Interlocked.Increment(ref _currentConnections);
+ }
+
+ public void ConnectionDisposed()
+ {
+ Interlocked.Decrement(ref _currentConnections);
+ }
+
+ public void ConsumerCreated()
+ {
+ Interlocked.Increment(ref _totalConsumers);
+ Interlocked.Increment(ref _currentConsumers);
+ }
+
+ public void ConsumerDisposed()
+ {
+ Interlocked.Decrement(ref _currentConsumers);
+ }
+
+ public void ProducerCreated()
+ {
+ Interlocked.Increment(ref _totalProducers);
+ Interlocked.Increment(ref _currentProducers);
+ }
+
+ public void ProducerDisposed()
+ {
+ Interlocked.Decrement(ref _currentProducers);
+ }
+
+ public void ReaderCreated()
+ {
+ Interlocked.Increment(ref _totalReaders);
+ Interlocked.Increment(ref _currentReaders);
+ }
+
+ public void ReaderDisposed()
+ {
+ Interlocked.Decrement(ref _currentReaders);
+ }
+
+ protected override void OnEventCommand(EventCommandEventArgs command)
+ {
+ if (command.Command != EventCommand.Enable)
+ return;
+
+ _totalClientsCounter ??= new PollingCounter("total-clients", this, () => Volatile.Read(ref _totalClients))
+ {
+ DisplayName = "Total number of clients"
+ };
+
+ _currentClientsCounter ??= new PollingCounter("current-clients", this, () => Volatile.Read(ref _currentClients))
+ {
+ DisplayName = "Current number of clients"
+ };
+
+ _totalConnectionsCounter ??= new PollingCounter("total-connections", this, () => Volatile.Read(ref _totalConnections))
+ {
+ DisplayName = "Total number of connections"
+ };
+
+ _currentConnectionsCounter ??= new PollingCounter("current-connections", this, () => Volatile.Read(ref _currentConnections))
+ {
+ DisplayName = "Current number of connections"
+ };
+
+ _totalConsumersCounter ??= new PollingCounter("total-consumers", this, () => Volatile.Read(ref _totalConsumers))
+ {
+ DisplayName = "Total number of consumers"
+ };
+
+ _currentConsumersCounter ??= new PollingCounter("current-consumers", this, () => Volatile.Read(ref _currentConsumers))
+ {
+ DisplayName = "Current number of consumers"
+ };
+
+ _totalProducersCounter ??= new PollingCounter("total-producers", this, () => Volatile.Read(ref _totalProducers))
+ {
+ DisplayName = "Total number of producers"
+ };
+
+ _currentProducersCounter ??= new PollingCounter("current-producers", this, () => Volatile.Read(ref _currentProducers))
+ {
+ DisplayName = "Current number of producers"
+ };
+
+ _totalReadersCounter ??= new PollingCounter("total-readers", this, () => Volatile.Read(ref _totalReaders))
+ {
+ DisplayName = "Total number of readers"
+ };
+
+ _currentReadersCounter ??= new PollingCounter("current-readers", this, () => Volatile.Read(ref _currentReaders))
+ {
+ DisplayName = "Current number of readers"
+ };
+ }
}
+#endif
diff --git a/src/DotPulsar/Internal/EnumLookup.cs b/src/DotPulsar/Internal/EnumLookup.cs
index 5d7bc33..009d2c1 100644
--- a/src/DotPulsar/Internal/EnumLookup.cs
+++ b/src/DotPulsar/Internal/EnumLookup.cs
@@ -12,28 +12,27 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using System;
+using System.Linq;
+using System.Runtime.CompilerServices;
+
+public sealed class EnumLookup<TKey, TValue> where TKey : Enum
{
- using System;
- using System.Linq;
- using System.Runtime.CompilerServices;
+ private readonly TValue[] _values;
- public sealed class EnumLookup<TKey, TValue> where TKey : Enum
+ public EnumLookup(TValue defaultValue)
{
- private readonly TValue[] _values;
-
- public EnumLookup(TValue defaultValue)
- {
- var max = Enum.GetValues(typeof(TKey)).Cast<int>().Max() + 1;
- _values = new TValue[max];
- for (var i = 0; i < max; ++i)
- _values[i] = defaultValue;
- }
-
- public void Set(TKey key, TValue value)
- => _values[Unsafe.As<TKey, int>(ref key)] = value;
-
- public TValue Get(TKey key)
- => _values[Unsafe.As<TKey, int>(ref key)];
+ var max = Enum.GetValues(typeof(TKey)).Cast<int>().Max() + 1;
+ _values = new TValue[max];
+ for (var i = 0; i < max; ++i)
+ _values[i] = defaultValue;
}
+
+ public void Set(TKey key, TValue value)
+ => _values[Unsafe.As<TKey, int>(ref key)] = value;
+
+ public TValue Get(TKey key)
+ => _values[Unsafe.As<TKey, int>(ref key)];
}
diff --git a/src/DotPulsar/Internal/Events/ChannelActivated.cs b/src/DotPulsar/Internal/Events/ChannelActivated.cs
index 1300e24..506ee8a 100644
--- a/src/DotPulsar/Internal/Events/ChannelActivated.cs
+++ b/src/DotPulsar/Internal/Events/ChannelActivated.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Events
+namespace DotPulsar.Internal.Events;
+
+using Abstractions;
+using System;
+
+public sealed class ChannelActivated : IEvent
{
- using Abstractions;
- using System;
+ public ChannelActivated(Guid correlationId)
+ => CorrelationId = correlationId;
- public sealed class ChannelActivated : IEvent
- {
- public ChannelActivated(Guid correlationId)
- => CorrelationId = correlationId;
-
- public Guid CorrelationId { get; }
- }
+ public Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/Events/ChannelClosedByServer.cs b/src/DotPulsar/Internal/Events/ChannelClosedByServer.cs
index 274f45c..a5ed6d0 100644
--- a/src/DotPulsar/Internal/Events/ChannelClosedByServer.cs
+++ b/src/DotPulsar/Internal/Events/ChannelClosedByServer.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Events
+namespace DotPulsar.Internal.Events;
+
+using Abstractions;
+using System;
+
+public sealed class ChannelClosedByServer : IEvent
{
- using Abstractions;
- using System;
+ public ChannelClosedByServer(Guid correlationId)
+ => CorrelationId = correlationId;
- public sealed class ChannelClosedByServer : IEvent
- {
- public ChannelClosedByServer(Guid correlationId)
- => CorrelationId = correlationId;
-
- public Guid CorrelationId { get; }
- }
+ public Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/Events/ChannelConnected.cs b/src/DotPulsar/Internal/Events/ChannelConnected.cs
index 6640d62..20ef3d2 100644
--- a/src/DotPulsar/Internal/Events/ChannelConnected.cs
+++ b/src/DotPulsar/Internal/Events/ChannelConnected.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Events
+namespace DotPulsar.Internal.Events;
+
+using Abstractions;
+using System;
+
+public sealed class ChannelConnected : IEvent
{
- using Abstractions;
- using System;
+ public ChannelConnected(Guid correlationId)
+ => CorrelationId = correlationId;
- public sealed class ChannelConnected : IEvent
- {
- public ChannelConnected(Guid correlationId)
- => CorrelationId = correlationId;
-
- public Guid CorrelationId { get; }
- }
+ public Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/Events/ChannelDeactivated.cs b/src/DotPulsar/Internal/Events/ChannelDeactivated.cs
index 5b0cf93..204e240 100644
--- a/src/DotPulsar/Internal/Events/ChannelDeactivated.cs
+++ b/src/DotPulsar/Internal/Events/ChannelDeactivated.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Events
+namespace DotPulsar.Internal.Events;
+
+using Abstractions;
+using System;
+
+public sealed class ChannelDeactivated : IEvent
{
- using Abstractions;
- using System;
+ public ChannelDeactivated(Guid correlationId)
+ => CorrelationId = correlationId;
- public sealed class ChannelDeactivated : IEvent
- {
- public ChannelDeactivated(Guid correlationId)
- => CorrelationId = correlationId;
-
- public Guid CorrelationId { get; }
- }
+ public Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/Events/ChannelDisconnected.cs b/src/DotPulsar/Internal/Events/ChannelDisconnected.cs
index 60e98b2..e752f90 100644
--- a/src/DotPulsar/Internal/Events/ChannelDisconnected.cs
+++ b/src/DotPulsar/Internal/Events/ChannelDisconnected.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Events
+namespace DotPulsar.Internal.Events;
+
+using Abstractions;
+using System;
+
+public sealed class ChannelDisconnected : IEvent
{
- using Abstractions;
- using System;
+ public ChannelDisconnected(Guid correlationId)
+ => CorrelationId = correlationId;
- public sealed class ChannelDisconnected : IEvent
- {
- public ChannelDisconnected(Guid correlationId)
- => CorrelationId = correlationId;
-
- public Guid CorrelationId { get; }
- }
+ public Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/Events/ChannelReachedEndOfTopic.cs b/src/DotPulsar/Internal/Events/ChannelReachedEndOfTopic.cs
index 08c1d4e..65d61ca 100644
--- a/src/DotPulsar/Internal/Events/ChannelReachedEndOfTopic.cs
+++ b/src/DotPulsar/Internal/Events/ChannelReachedEndOfTopic.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Events
+namespace DotPulsar.Internal.Events;
+
+using Abstractions;
+using System;
+
+public sealed class ChannelReachedEndOfTopic : IEvent
{
- using Abstractions;
- using System;
+ public ChannelReachedEndOfTopic(Guid correlationId)
+ => CorrelationId = correlationId;
- public sealed class ChannelReachedEndOfTopic : IEvent
- {
- public ChannelReachedEndOfTopic(Guid correlationId)
- => CorrelationId = correlationId;
-
- public Guid CorrelationId { get; }
- }
+ public Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/Events/ChannelUnsubscribed.cs b/src/DotPulsar/Internal/Events/ChannelUnsubscribed.cs
index 000cf7c..71be9b2 100644
--- a/src/DotPulsar/Internal/Events/ChannelUnsubscribed.cs
+++ b/src/DotPulsar/Internal/Events/ChannelUnsubscribed.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Events
+namespace DotPulsar.Internal.Events;
+
+using Abstractions;
+using System;
+
+public sealed class ChannelUnsubscribed : IEvent
{
- using Abstractions;
- using System;
+ public ChannelUnsubscribed(Guid correlationId)
+ => CorrelationId = correlationId;
- public sealed class ChannelUnsubscribed : IEvent
- {
- public ChannelUnsubscribed(Guid correlationId)
- => CorrelationId = correlationId;
-
- public Guid CorrelationId { get; }
- }
+ public Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/Events/ConsumerCreated.cs b/src/DotPulsar/Internal/Events/ConsumerCreated.cs
index 41c5513..87d04ff 100644
--- a/src/DotPulsar/Internal/Events/ConsumerCreated.cs
+++ b/src/DotPulsar/Internal/Events/ConsumerCreated.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Events
+namespace DotPulsar.Internal.Events;
+
+using Abstractions;
+using System;
+
+public sealed class ConsumerCreated : IEvent
{
- using Abstractions;
- using System;
+ public ConsumerCreated(Guid correlationId)
+ => CorrelationId = correlationId;
- public sealed class ConsumerCreated : IEvent
- {
- public ConsumerCreated(Guid correlationId)
- => CorrelationId = correlationId;
-
- public Guid CorrelationId { get; }
- }
+ public Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/Events/ConsumerDisposed.cs b/src/DotPulsar/Internal/Events/ConsumerDisposed.cs
index 130f9c9..a767a66 100644
--- a/src/DotPulsar/Internal/Events/ConsumerDisposed.cs
+++ b/src/DotPulsar/Internal/Events/ConsumerDisposed.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Events
+namespace DotPulsar.Internal.Events;
+
+using Abstractions;
+using System;
+
+public sealed class ConsumerDisposed : IEvent
{
- using Abstractions;
- using System;
+ public ConsumerDisposed(Guid correlationId)
+ => CorrelationId = correlationId;
- public sealed class ConsumerDisposed : IEvent
- {
- public ConsumerDisposed(Guid correlationId)
- => CorrelationId = correlationId;
-
- public Guid CorrelationId { get; }
- }
+ public Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/Events/ExecutorFaulted.cs b/src/DotPulsar/Internal/Events/ExecutorFaulted.cs
index 33661a2..0ba9dad 100644
--- a/src/DotPulsar/Internal/Events/ExecutorFaulted.cs
+++ b/src/DotPulsar/Internal/Events/ExecutorFaulted.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Events
+namespace DotPulsar.Internal.Events;
+
+using Abstractions;
+using System;
+
+public sealed class ExecutorFaulted : IEvent
{
- using Abstractions;
- using System;
+ public ExecutorFaulted(Guid correlationId)
+ => CorrelationId = correlationId;
- public sealed class ExecutorFaulted : IEvent
- {
- public ExecutorFaulted(Guid correlationId)
- => CorrelationId = correlationId;
-
- public Guid CorrelationId { get; }
- }
+ public Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/Events/ProducerCreated.cs b/src/DotPulsar/Internal/Events/ProducerCreated.cs
index 2a89db7..66e110d 100644
--- a/src/DotPulsar/Internal/Events/ProducerCreated.cs
+++ b/src/DotPulsar/Internal/Events/ProducerCreated.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Events
+namespace DotPulsar.Internal.Events;
+
+using Abstractions;
+using System;
+
+public sealed class ProducerCreated : IEvent
{
- using Abstractions;
- using System;
+ public ProducerCreated(Guid correlationId)
+ => CorrelationId = correlationId;
- public sealed class ProducerCreated : IEvent
- {
- public ProducerCreated(Guid correlationId)
- => CorrelationId = correlationId;
-
- public Guid CorrelationId { get; }
- }
+ public Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/Events/ProducerDisposed.cs b/src/DotPulsar/Internal/Events/ProducerDisposed.cs
index 223024f..5bd1e2e 100644
--- a/src/DotPulsar/Internal/Events/ProducerDisposed.cs
+++ b/src/DotPulsar/Internal/Events/ProducerDisposed.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Events
+namespace DotPulsar.Internal.Events;
+
+using Abstractions;
+using System;
+
+public sealed class ProducerDisposed : IEvent
{
- using Abstractions;
- using System;
+ public ProducerDisposed(Guid correlationId)
+ => CorrelationId = correlationId;
- public sealed class ProducerDisposed : IEvent
- {
- public ProducerDisposed(Guid correlationId)
- => CorrelationId = correlationId;
-
- public Guid CorrelationId { get; }
- }
+ public Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/Events/ReaderCreated.cs b/src/DotPulsar/Internal/Events/ReaderCreated.cs
index 1aa55f1..43d29da 100644
--- a/src/DotPulsar/Internal/Events/ReaderCreated.cs
+++ b/src/DotPulsar/Internal/Events/ReaderCreated.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Events
+namespace DotPulsar.Internal.Events;
+
+using Abstractions;
+using System;
+
+public sealed class ReaderCreated : IEvent
{
- using Abstractions;
- using System;
+ public ReaderCreated(Guid correlationId)
+ => CorrelationId = correlationId;
- public sealed class ReaderCreated : IEvent
- {
- public ReaderCreated(Guid correlationId)
- => CorrelationId = correlationId;
-
- public Guid CorrelationId { get; }
- }
+ public Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/Events/ReaderDisposed.cs b/src/DotPulsar/Internal/Events/ReaderDisposed.cs
index 33a9ac6..f852488 100644
--- a/src/DotPulsar/Internal/Events/ReaderDisposed.cs
+++ b/src/DotPulsar/Internal/Events/ReaderDisposed.cs
@@ -12,16 +12,15 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Events
+namespace DotPulsar.Internal.Events;
+
+using Abstractions;
+using System;
+
+public sealed class ReaderDisposed : IEvent
{
- using Abstractions;
- using System;
+ public ReaderDisposed(Guid correlationId)
+ => CorrelationId = correlationId;
- public sealed class ReaderDisposed : IEvent
- {
- public ReaderDisposed(Guid correlationId)
- => CorrelationId = correlationId;
-
- public Guid CorrelationId { get; }
- }
+ public Guid CorrelationId { get; }
}
diff --git a/src/DotPulsar/Internal/ExceptionHandlerPipeline.cs b/src/DotPulsar/Internal/ExceptionHandlerPipeline.cs
index 143555f..00d943e 100644
--- a/src/DotPulsar/Internal/ExceptionHandlerPipeline.cs
+++ b/src/DotPulsar/Internal/ExceptionHandlerPipeline.cs
@@ -12,29 +12,28 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using DotPulsar.Abstractions;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+public sealed class ExceptionHandlerPipeline : IHandleException
{
- using DotPulsar.Abstractions;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
+ private readonly IHandleException[] _handlers;
- public sealed class ExceptionHandlerPipeline : IHandleException
+ public ExceptionHandlerPipeline(IEnumerable<IHandleException> handlers)
+ => _handlers = handlers.ToArray();
+
+ public async ValueTask OnException(ExceptionContext exceptionContext)
{
- private readonly IHandleException[] _handlers;
-
- public ExceptionHandlerPipeline(IEnumerable<IHandleException> handlers)
- => _handlers = handlers.ToArray();
-
- public async ValueTask OnException(ExceptionContext exceptionContext)
+ foreach (var handler in _handlers)
{
- foreach (var handler in _handlers)
- {
- await handler.OnException(exceptionContext).ConfigureAwait(false);
+ await handler.OnException(exceptionContext).ConfigureAwait(false);
- if (exceptionContext.ExceptionHandled)
- break;
- }
+ if (exceptionContext.ExceptionHandled)
+ break;
}
}
}
diff --git a/src/DotPulsar/Internal/Exceptions/AsyncLockDisposedException.cs b/src/DotPulsar/Internal/Exceptions/AsyncLockDisposedException.cs
index 0efb519..457d810 100644
--- a/src/DotPulsar/Internal/Exceptions/AsyncLockDisposedException.cs
+++ b/src/DotPulsar/Internal/Exceptions/AsyncLockDisposedException.cs
@@ -12,12 +12,11 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Exceptions
-{
- using System;
+namespace DotPulsar.Internal.Exceptions;
- public sealed class AsyncLockDisposedException : ObjectDisposedException
- {
- public AsyncLockDisposedException() : base(typeof(AsyncLock).FullName) { }
- }
+using System;
+
+public sealed class AsyncLockDisposedException : ObjectDisposedException
+{
+ public AsyncLockDisposedException() : base(typeof(AsyncLock).FullName) { }
}
diff --git a/src/DotPulsar/Internal/Exceptions/AsyncQueueDisposedException.cs b/src/DotPulsar/Internal/Exceptions/AsyncQueueDisposedException.cs
index ea5f5fd..5248275 100644
--- a/src/DotPulsar/Internal/Exceptions/AsyncQueueDisposedException.cs
+++ b/src/DotPulsar/Internal/Exceptions/AsyncQueueDisposedException.cs
@@ -12,12 +12,11 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Exceptions
-{
- using System;
+namespace DotPulsar.Internal.Exceptions;
- public sealed class AsyncQueueDisposedException : ObjectDisposedException
- {
- public AsyncQueueDisposedException() : base(typeof(AsyncQueue<>).FullName) { }
- }
+using System;
+
+public sealed class AsyncQueueDisposedException : ObjectDisposedException
+{
+ public AsyncQueueDisposedException() : base(typeof(AsyncQueue<>).FullName) { }
}
diff --git a/src/DotPulsar/Internal/Exceptions/ChannelNotReadyException.cs b/src/DotPulsar/Internal/Exceptions/ChannelNotReadyException.cs
index 64178cd..599c0b2 100644
--- a/src/DotPulsar/Internal/Exceptions/ChannelNotReadyException.cs
+++ b/src/DotPulsar/Internal/Exceptions/ChannelNotReadyException.cs
@@ -12,12 +12,11 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Exceptions
-{
- using DotPulsar.Exceptions;
+namespace DotPulsar.Internal.Exceptions;
- public sealed class ChannelNotReadyException : DotPulsarException
- {
- public ChannelNotReadyException() : base("The service is not ready yet") { }
- }
+using DotPulsar.Exceptions;
+
+public sealed class ChannelNotReadyException : DotPulsarException
+{
+ public ChannelNotReadyException() : base("The service is not ready yet") { }
}
diff --git a/src/DotPulsar/Internal/Exceptions/ConnectionDisposedException.cs b/src/DotPulsar/Internal/Exceptions/ConnectionDisposedException.cs
index 7b0b1d4..ce398e7 100644
--- a/src/DotPulsar/Internal/Exceptions/ConnectionDisposedException.cs
+++ b/src/DotPulsar/Internal/Exceptions/ConnectionDisposedException.cs
@@ -12,12 +12,11 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Exceptions
-{
- using System;
+namespace DotPulsar.Internal.Exceptions;
- public sealed class ConnectionDisposedException : ObjectDisposedException
- {
- public ConnectionDisposedException() : base(typeof(Connection).FullName) { }
- }
+using System;
+
+public sealed class ConnectionDisposedException : ObjectDisposedException
+{
+ public ConnectionDisposedException() : base(typeof(Connection).FullName) { }
}
diff --git a/src/DotPulsar/Internal/Exceptions/ConsumerNotFoundException.cs b/src/DotPulsar/Internal/Exceptions/ConsumerNotFoundException.cs
index ade8ecd..be58640 100644
--- a/src/DotPulsar/Internal/Exceptions/ConsumerNotFoundException.cs
+++ b/src/DotPulsar/Internal/Exceptions/ConsumerNotFoundException.cs
@@ -12,12 +12,11 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Exceptions
-{
- using DotPulsar.Exceptions;
+namespace DotPulsar.Internal.Exceptions;
- public sealed class ConsumerNotFoundException : DotPulsarException
- {
- public ConsumerNotFoundException(string message) : base(message) { }
- }
+using DotPulsar.Exceptions;
+
+public sealed class ConsumerNotFoundException : DotPulsarException
+{
+ public ConsumerNotFoundException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Internal/Exceptions/PulsarStreamDisposedException.cs b/src/DotPulsar/Internal/Exceptions/PulsarStreamDisposedException.cs
index b4ec0a0..11b13a3 100644
--- a/src/DotPulsar/Internal/Exceptions/PulsarStreamDisposedException.cs
+++ b/src/DotPulsar/Internal/Exceptions/PulsarStreamDisposedException.cs
@@ -12,12 +12,11 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Exceptions
-{
- using System;
+namespace DotPulsar.Internal.Exceptions;
- public sealed class PulsarStreamDisposedException : ObjectDisposedException
- {
- public PulsarStreamDisposedException() : base(typeof(PulsarStream).FullName) { }
- }
+using System;
+
+public sealed class PulsarStreamDisposedException : ObjectDisposedException
+{
+ public PulsarStreamDisposedException() : base(typeof(PulsarStream).FullName) { }
}
diff --git a/src/DotPulsar/Internal/Exceptions/ServiceNotReadyException.cs b/src/DotPulsar/Internal/Exceptions/ServiceNotReadyException.cs
index d7f2975..35e9a51 100644
--- a/src/DotPulsar/Internal/Exceptions/ServiceNotReadyException.cs
+++ b/src/DotPulsar/Internal/Exceptions/ServiceNotReadyException.cs
@@ -12,12 +12,11 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Exceptions
-{
- using DotPulsar.Exceptions;
+namespace DotPulsar.Internal.Exceptions;
- public sealed class ServiceNotReadyException : DotPulsarException
- {
- public ServiceNotReadyException(string message) : base(message) { }
- }
+using DotPulsar.Exceptions;
+
+public sealed class ServiceNotReadyException : DotPulsarException
+{
+ public ServiceNotReadyException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Internal/Exceptions/TooManyRequestsException.cs b/src/DotPulsar/Internal/Exceptions/TooManyRequestsException.cs
index 80c91c2..22ef3ae 100644
--- a/src/DotPulsar/Internal/Exceptions/TooManyRequestsException.cs
+++ b/src/DotPulsar/Internal/Exceptions/TooManyRequestsException.cs
@@ -12,12 +12,11 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Exceptions
-{
- using DotPulsar.Exceptions;
+namespace DotPulsar.Internal.Exceptions;
- public sealed class TooManyRequestsException : DotPulsarException
- {
- public TooManyRequestsException(string message) : base(message) { }
- }
+using DotPulsar.Exceptions;
+
+public sealed class TooManyRequestsException : DotPulsarException
+{
+ public TooManyRequestsException(string message) : base(message) { }
}
diff --git a/src/DotPulsar/Internal/Exceptions/UnexpectedResponseException.cs b/src/DotPulsar/Internal/Exceptions/UnexpectedResponseException.cs
index 50b814d..5033af4 100644
--- a/src/DotPulsar/Internal/Exceptions/UnexpectedResponseException.cs
+++ b/src/DotPulsar/Internal/Exceptions/UnexpectedResponseException.cs
@@ -12,15 +12,14 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Exceptions
+namespace DotPulsar.Internal.Exceptions;
+
+using DotPulsar.Exceptions;
+using System;
+
+public sealed class UnexpectedResponseException : DotPulsarException
{
- using DotPulsar.Exceptions;
- using System;
+ public UnexpectedResponseException(string message) : base(message) { }
- public sealed class UnexpectedResponseException : DotPulsarException
- {
- public UnexpectedResponseException(string message) : base(message) { }
-
- public UnexpectedResponseException(string message, Exception innerException) : base(message, innerException) { }
- }
+ public UnexpectedResponseException(string message, Exception innerException) : base(message, innerException) { }
}
diff --git a/src/DotPulsar/Internal/Executor.cs b/src/DotPulsar/Internal/Executor.cs
index 540229e..ccabb22 100644
--- a/src/DotPulsar/Internal/Executor.cs
+++ b/src/DotPulsar/Internal/Executor.cs
@@ -12,154 +12,153 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using Abstractions;
+using DotPulsar.Abstractions;
+using Events;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+public sealed class Executor : IExecute
{
- using Abstractions;
- using DotPulsar.Abstractions;
- using Events;
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+ private readonly Guid _correlationId;
+ private readonly IRegisterEvent _eventRegister;
+ private readonly IHandleException _exceptionHandler;
- public sealed class Executor : IExecute
+ public Executor(Guid correlationId, IRegisterEvent eventRegister, IHandleException exceptionHandler)
{
- private readonly Guid _correlationId;
- private readonly IRegisterEvent _eventRegister;
- private readonly IHandleException _exceptionHandler;
+ _correlationId = correlationId;
+ _eventRegister = eventRegister;
+ _exceptionHandler = exceptionHandler;
+ }
- public Executor(Guid correlationId, IRegisterEvent eventRegister, IHandleException exceptionHandler)
+ public async ValueTask Execute(Action action, CancellationToken cancellationToken)
+ {
+ while (true)
{
- _correlationId = correlationId;
- _eventRegister = eventRegister;
- _exceptionHandler = exceptionHandler;
- }
-
- public async ValueTask Execute(Action action, CancellationToken cancellationToken)
- {
- while (true)
+ try
{
- try
- {
- action();
- return;
- }
- catch (Exception ex)
- {
- if (await Handle(ex, cancellationToken).ConfigureAwait(false))
- throw;
- }
-
- cancellationToken.ThrowIfCancellationRequested();
+ action();
+ return;
}
- }
-
- public async ValueTask Execute(Func<Task> func, CancellationToken cancellationToken)
- {
- while (true)
+ catch (Exception ex)
{
- try
- {
- await func().ConfigureAwait(false);
- return;
- }
- catch (Exception ex)
- {
- if (await Handle(ex, cancellationToken).ConfigureAwait(false))
- throw;
- }
-
- cancellationToken.ThrowIfCancellationRequested();
+ if (await Handle(ex, cancellationToken).ConfigureAwait(false))
+ throw;
}
- }
- public async ValueTask Execute(Func<ValueTask> func, CancellationToken cancellationToken)
+ cancellationToken.ThrowIfCancellationRequested();
+ }
+ }
+
+ public async ValueTask Execute(Func<Task> func, CancellationToken cancellationToken)
+ {
+ while (true)
{
- while (true)
+ try
{
- try
- {
- await func().ConfigureAwait(false);
- return;
- }
- catch (Exception ex)
- {
- if (await Handle(ex, cancellationToken).ConfigureAwait(false))
- throw;
- }
-
- cancellationToken.ThrowIfCancellationRequested();
+ await func().ConfigureAwait(false);
+ return;
}
- }
-
- public async ValueTask<TResult> Execute<TResult>(Func<TResult> func, CancellationToken cancellationToken)
- {
- while (true)
+ catch (Exception ex)
{
- try
- {
- return func();
- }
- catch (Exception ex)
- {
- if (await Handle(ex, cancellationToken).ConfigureAwait(false))
- throw;
- }
-
- cancellationToken.ThrowIfCancellationRequested();
+ if (await Handle(ex, cancellationToken).ConfigureAwait(false))
+ throw;
}
- }
- public async ValueTask<TResult> Execute<TResult>(Func<Task<TResult>> func, CancellationToken cancellationToken)
+ cancellationToken.ThrowIfCancellationRequested();
+ }
+ }
+
+ public async ValueTask Execute(Func<ValueTask> func, CancellationToken cancellationToken)
+ {
+ while (true)
{
- while (true)
+ try
{
- try
- {
- return await func().ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- if (await Handle(ex, cancellationToken).ConfigureAwait(false))
- throw;
- }
-
- cancellationToken.ThrowIfCancellationRequested();
+ await func().ConfigureAwait(false);
+ return;
}
- }
-
- public async ValueTask<TResult> Execute<TResult>(Func<ValueTask<TResult>> func, CancellationToken cancellationToken)
- {
- while (true)
+ catch (Exception ex)
{
- try
- {
- return await func().ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- if (await Handle(ex, cancellationToken).ConfigureAwait(false))
- throw;
- }
-
- cancellationToken.ThrowIfCancellationRequested();
+ if (await Handle(ex, cancellationToken).ConfigureAwait(false))
+ throw;
}
- }
- private async ValueTask<bool> Handle(Exception exception, CancellationToken cancellationToken)
+ cancellationToken.ThrowIfCancellationRequested();
+ }
+ }
+
+ public async ValueTask<TResult> Execute<TResult>(Func<TResult> func, CancellationToken cancellationToken)
+ {
+ while (true)
{
- if (cancellationToken.IsCancellationRequested)
- return true;
+ try
+ {
+ return func();
+ }
+ catch (Exception ex)
+ {
+ if (await Handle(ex, cancellationToken).ConfigureAwait(false))
+ throw;
+ }
- var context = new ExceptionContext(exception, cancellationToken);
-
- await _exceptionHandler.OnException(context).ConfigureAwait(false);
-
- if (context.Result != FaultAction.Retry)
- _eventRegister.Register(new ExecutorFaulted(_correlationId));
-
- return context.Result == FaultAction.ThrowException
- ? throw context.Exception
- : context.Result == FaultAction.Rethrow;
+ cancellationToken.ThrowIfCancellationRequested();
}
}
+
+ public async ValueTask<TResult> Execute<TResult>(Func<Task<TResult>> func, CancellationToken cancellationToken)
+ {
+ while (true)
+ {
+ try
+ {
+ return await func().ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ if (await Handle(ex, cancellationToken).ConfigureAwait(false))
+ throw;
+ }
+
+ cancellationToken.ThrowIfCancellationRequested();
+ }
+ }
+
+ public async ValueTask<TResult> Execute<TResult>(Func<ValueTask<TResult>> func, CancellationToken cancellationToken)
+ {
+ while (true)
+ {
+ try
+ {
+ return await func().ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ if (await Handle(ex, cancellationToken).ConfigureAwait(false))
+ throw;
+ }
+
+ cancellationToken.ThrowIfCancellationRequested();
+ }
+ }
+
+ private async ValueTask<bool> Handle(Exception exception, CancellationToken cancellationToken)
+ {
+ if (cancellationToken.IsCancellationRequested)
+ return true;
+
+ var context = new ExceptionContext(exception, cancellationToken);
+
+ await _exceptionHandler.OnException(context).ConfigureAwait(false);
+
+ if (context.Result != FaultAction.Retry)
+ _eventRegister.Register(new ExecutorFaulted(_correlationId));
+
+ return context.Result == FaultAction.ThrowException
+ ? throw context.Exception
+ : context.Result == FaultAction.Rethrow;
+ }
}
diff --git a/src/DotPulsar/Internal/ExecutorState.cs b/src/DotPulsar/Internal/ExecutorState.cs
index c5386ce..bf2c7aa 100644
--- a/src/DotPulsar/Internal/ExecutorState.cs
+++ b/src/DotPulsar/Internal/ExecutorState.cs
@@ -12,11 +12,10 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+public enum ExecutorState : byte
{
- public enum ExecutorState : byte
- {
- Ok,
- Faulted
- }
+ Ok,
+ Faulted
}
diff --git a/src/DotPulsar/Internal/Extensions/ActivityExtensions.cs b/src/DotPulsar/Internal/Extensions/ActivityExtensions.cs
index 850e93e..11c3149 100644
--- a/src/DotPulsar/Internal/Extensions/ActivityExtensions.cs
+++ b/src/DotPulsar/Internal/Extensions/ActivityExtensions.cs
@@ -12,45 +12,44 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Extensions
+namespace DotPulsar.Internal.Extensions;
+
+using System;
+using System.Diagnostics;
+
+public static class ActivityExtensions
{
- using System;
- using System.Diagnostics;
+ private const string _exceptionEventName = "exception";
+ private const string _exceptionStackTrace = "exception.stacktrace";
+ private const string _exceptionType = "exception.type";
+ private const string _exceptionMessage = "exception.message";
+ private const string _messageId = "messaging.message_id";
+ private const string _payloadSize = "messaging.message_payload_size_bytes";
+ private const string _statusCode = "otel.status_code";
- public static class ActivityExtensions
+ public static void AddException(this Activity activity, Exception exception)
{
- private const string _exceptionEventName = "exception";
- private const string _exceptionStackTrace = "exception.stacktrace";
- private const string _exceptionType = "exception.type";
- private const string _exceptionMessage = "exception.message";
- private const string _messageId = "messaging.message_id";
- private const string _payloadSize = "messaging.message_payload_size_bytes";
- private const string _statusCode = "otel.status_code";
+ activity.SetStatusCode("ERROR");
- public static void AddException(this Activity activity, Exception exception)
- {
- activity.SetStatusCode("ERROR");
-
- var exceptionTags = new ActivityTagsCollection
+ var exceptionTags = new ActivityTagsCollection
{
{ _exceptionType, exception.GetType().FullName },
{ _exceptionStackTrace, exception.ToString() }
};
- if (!string.IsNullOrWhiteSpace(exception.Message))
- exceptionTags.Add(_exceptionMessage, exception.Message);
+ if (!string.IsNullOrWhiteSpace(exception.Message))
+ exceptionTags.Add(_exceptionMessage, exception.Message);
- var activityEvent = new ActivityEvent(_exceptionEventName, default, exceptionTags);
- activity.AddEvent(activityEvent);
- }
-
- public static void SetMessageId(this Activity activity, MessageId messageId)
- => activity.SetTag(_messageId, messageId.ToString());
-
- public static void SetStatusCode(this Activity activity, string statusCode)
- => activity.SetTag(_statusCode, statusCode);
-
- public static void SetPayloadSize(this Activity activity, long payloadSize)
- => activity.SetTag(_payloadSize, payloadSize);
+ var activityEvent = new ActivityEvent(_exceptionEventName, default, exceptionTags);
+ activity.AddEvent(activityEvent);
}
+
+ public static void SetMessageId(this Activity activity, MessageId messageId)
+ => activity.SetTag(_messageId, messageId.ToString());
+
+ public static void SetStatusCode(this Activity activity, string statusCode)
+ => activity.SetTag(_statusCode, statusCode);
+
+ public static void SetPayloadSize(this Activity activity, long payloadSize)
+ => activity.SetTag(_payloadSize, payloadSize);
}
diff --git a/src/DotPulsar/Internal/Extensions/CommandExtensions.cs b/src/DotPulsar/Internal/Extensions/CommandExtensions.cs
index 642a103..a17e313 100644
--- a/src/DotPulsar/Internal/Extensions/CommandExtensions.cs
+++ b/src/DotPulsar/Internal/Extensions/CommandExtensions.cs
@@ -12,190 +12,189 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Extensions
+namespace DotPulsar.Internal.Extensions;
+
+using DotPulsar.Exceptions;
+using Exceptions;
+using PulsarApi;
+
+public static class CommandExtensions
{
- using DotPulsar.Exceptions;
- using Exceptions;
- using PulsarApi;
-
- public static class CommandExtensions
+ public static void Expect(this BaseCommand command, BaseCommand.Type type)
{
- public static void Expect(this BaseCommand command, BaseCommand.Type type)
- {
- if (command.CommandType == type)
- return;
+ if (command.CommandType == type)
+ return;
- if (command.CommandType == BaseCommand.Type.Error)
- command.Error.Throw();
+ if (command.CommandType == BaseCommand.Type.Error)
+ command.Error.Throw();
- if (command.CommandType == BaseCommand.Type.SendError)
- command.SendError.Throw();
+ if (command.CommandType == BaseCommand.Type.SendError)
+ command.SendError.Throw();
- throw new UnexpectedResponseException($"Expected '{type}' but got '{command.CommandType}'");
- }
-
- public static void Throw(this CommandSendError command)
- => Throw(command.Error, command.Message);
-
- public static void Throw(this CommandLookupTopicResponse command)
- => Throw(command.Error, command.Message);
-
- public static void Throw(this CommandError command)
- => Throw(command.Error, command.Message);
-
- public static void Throw(this CommandGetOrCreateSchemaResponse command)
- => Throw(command.ErrorCode, command.ErrorMessage);
-
- public static void Throw(this CommandPartitionedTopicMetadataResponse command)
- => Throw(command.Error, command.Message);
-
- private static void Throw(ServerError error, string message)
- => throw (error switch
- {
- ServerError.AuthenticationError => new AuthenticationException(message),
- ServerError.AuthorizationError => new AuthorizationException(message),
- ServerError.ChecksumError => new ChecksumException(message),
- ServerError.ConsumerAssignError => new ConsumerAssignException(message),
- ServerError.ConsumerBusy => new ConsumerBusyException(message),
- ServerError.ConsumerNotFound => new ConsumerNotFoundException(message),
- ServerError.IncompatibleSchema => new IncompatibleSchemaException(message),
- ServerError.InvalidTopicName => new InvalidTopicNameException(message),
- ServerError.InvalidTxnStatus => new InvalidTransactionStatusException(message),
- ServerError.MetadataError => new MetadataException(message),
- ServerError.NotAllowedError => new NotAllowedException(message),
- ServerError.PersistenceError => new PersistenceException(message),
- ServerError.ProducerBlockedQuotaExceededError => new ProducerBlockedQuotaExceededException($"{message}. Error code: {error}"),
- ServerError.ProducerBlockedQuotaExceededException => new ProducerBlockedQuotaExceededException($"{message}. Error code: {error}"),
- ServerError.ProducerBusy => new ProducerBusyException(message),
- ServerError.ServiceNotReady => new ServiceNotReadyException(message),
- ServerError.SubscriptionNotFound => new SubscriptionNotFoundException(message),
- ServerError.TooManyRequests => new TooManyRequestsException(message),
- ServerError.TopicNotFound => new TopicNotFoundException(message),
- ServerError.TopicTerminatedError => new TopicTerminatedException(message),
- ServerError.TransactionConflict => new TransactionConflictException(message),
- ServerError.TransactionCoordinatorNotFound => new TransactionCoordinatorNotFoundException(message),
- ServerError.UnknownError => new UnknownException($"{message}. Error code: {error}"),
- ServerError.UnsupportedVersionError => new UnsupportedVersionException(message),
- _ => new UnknownException($"{message}. Error code: {error}")
- });
-
- public static BaseCommand AsBaseCommand(this CommandAck command)
- => new()
- {
- CommandType = BaseCommand.Type.Ack,
- Ack = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandConnect command)
- => new()
- {
- CommandType = BaseCommand.Type.Connect,
- Connect = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandPing command)
- => new()
- {
- CommandType = BaseCommand.Type.Ping,
- Ping = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandPong command)
- => new()
- {
- CommandType = BaseCommand.Type.Pong,
- Pong = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandProducer command)
- => new()
- {
- CommandType = BaseCommand.Type.Producer,
- Producer = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandGetLastMessageId command)
- => new()
- {
- CommandType = BaseCommand.Type.GetLastMessageId,
- GetLastMessageId = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandUnsubscribe command)
- => new()
- {
- CommandType = BaseCommand.Type.Unsubscribe,
- Unsubscribe = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandSubscribe command)
- => new()
- {
- CommandType = BaseCommand.Type.Subscribe,
- Subscribe = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandLookupTopic command)
- => new()
- {
- CommandType = BaseCommand.Type.Lookup,
- LookupTopic = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandSend command)
- => new()
- {
- CommandType = BaseCommand.Type.Send,
- Send = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandFlow command)
- => new()
- {
- CommandType = BaseCommand.Type.Flow,
- Flow = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandCloseProducer command)
- => new()
- {
- CommandType = BaseCommand.Type.CloseProducer,
- CloseProducer = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandCloseConsumer command)
- => new()
- {
- CommandType = BaseCommand.Type.CloseConsumer,
- CloseConsumer = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandSeek command)
- => new()
- {
- CommandType = BaseCommand.Type.Seek,
- Seek = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandRedeliverUnacknowledgedMessages command)
- => new()
- {
- CommandType = BaseCommand.Type.RedeliverUnacknowledgedMessages,
- RedeliverUnacknowledgedMessages = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandGetOrCreateSchema command)
- => new()
- {
- CommandType = BaseCommand.Type.GetOrCreateSchema,
- GetOrCreateSchema = command
- };
-
- public static BaseCommand AsBaseCommand(this CommandPartitionedTopicMetadata command)
- => new()
- {
- CommandType = BaseCommand.Type.PartitionedMetadata,
- PartitionMetadata = command
- };
+ throw new UnexpectedResponseException($"Expected '{type}' but got '{command.CommandType}'");
}
+
+ public static void Throw(this CommandSendError command)
+ => Throw(command.Error, command.Message);
+
+ public static void Throw(this CommandLookupTopicResponse command)
+ => Throw(command.Error, command.Message);
+
+ public static void Throw(this CommandError command)
+ => Throw(command.Error, command.Message);
+
+ public static void Throw(this CommandGetOrCreateSchemaResponse command)
+ => Throw(command.ErrorCode, command.ErrorMessage);
+
+ public static void Throw(this CommandPartitionedTopicMetadataResponse command)
+ => Throw(command.Error, command.Message);
+
+ private static void Throw(ServerError error, string message)
+ => throw (error switch
+ {
+ ServerError.AuthenticationError => new AuthenticationException(message),
+ ServerError.AuthorizationError => new AuthorizationException(message),
+ ServerError.ChecksumError => new ChecksumException(message),
+ ServerError.ConsumerAssignError => new ConsumerAssignException(message),
+ ServerError.ConsumerBusy => new ConsumerBusyException(message),
+ ServerError.ConsumerNotFound => new ConsumerNotFoundException(message),
+ ServerError.IncompatibleSchema => new IncompatibleSchemaException(message),
+ ServerError.InvalidTopicName => new InvalidTopicNameException(message),
+ ServerError.InvalidTxnStatus => new InvalidTransactionStatusException(message),
+ ServerError.MetadataError => new MetadataException(message),
+ ServerError.NotAllowedError => new NotAllowedException(message),
+ ServerError.PersistenceError => new PersistenceException(message),
+ ServerError.ProducerBlockedQuotaExceededError => new ProducerBlockedQuotaExceededException($"{message}. Error code: {error}"),
+ ServerError.ProducerBlockedQuotaExceededException => new ProducerBlockedQuotaExceededException($"{message}. Error code: {error}"),
+ ServerError.ProducerBusy => new ProducerBusyException(message),
+ ServerError.ServiceNotReady => new ServiceNotReadyException(message),
+ ServerError.SubscriptionNotFound => new SubscriptionNotFoundException(message),
+ ServerError.TooManyRequests => new TooManyRequestsException(message),
+ ServerError.TopicNotFound => new TopicNotFoundException(message),
+ ServerError.TopicTerminatedError => new TopicTerminatedException(message),
+ ServerError.TransactionConflict => new TransactionConflictException(message),
+ ServerError.TransactionCoordinatorNotFound => new TransactionCoordinatorNotFoundException(message),
+ ServerError.UnknownError => new UnknownException($"{message}. Error code: {error}"),
+ ServerError.UnsupportedVersionError => new UnsupportedVersionException(message),
+ _ => new UnknownException($"{message}. Error code: {error}")
+ });
+
+ public static BaseCommand AsBaseCommand(this CommandAck command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.Ack,
+ Ack = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandConnect command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.Connect,
+ Connect = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandPing command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.Ping,
+ Ping = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandPong command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.Pong,
+ Pong = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandProducer command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.Producer,
+ Producer = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandGetLastMessageId command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.GetLastMessageId,
+ GetLastMessageId = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandUnsubscribe command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.Unsubscribe,
+ Unsubscribe = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandSubscribe command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.Subscribe,
+ Subscribe = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandLookupTopic command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.Lookup,
+ LookupTopic = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandSend command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.Send,
+ Send = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandFlow command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.Flow,
+ Flow = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandCloseProducer command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.CloseProducer,
+ CloseProducer = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandCloseConsumer command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.CloseConsumer,
+ CloseConsumer = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandSeek command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.Seek,
+ Seek = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandRedeliverUnacknowledgedMessages command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.RedeliverUnacknowledgedMessages,
+ RedeliverUnacknowledgedMessages = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandGetOrCreateSchema command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.GetOrCreateSchema,
+ GetOrCreateSchema = command
+ };
+
+ public static BaseCommand AsBaseCommand(this CommandPartitionedTopicMetadata command)
+ => new()
+ {
+ CommandType = BaseCommand.Type.PartitionedMetadata,
+ PartitionMetadata = command
+ };
}
diff --git a/src/DotPulsar/Internal/Extensions/MessageIdDataExtensions.cs b/src/DotPulsar/Internal/Extensions/MessageIdDataExtensions.cs
index 8f59a64..f632659 100644
--- a/src/DotPulsar/Internal/Extensions/MessageIdDataExtensions.cs
+++ b/src/DotPulsar/Internal/Extensions/MessageIdDataExtensions.cs
@@ -12,21 +12,20 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Extensions
+namespace DotPulsar.Internal.Extensions;
+
+using DotPulsar.Internal.PulsarApi;
+
+public static class MessageIdDataExtensions
{
- using DotPulsar.Internal.PulsarApi;
+ public static MessageId ToMessageId(this MessageIdData messageIdData)
+ => new(messageIdData.LedgerId, messageIdData.EntryId, messageIdData.Partition, messageIdData.BatchIndex);
- public static class MessageIdDataExtensions
+ public static void MapFrom(this MessageIdData destination, MessageId source)
{
- public static MessageId ToMessageId(this MessageIdData messageIdData)
- => new(messageIdData.LedgerId, messageIdData.EntryId, messageIdData.Partition, messageIdData.BatchIndex);
-
- public static void MapFrom(this MessageIdData destination, MessageId source)
- {
- destination.LedgerId = source.LedgerId;
- destination.EntryId = source.EntryId;
- destination.Partition = source.Partition;
- destination.BatchIndex = source.BatchIndex;
- }
+ destination.LedgerId = source.LedgerId;
+ destination.EntryId = source.EntryId;
+ destination.Partition = source.Partition;
+ destination.BatchIndex = source.BatchIndex;
}
}
diff --git a/src/DotPulsar/Internal/Extensions/MessageMetadataExtensions.cs b/src/DotPulsar/Internal/Extensions/MessageMetadataExtensions.cs
index f2bac5f..734f53d 100644
--- a/src/DotPulsar/Internal/Extensions/MessageMetadataExtensions.cs
+++ b/src/DotPulsar/Internal/Extensions/MessageMetadataExtensions.cs
@@ -12,65 +12,64 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Extensions
+namespace DotPulsar.Internal.Extensions;
+
+using System;
+using System.Text;
+using Metadata = PulsarApi.MessageMetadata;
+
+public static class MessageMetadataExtensions
{
- using System;
- using System.Text;
- using Metadata = PulsarApi.MessageMetadata;
+ // Deliver at
+ public static DateTime GetDeliverAtTimeAsDateTime(this Metadata metadata)
+ => metadata.GetDeliverAtTimeAsDateTimeOffset().UtcDateTime;
- public static class MessageMetadataExtensions
+ public static void SetDeliverAtTime(this Metadata metadata, DateTime timestamp)
+ => metadata.SetDeliverAtTime(new DateTimeOffset(timestamp));
+
+ public static DateTimeOffset GetDeliverAtTimeAsDateTimeOffset(this Metadata metadata)
+ => DateTimeOffset.FromUnixTimeMilliseconds(metadata.DeliverAtTime);
+
+ public static void SetDeliverAtTime(this Metadata metadata, DateTimeOffset timestamp)
+ => metadata.DeliverAtTime = timestamp.ToUnixTimeMilliseconds();
+
+ // Event time
+ public static DateTime GetEventTimeAsDateTime(this Metadata metadata)
+ => metadata.GetEventTimeAsDateTimeOffset().UtcDateTime;
+
+ public static void SetEventTime(this Metadata metadata, DateTime timestamp)
+ => metadata.SetEventTime(new DateTimeOffset(timestamp));
+
+ public static DateTimeOffset GetEventTimeAsDateTimeOffset(this Metadata metadata)
+ => DateTimeOffset.FromUnixTimeMilliseconds((long) metadata.EventTime);
+
+ public static void SetEventTime(this Metadata metadata, DateTimeOffset timestamp)
+ => metadata.EventTime = (ulong) timestamp.ToUnixTimeMilliseconds();
+
+ // Key
+ public static byte[]? GetKeyAsBytes(this Metadata metadata)
{
- // Deliver at
- public static DateTime GetDeliverAtTimeAsDateTime(this Metadata metadata)
- => metadata.GetDeliverAtTimeAsDateTimeOffset().UtcDateTime;
+ if (metadata.PartitionKey is null)
+ return null;
- public static void SetDeliverAtTime(this Metadata metadata, DateTime timestamp)
- => metadata.SetDeliverAtTime(new DateTimeOffset(timestamp));
+ if (metadata.PartitionKeyB64Encoded)
+ return Convert.FromBase64String(metadata.PartitionKey);
- public static DateTimeOffset GetDeliverAtTimeAsDateTimeOffset(this Metadata metadata)
- => DateTimeOffset.FromUnixTimeMilliseconds(metadata.DeliverAtTime);
+ return Encoding.UTF8.GetBytes(metadata.PartitionKey);
+ }
- public static void SetDeliverAtTime(this Metadata metadata, DateTimeOffset timestamp)
- => metadata.DeliverAtTime = timestamp.ToUnixTimeMilliseconds();
+ public static void SetKey(this Metadata metadata, string? key)
+ {
+ metadata.PartitionKey = key;
+ metadata.PartitionKeyB64Encoded = false;
+ }
- // Event time
- public static DateTime GetEventTimeAsDateTime(this Metadata metadata)
- => metadata.GetEventTimeAsDateTimeOffset().UtcDateTime;
+ public static void SetKey(this Metadata metadata, byte[]? key)
+ {
+ if (key is null)
+ return;
- public static void SetEventTime(this Metadata metadata, DateTime timestamp)
- => metadata.SetEventTime(new DateTimeOffset(timestamp));
-
- public static DateTimeOffset GetEventTimeAsDateTimeOffset(this Metadata metadata)
- => DateTimeOffset.FromUnixTimeMilliseconds((long) metadata.EventTime);
-
- public static void SetEventTime(this Metadata metadata, DateTimeOffset timestamp)
- => metadata.EventTime = (ulong) timestamp.ToUnixTimeMilliseconds();
-
- // Key
- public static byte[]? GetKeyAsBytes(this Metadata metadata)
- {
- if (metadata.PartitionKey is null)
- return null;
-
- if (metadata.PartitionKeyB64Encoded)
- return Convert.FromBase64String(metadata.PartitionKey);
-
- return Encoding.UTF8.GetBytes(metadata.PartitionKey);
- }
-
- public static void SetKey(this Metadata metadata, string? key)
- {
- metadata.PartitionKey = key;
- metadata.PartitionKeyB64Encoded = false;
- }
-
- public static void SetKey(this Metadata metadata, byte[]? key)
- {
- if (key is null)
- return;
-
- metadata.PartitionKey = Convert.ToBase64String(key);
- metadata.PartitionKeyB64Encoded = true;
- }
+ metadata.PartitionKey = Convert.ToBase64String(key);
+ metadata.PartitionKeyB64Encoded = true;
}
}
diff --git a/src/DotPulsar/Internal/Extensions/MessagePackageExtensions.cs b/src/DotPulsar/Internal/Extensions/MessagePackageExtensions.cs
index 4e8ead0..1c94e21 100644
--- a/src/DotPulsar/Internal/Extensions/MessagePackageExtensions.cs
+++ b/src/DotPulsar/Internal/Extensions/MessagePackageExtensions.cs
@@ -12,29 +12,28 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Extensions
+namespace DotPulsar.Internal.Extensions;
+
+using PulsarApi;
+using System.Buffers;
+
+public static class MessagePackageExtensions
{
- using PulsarApi;
- using System.Buffers;
+ public static uint GetMetadataSize(this MessagePackage package)
+ => package.Data.ReadUInt32(Constants.MetadataSizeOffset, true);
- public static class MessagePackageExtensions
- {
- public static uint GetMetadataSize(this MessagePackage package)
- => package.Data.ReadUInt32(Constants.MetadataSizeOffset, true);
+ public static MessageMetadata ExtractMetadata(this MessagePackage package, uint metadataSize)
+ => Serializer.Deserialize<MessageMetadata>(package.Data.Slice(Constants.MetadataOffset, metadataSize));
- public static MessageMetadata ExtractMetadata(this MessagePackage package, uint metadataSize)
- => Serializer.Deserialize<MessageMetadata>(package.Data.Slice(Constants.MetadataOffset, metadataSize));
+ public static ReadOnlySequence<byte> ExtractData(this MessagePackage package, uint metadataSize)
+ => package.Data.Slice(Constants.MetadataOffset + metadataSize);
- public static ReadOnlySequence<byte> ExtractData(this MessagePackage package, uint metadataSize)
- => package.Data.Slice(Constants.MetadataOffset + metadataSize);
+ public static bool ValidateMagicNumberAndChecksum(this MessagePackage package)
+ => StartsWithMagicNumber(package.Data) && HasValidChecksum(package.Data);
- public static bool ValidateMagicNumberAndChecksum(this MessagePackage package)
- => StartsWithMagicNumber(package.Data) && HasValidChecksum(package.Data);
+ private static bool StartsWithMagicNumber(ReadOnlySequence<byte> input)
+ => input.StartsWith(Constants.MagicNumber);
- private static bool StartsWithMagicNumber(ReadOnlySequence<byte> input)
- => input.StartsWith(Constants.MagicNumber);
-
- private static bool HasValidChecksum(ReadOnlySequence<byte> input)
- => input.ReadUInt32(Constants.MagicNumber.Length, true) == Crc32C.Calculate(input.Slice(Constants.MetadataSizeOffset));
- }
+ private static bool HasValidChecksum(ReadOnlySequence<byte> input)
+ => input.ReadUInt32(Constants.MagicNumber.Length, true) == Crc32C.Calculate(input.Slice(Constants.MetadataSizeOffset));
}
diff --git a/src/DotPulsar/Internal/Extensions/ReadOnlySequenceExtensions.cs b/src/DotPulsar/Internal/Extensions/ReadOnlySequenceExtensions.cs
index 21994fb..6f66461 100644
--- a/src/DotPulsar/Internal/Extensions/ReadOnlySequenceExtensions.cs
+++ b/src/DotPulsar/Internal/Extensions/ReadOnlySequenceExtensions.cs
@@ -12,89 +12,88 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal.Extensions
+namespace DotPulsar.Internal.Extensions;
+
+using System;
+using System.Buffers;
+
+public static class ReadOnlySequenceExtensions
{
- using System;
- using System.Buffers;
-
- public static class ReadOnlySequenceExtensions
+ public static bool StartsWith<T>(this ReadOnlySequence<T> sequence, ReadOnlyMemory<T> target) where T : IEquatable<T>
{
- public static bool StartsWith<T>(this ReadOnlySequence<T> sequence, ReadOnlyMemory<T> target) where T : IEquatable<T>
- {
- if (target.Length > sequence.Length)
- return false;
-
- var targetIndex = 0;
- var targetSpan = target.Span;
-
- foreach (var memory in sequence)
- {
- var span = memory.Span;
-
- for (var i = 0; i < span.Length; ++i)
- {
- if (!span[i].Equals(targetSpan[targetIndex]))
- return false;
-
- ++targetIndex;
-
- if (targetIndex == targetSpan.Length)
- return true;
- }
- }
-
+ if (target.Length > sequence.Length)
return false;
+
+ var targetIndex = 0;
+ var targetSpan = target.Span;
+
+ foreach (var memory in sequence)
+ {
+ var span = memory.Span;
+
+ for (var i = 0; i < span.Length; ++i)
+ {
+ if (!span[i].Equals(targetSpan[targetIndex]))
+ return false;
+
+ ++targetIndex;
+
+ if (targetIndex == targetSpan.Length)
+ return true;
+ }
}
- public static uint ReadUInt32(this ReadOnlySequence<byte> sequence, long start, bool isBigEndian)
+ return false;
+ }
+
+ public static uint ReadUInt32(this ReadOnlySequence<byte> sequence, long start, bool isBigEndian)
+ {
+ if (sequence.Length < 4 + start)
+ throw new ArgumentOutOfRangeException(nameof(start), start, "Sequence must be at least 4 bytes long from 'start' to end");
+
+ var reverse = isBigEndian != BitConverter.IsLittleEndian;
+ var union = new UIntUnion();
+ var read = 0;
+
+ foreach (var memory in sequence)
{
- if (sequence.Length < 4 + start)
- throw new ArgumentOutOfRangeException(nameof(start), start, "Sequence must be at least 4 bytes long from 'start' to end");
-
- var reverse = isBigEndian != BitConverter.IsLittleEndian;
- var union = new UIntUnion();
- var read = 0;
-
- foreach (var memory in sequence)
+ if (start > memory.Length)
{
- if (start > memory.Length)
- {
- start -= memory.Length;
- continue;
- }
-
- var span = memory.Span;
-
- for (var i = (int) start; i < span.Length; ++i, ++read)
- {
- switch (read)
- {
- case 0:
- if (reverse) union.B0 = span[i];
- else union.B3 = span[i];
- continue;
- case 1:
- if (reverse) union.B1 = span[i];
- else union.B2 = span[i];
- continue;
- case 2:
- if (reverse) union.B2 = span[i];
- else union.B1 = span[i];
- continue;
- case 3:
- if (reverse) union.B3 = span[i];
- else union.B0 = span[i];
- break;
- }
- }
-
- if (read == 4)
- break;
-
- start = 0;
+ start -= memory.Length;
+ continue;
}
- return union.UInt;
+ var span = memory.Span;
+
+ for (var i = (int) start; i < span.Length; ++i, ++read)
+ {
+ switch (read)
+ {
+ case 0:
+ if (reverse) union.B0 = span[i];
+ else union.B3 = span[i];
+ continue;
+ case 1:
+ if (reverse) union.B1 = span[i];
+ else union.B2 = span[i];
+ continue;
+ case 2:
+ if (reverse) union.B2 = span[i];
+ else union.B1 = span[i];
+ continue;
+ case 3:
+ if (reverse) union.B3 = span[i];
+ else union.B0 = span[i];
+ break;
+ }
+ }
+
+ if (read == 4)
+ break;
+
+ start = 0;
}
+
+ return union.UInt;
}
}
diff --git a/src/DotPulsar/Internal/FuncExceptionHandler.cs b/src/DotPulsar/Internal/FuncExceptionHandler.cs
index 8d99a9e..0ea2848 100644
--- a/src/DotPulsar/Internal/FuncExceptionHandler.cs
+++ b/src/DotPulsar/Internal/FuncExceptionHandler.cs
@@ -1,17 +1,30 @@
-namespace DotPulsar.Internal
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace DotPulsar.Internal;
+
+using DotPulsar.Abstractions;
+using System;
+using System.Threading.Tasks;
+
+public sealed class FuncExceptionHandler : IHandleException
{
- using DotPulsar.Abstractions;
- using System;
- using System.Threading.Tasks;
+ private readonly Func<ExceptionContext, ValueTask> _exceptionHandler;
- public sealed class FuncExceptionHandler : IHandleException
- {
- private readonly Func<ExceptionContext, ValueTask> _exceptionHandler;
+ public FuncExceptionHandler(Func<ExceptionContext, ValueTask> exceptionHandler)
+ => _exceptionHandler = exceptionHandler;
- public FuncExceptionHandler(Func<ExceptionContext, ValueTask> exceptionHandler)
- => _exceptionHandler = exceptionHandler;
-
- public ValueTask OnException(ExceptionContext exceptionContext)
- => _exceptionHandler(exceptionContext);
- }
+ public ValueTask OnException(ExceptionContext exceptionContext)
+ => _exceptionHandler(exceptionContext);
}
diff --git a/src/DotPulsar/Internal/FuncStateChangedHandler.cs b/src/DotPulsar/Internal/FuncStateChangedHandler.cs
index ab97199..b881931 100644
--- a/src/DotPulsar/Internal/FuncStateChangedHandler.cs
+++ b/src/DotPulsar/Internal/FuncStateChangedHandler.cs
@@ -12,26 +12,25 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using DotPulsar.Abstractions;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+public sealed class FuncStateChangedHandler<TStateChanged> : IHandleStateChanged<TStateChanged>
{
- using DotPulsar.Abstractions;
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+ private readonly Func<TStateChanged, CancellationToken, ValueTask> _stateChangedHandler;
- public sealed class FuncStateChangedHandler<TStateChanged> : IHandleStateChanged<TStateChanged>
+ public FuncStateChangedHandler(Func<TStateChanged, CancellationToken, ValueTask> stateChangedHandler, CancellationToken cancellationToken)
{
- private readonly Func<TStateChanged, CancellationToken, ValueTask> _stateChangedHandler;
-
- public FuncStateChangedHandler(Func<TStateChanged, CancellationToken, ValueTask> stateChangedHandler, CancellationToken cancellationToken)
- {
- _stateChangedHandler = stateChangedHandler;
- CancellationToken = cancellationToken;
- }
-
- public CancellationToken CancellationToken { get; }
-
- public async ValueTask OnStateChanged(TStateChanged stateChanged, CancellationToken cancellationToken)
- => await _stateChangedHandler(stateChanged, cancellationToken).ConfigureAwait(false);
+ _stateChangedHandler = stateChangedHandler;
+ CancellationToken = cancellationToken;
}
+
+ public CancellationToken CancellationToken { get; }
+
+ public async ValueTask OnStateChanged(TStateChanged stateChanged, CancellationToken cancellationToken)
+ => await _stateChangedHandler(stateChanged, cancellationToken).ConfigureAwait(false);
}
diff --git a/src/DotPulsar/Internal/IdLookup.cs b/src/DotPulsar/Internal/IdLookup.cs
index 8b674e1..d326f7b 100644
--- a/src/DotPulsar/Internal/IdLookup.cs
+++ b/src/DotPulsar/Internal/IdLookup.cs
@@ -12,92 +12,91 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using System.Collections.Generic;
+
+public sealed class IdLookup<T> where T : class
{
- using System.Collections.Generic;
+ private T?[] _items;
- public sealed class IdLookup<T> where T : class
+ public IdLookup()
+ => _items = new T[1];
+
+ public bool IsEmpty()
{
- private T?[] _items;
+ lock (_items)
+ {
+ for (var i = 0; i < _items.Length; ++i)
+ {
+ if (_items[i] is not null)
+ return false;
+ }
- public IdLookup()
- => _items = new T[1];
+ return true;
+ }
+ }
- public bool IsEmpty()
+ public ulong Add(T item)
+ {
+ lock (_items)
+ {
+ for (var i = 0; i < _items.Length; ++i)
+ {
+ if (_items[i] is not null)
+ continue;
+
+ _items[i] = item;
+ return (ulong) i;
+ }
+
+ var newArray = new T[_items.Length + 1];
+ _items.CopyTo(newArray, 0);
+ var id = newArray.Length - 1;
+ newArray[id] = item;
+ _items = newArray;
+ return (ulong) id;
+ }
+ }
+
+ public T? Remove(ulong id)
+ {
+ lock (_items)
+ {
+ var item = _items[(int) id];
+ _items[(int) id] = null;
+ return item;
+ }
+ }
+
+ public T[] RemoveAll()
+ {
+ lock (_items)
+ {
+ var items = new List<T>();
+
+ for (var i = 0; i < _items.Length; ++i)
+ {
+ var item = _items[i];
+
+ if (item is not null)
+ {
+ items.Add(item);
+ _items[i] = null;
+ }
+ }
+
+ return items.ToArray();
+ }
+ }
+
+ public T? this[ulong id]
+ {
+ get
{
lock (_items)
{
- for (var i = 0; i < _items.Length; ++i)
- {
- if (_items[i] is not null)
- return false;
- }
-
- return true;
- }
- }
-
- public ulong Add(T item)
- {
- lock (_items)
- {
- for (var i = 0; i < _items.Length; ++i)
- {
- if (_items[i] is not null)
- continue;
-
- _items[i] = item;
- return (ulong) i;
- }
-
- var newArray = new T[_items.Length + 1];
- _items.CopyTo(newArray, 0);
- var id = newArray.Length - 1;
- newArray[id] = item;
- _items = newArray;
- return (ulong) id;
- }
- }
-
- public T? Remove(ulong id)
- {
- lock (_items)
- {
- var item = _items[(int) id];
- _items[(int) id] = null;
- return item;
- }
- }
-
- public T[] RemoveAll()
- {
- lock (_items)
- {
- var items = new List<T>();
-
- for (var i = 0; i < _items.Length; ++i)
- {
- var item = _items[i];
-
- if (item is not null)
- {
- items.Add(item);
- _items[i] = null;
- }
- }
-
- return items.ToArray();
- }
- }
-
- public T? this[ulong id]
- {
- get
- {
- lock (_items)
- {
- return _items[(int) id];
- }
+ return _items[(int) id];
}
}
}
diff --git a/src/DotPulsar/Internal/Message.cs b/src/DotPulsar/Internal/Message.cs
index 8de1222..dc31286 100644
--- a/src/DotPulsar/Internal/Message.cs
+++ b/src/DotPulsar/Internal/Message.cs
@@ -12,87 +12,86 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using DotPulsar.Abstractions;
+using System;
+using System.Buffers;
+using System.Collections.Generic;
+
+public sealed class Message<TValue> : IMessage<TValue>
{
- using DotPulsar.Abstractions;
- using System;
- using System.Buffers;
- using System.Collections.Generic;
+ private readonly ISchema<TValue> _schema;
- public sealed class Message<TValue> : IMessage<TValue>
+ internal Message(
+ MessageId messageId,
+ ReadOnlySequence<byte> data,
+ string producerName,
+ ulong sequenceId,
+ uint redeliveryCount,
+ ulong eventTime,
+ ulong publishTime,
+ IReadOnlyDictionary<string, string> properties,
+ bool hasBase64EncodedKey,
+ string? key,
+ byte[]? orderingKey,
+ byte[]? schemaVersion,
+ ISchema<TValue> schema)
{
- private readonly ISchema<TValue> _schema;
-
- internal Message(
- MessageId messageId,
- ReadOnlySequence<byte> data,
- string producerName,
- ulong sequenceId,
- uint redeliveryCount,
- ulong eventTime,
- ulong publishTime,
- IReadOnlyDictionary<string, string> properties,
- bool hasBase64EncodedKey,
- string? key,
- byte[]? orderingKey,
- byte[]? schemaVersion,
- ISchema<TValue> schema)
- {
- MessageId = messageId;
- Data = data;
- ProducerName = producerName;
- SequenceId = sequenceId;
- RedeliveryCount = redeliveryCount;
- EventTime = eventTime;
- PublishTime = publishTime;
- Properties = properties;
- HasBase64EncodedKey = hasBase64EncodedKey;
- Key = key;
- OrderingKey = orderingKey;
- SchemaVersion = schemaVersion;
- _schema = schema;
- }
-
- public MessageId MessageId { get; }
-
- public ReadOnlySequence<byte> Data { get; }
-
- public string ProducerName { get; }
-
- public byte[]? SchemaVersion { get; }
-
- public ulong SequenceId { get; }
-
- public uint RedeliveryCount { get; }
-
- public bool HasEventTime => EventTime != 0;
-
- public ulong EventTime { get; }
-
- public DateTime EventTimeAsDateTime => EventTimeAsDateTimeOffset.UtcDateTime;
-
- public DateTimeOffset EventTimeAsDateTimeOffset => DateTimeOffset.FromUnixTimeMilliseconds((long) EventTime);
-
- public bool HasBase64EncodedKey { get; }
-
- public bool HasKey => Key is not null;
-
- public string? Key { get; }
-
- public byte[]? KeyBytes => Key is not null ? Convert.FromBase64String(Key) : null;
-
- public bool HasOrderingKey => OrderingKey is not null;
-
- public byte[]? OrderingKey { get; }
-
- public ulong PublishTime { get; }
-
- public DateTime PublishTimeAsDateTime => PublishTimeAsDateTimeOffset.UtcDateTime;
-
- public DateTimeOffset PublishTimeAsDateTimeOffset => DateTimeOffset.FromUnixTimeMilliseconds((long) PublishTime);
-
- public IReadOnlyDictionary<string, string> Properties { get; }
-
- public TValue Value() => _schema.Decode(Data);
+ MessageId = messageId;
+ Data = data;
+ ProducerName = producerName;
+ SequenceId = sequenceId;
+ RedeliveryCount = redeliveryCount;
+ EventTime = eventTime;
+ PublishTime = publishTime;
+ Properties = properties;
+ HasBase64EncodedKey = hasBase64EncodedKey;
+ Key = key;
+ OrderingKey = orderingKey;
+ SchemaVersion = schemaVersion;
+ _schema = schema;
}
+
+ public MessageId MessageId { get; }
+
+ public ReadOnlySequence<byte> Data { get; }
+
+ public string ProducerName { get; }
+
+ public byte[]? SchemaVersion { get; }
+
+ public ulong SequenceId { get; }
+
+ public uint RedeliveryCount { get; }
+
+ public bool HasEventTime => EventTime != 0;
+
+ public ulong EventTime { get; }
+
+ public DateTime EventTimeAsDateTime => EventTimeAsDateTimeOffset.UtcDateTime;
+
+ public DateTimeOffset EventTimeAsDateTimeOffset => DateTimeOffset.FromUnixTimeMilliseconds((long) EventTime);
+
+ public bool HasBase64EncodedKey { get; }
+
+ public bool HasKey => Key is not null;
+
+ public string? Key { get; }
+
+ public byte[]? KeyBytes => Key is not null ? Convert.FromBase64String(Key) : null;
+
+ public bool HasOrderingKey => OrderingKey is not null;
+
+ public byte[]? OrderingKey { get; }
+
+ public ulong PublishTime { get; }
+
+ public DateTime PublishTimeAsDateTime => PublishTimeAsDateTimeOffset.UtcDateTime;
+
+ public DateTimeOffset PublishTimeAsDateTimeOffset => DateTimeOffset.FromUnixTimeMilliseconds((long) PublishTime);
+
+ public IReadOnlyDictionary<string, string> Properties { get; }
+
+ public TValue Value() => _schema.Decode(Data);
}
diff --git a/src/DotPulsar/Internal/MessageBuilder.cs b/src/DotPulsar/Internal/MessageBuilder.cs
index 44b3812..5013596 100644
--- a/src/DotPulsar/Internal/MessageBuilder.cs
+++ b/src/DotPulsar/Internal/MessageBuilder.cs
@@ -12,98 +12,97 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using DotPulsar.Abstractions;
+using Extensions;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+public sealed class MessageBuilder<TMessage> : IMessageBuilder<TMessage>
{
- using DotPulsar.Abstractions;
- using Extensions;
- using System;
- using System.Threading;
- using System.Threading.Tasks;
+ private readonly IProducer<TMessage> _producer;
+ private readonly MessageMetadata _metadata;
- public sealed class MessageBuilder<TMessage> : IMessageBuilder<TMessage>
+ public MessageBuilder(IProducer<TMessage> producer)
{
- private readonly IProducer<TMessage> _producer;
- private readonly MessageMetadata _metadata;
-
- public MessageBuilder(IProducer<TMessage> producer)
- {
- _producer = producer;
- _metadata = new MessageMetadata();
- }
-
- public IMessageBuilder<TMessage> DeliverAt(long timestamp)
- {
- _metadata.Metadata.DeliverAtTime = timestamp;
- return this;
- }
-
- public IMessageBuilder<TMessage> DeliverAt(DateTime timestamp)
- {
- _metadata.Metadata.SetDeliverAtTime(timestamp);
- return this;
- }
-
- public IMessageBuilder<TMessage> DeliverAt(DateTimeOffset timestamp)
- {
- _metadata.Metadata.SetDeliverAtTime(timestamp);
- return this;
- }
-
- public IMessageBuilder<TMessage> EventTime(ulong eventTime)
- {
- _metadata.Metadata.EventTime = eventTime;
- return this;
- }
-
- public IMessageBuilder<TMessage> EventTime(DateTime eventTime)
- {
- _metadata.Metadata.SetEventTime(eventTime);
- return this;
- }
-
- public IMessageBuilder<TMessage> EventTime(DateTimeOffset eventTime)
- {
- _metadata.Metadata.SetEventTime(eventTime);
- return this;
- }
-
- public IMessageBuilder<TMessage> Key(string key)
- {
- _metadata.Metadata.SetKey(key);
- return this;
- }
-
- public IMessageBuilder<TMessage> KeyBytes(byte[] key)
- {
- _metadata.Metadata.SetKey(key);
- return this;
- }
-
- public IMessageBuilder<TMessage> OrderingKey(byte[] key)
- {
- _metadata.Metadata.OrderingKey = key;
- return this;
- }
-
- public IMessageBuilder<TMessage> Property(string key, string value)
- {
- _metadata[key] = value;
- return this;
- }
-
- public IMessageBuilder<TMessage> SchemaVersion(byte[] schemaVersion)
- {
- _metadata.Metadata.SchemaVersion = schemaVersion;
- return this;
- }
-
- public IMessageBuilder<TMessage> SequenceId(ulong sequenceId)
- {
- _metadata.Metadata.SequenceId = sequenceId;
- return this;
- }
-
- public async ValueTask<MessageId> Send(TMessage message, CancellationToken cancellationToken)
- => await _producer.Send(_metadata, message, cancellationToken).ConfigureAwait(false);
+ _producer = producer;
+ _metadata = new MessageMetadata();
}
+
+ public IMessageBuilder<TMessage> DeliverAt(long timestamp)
+ {
+ _metadata.Metadata.DeliverAtTime = timestamp;
+ return this;
+ }
+
+ public IMessageBuilder<TMessage> DeliverAt(DateTime timestamp)
+ {
+ _metadata.Metadata.SetDeliverAtTime(timestamp);
+ return this;
+ }
+
+ public IMessageBuilder<TMessage> DeliverAt(DateTimeOffset timestamp)
+ {
+ _metadata.Metadata.SetDeliverAtTime(timestamp);
+ return this;
+ }
+
+ public IMessageBuilder<TMessage> EventTime(ulong eventTime)
+ {
+ _metadata.Metadata.EventTime = eventTime;
+ return this;
+ }
+
+ public IMessageBuilder<TMessage> EventTime(DateTime eventTime)
+ {
+ _metadata.Metadata.SetEventTime(eventTime);
+ return this;
+ }
+
+ public IMessageBuilder<TMessage> EventTime(DateTimeOffset eventTime)
+ {
+ _metadata.Metadata.SetEventTime(eventTime);
+ return this;
+ }
+
+ public IMessageBuilder<TMessage> Key(string key)
+ {
+ _metadata.Metadata.SetKey(key);
+ return this;
+ }
+
+ public IMessageBuilder<TMessage> KeyBytes(byte[] key)
+ {
+ _metadata.Metadata.SetKey(key);
+ return this;
+ }
+
+ public IMessageBuilder<TMessage> OrderingKey(byte[] key)
+ {
+ _metadata.Metadata.OrderingKey = key;
+ return this;
+ }
+
+ public IMessageBuilder<TMessage> Property(string key, string value)
+ {
+ _metadata[key] = value;
+ return this;
+ }
+
+ public IMessageBuilder<TMessage> SchemaVersion(byte[] schemaVersion)
+ {
+ _metadata.Metadata.SchemaVersion = schemaVersion;
+ return this;
+ }
+
+ public IMessageBuilder<TMessage> SequenceId(ulong sequenceId)
+ {
+ _metadata.Metadata.SequenceId = sequenceId;
+ return this;
+ }
+
+ public async ValueTask<MessageId> Send(TMessage message, CancellationToken cancellationToken)
+ => await _producer.Send(_metadata, message, cancellationToken).ConfigureAwait(false);
}
diff --git a/src/DotPulsar/Internal/MessageFactory.cs b/src/DotPulsar/Internal/MessageFactory.cs
index 1f68425..4ecb94d 100644
--- a/src/DotPulsar/Internal/MessageFactory.cs
+++ b/src/DotPulsar/Internal/MessageFactory.cs
@@ -12,92 +12,91 @@
* limitations under the License.
*/
-namespace DotPulsar.Internal
+namespace DotPulsar.Internal;
+
+using DotPulsar.Abstractions;
+using DotPulsar.Internal.Abstractions;
+using DotPulsar.Internal.PulsarApi;
+using System.Buffers;
+using System.Collections.Generic;
+
+public sealed class MessageFactory<TValue> : IMessageFactory<TValue>
{
- using DotPulsar.Abstractions;
- using DotPulsar.Internal.Abstractions;
- using DotPulsar.Internal.PulsarApi;
- using System.Buffers;
- using System.Collections.Generic;
+ private static readonly Dictionary<string, string> _empty;
- public sealed class MessageFactory<TValue> : IMessageFactory<TValue>
+ static MessageFactory() => _empty = new Dictionary<string, string>();
+
+ private static IReadOnlyDictionary<string, string> FromKeyValueList(List<KeyValue> keyValues)
{
- private static readonly Dictionary<string, string> _empty;
+ if (keyValues.Count == 0)
+ return _empty;
- static MessageFactory() => _empty = new Dictionary<string, string>();
+ var dictionary = new Dictionary<string, string>(keyValues.Count);
- private static IReadOnlyDictionary<string, string> FromKeyValueList(List<KeyValue> keyValues)
+ for (var i = 0; i < keyValues.Count; ++i)
{
- if (keyValues.Count == 0)
- return _empty;
-
- var dictionary = new Dictionary<string, string>(keyValues.Count);
-
- for (var i = 0; i < keyValues.Count; ++i)
- {
- var keyValue = keyValues[i];
- dictionary.Add(keyValue.Key, keyValue.Value);
- }
-
- return dictionary;
+ var keyValue = keyValues[i];
+ dictionary.Add(keyValue.Key, keyValue.Value);
}
- private readonly ISchema<TValue> _schema;
+ return dictionar