Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased]

Added

  • A number of resilience, correctness, and performance improvements
  • Experimental: Added an extension method for IConsumer that will ‘Process’ and auto-acknowledge messages while creating an Activity (useful for doing tracing)
  • Schemas with support for the following types
    • Boolean
    • Bytes (using byte[] and ReadOnlySequence<byte>)
    • String (UTF-8, UTF-16, and US-ASCII)
    • INT8, INT16, INT32, and INT64
    • Float and Double
    • Time (using TimeSpan)
    • Timestamp and Date (using DateTime)

Changed

  • Breaking: Building a producer will now create an IProducer<T> The non-generic IProducer interface is still there, but messages can only be sent (ISend) with IProducer<T>
  • Breaking: Building a reader or consumer will now create an IConsumer<T> or IReader<T> The non-genric IReader and IConsumer are still there, but messages can only be consumed/read (IReceive) with IConsumer<T> and IReader<T>
  • Breaking: Receiving a message with now return an IMessage<T> instead of the Message class (which is now internal) The non-generic IMessage can be used if ‘Value()’ (decoding the ‘Data’ bytes) is not used (when just handling raw messages)
  • Breaking: The message builder is now generic
  • Setting an Action and Func StateChangedHandler on the ConsumerBuilder, ReaderBuilder, and ProducerBuilder are now extension methods
  • Setting an Action and Func ExceptionHandler on the PulsarClientBuilder are now extension methods

Fixed

  • When the broker sends a CommandClose[Producer/Consumer] all in-flight (and following) requests to the broker are ignored. Even though we reconnect the consumer, reader, or producer the tasks for the in-flight requests will hang as long as the connection is kept alive by other producers/consumers/readers. This situation is now handled and the requests will be sent again on the new connection. As a client library, we can only handle this (unexpected) behavior for requests that get a response. For “fire and forget” requests, like “Flow”, this remains a problem and should be solved broker/server-side by sending a response for all requests in all situations.

[0.11.0] - 2021-02-21

Added

  • The Consumer and Reader now share the IReceive interface for receiving a single message: ValueTask<Message> Receive(CancellationToken cancellationToken)
  • The Consumer and Reader now share the ISeek interface for seeking on message-id and publish time
  • The Consumer and Reader now share the IGetLastMessageId interface for getting the last message-id on a topic
  • The Consumer, Reader, and Producer now share the IState interface adding ‘OnStateChangeFrom’ and ‘OnStateChangeTo’
  • The PulsarClient, Consumer, Reader, and Producer now have the read-only property ‘ServiceUrl’
  • The Consumer now have the read-only property ‘SubscriptionName’
  • All message compression types are now supported (listed below). Please read this compression how-to
    • LZ4
    • SNAPPY
    • ZLIB
    • ZSTD

Changed

  • MessageId.ToString() now returns a string matching that of other clients: “{LedgerId}:{EntryId}:{Partition}:{BatchIndex}”
  • A lot of methods were made into extension methods and now require a using statement for ‘DotPulsar.Extensions’
    • Producer.StateChangedTo(ProducerState state, CancellationToken cancellationToken)
    • Producer.StateChangedFrom(ProducerState state, CancellationToken cancellationToken)
    • Producer.Send(byte[] data, CancellationToken cancellationToken)
    • Producer.Send(ReadOnlyMemory<byte> data, CancellationToken cancellationToken)
    • Producer.Send(MessageMetadata metadata, byte[] data, CancellationToken cancellationToken)
    • Producer.Send(MessageMetadata metadata, ReadOnlyMemory<byte> data, CancellationToken cancellationToken)
    • Consumer.Acknowledge(Message message, CancellationToken cancellationToken)
    • Consumer.AcknowledgeCumulative(Message message, CancellationToken cancellationToken)
    • Consumer.StateChangedTo(ConsumerState state, CancellationToken cancellationToken)
    • Consumer.StateChangedFrom(ConsumerState state, CancellationToken cancellationToken)
    • Consumer.Messages(CancellationToken cancellationToken)
    • Consumer.Seek(DateTime publishTime, CancellationToken cancellationToken)
    • Consumer.Seek(DateTimeOffset publishTime, CancellationToken cancellationToken)
    • Reader.StateChangedTo(ReaderState state, CancellationToken cancellationToken)
    • Reader.StateChangedFrom(ReaderState state, CancellationToken cancellationToken)
    • Reader.Messages(CancellationToken cancellationToken)
    • Reader.Seek(DateTime publishTime, CancellationToken cancellationToken)
    • Reader.Seek(DateTimeOffset publishTime, CancellationToken cancellationToken)

Fixed

  • Before the Consumer and Reader would throw an ArgumentOutOfRangeException if they encountered a compressed message. Now they will throw a CompressionException if the compression type is not supported
  • DotPulsarEventSource (performance counters) was only enabled for .NET Standard 2.1. Now it's enabled for all target frameworks except .NET Standard 2.0

[0.10.1] - 2020-12-23

Added

  • MessageId implements IComparable<MessageId>

Fixed

  • Do not throw exceptions when disposing consumers, readers, or producers

[0.10.0] - 2020-12-16

Added

  • Added performance improvements when receiving data
  • Added the IHandleStateChanged<TStateChanged> interface for easier state monitoring
  • Added StateChangedHandler methods on ConsumerBuilder, ReaderBuilder, and ProducerBuilder for easier state monitoring
  • Added StateChangedHandler property on ConsumerOptions, ReaderOptions, and ProducerOptions for easier state monitoring
  • Added four new DotPulsarExceptions: InvalidTransactionStatusException, NotAllowedException, TransactionConflictException and TransactionCoordinatorNotFoundException
  • Added properties on Message to read EventTime and PublishTime as DateTime
  • Added methods on the IMessageBuilder to set EventTime and DeliverAt using DateTime
  • Added properties on MessageMetadata to set EventTime and DeliverAtTime using DateTime
  • Added seeking by MessageId on the Reader
  • Added seeking by message publish time on the Consumer and Reader
  • Added GetLastMessageId on the Reader

Changed

  • The protobuf-net dependency is upgraded from 2.4.6 to 3.0.73 to get support for ReadOnlySequence<byte>

Fixed

  • Reconnection issues when seeking

[0.9.7] - 2020-12-04

Added

  • Added an ExceptionHandler method on the IPulsarClientBuilder taking an Action<ExceptionContext> for easy sync exception handling
  • Added .NET 5 as a target framework and started using C# 9.0
  • Added performance improvements when sending and receiving data
  • The default values for ConsumerOptions, ReaderOptions, and ProducerOptions are now public

[0.9.6] - 2020-10-15

Fixed

  • Fixed missing metadata properties in batched messages containing only one message
  • Fixed potential torn reads in EventCounters