77[ ![ codecov] ( https://codecov.io/gh/rabbitmq/rabbitmq-stream-dotnet-client/branch/main/graph/badge.svg?token=OIA04ZQD79 )] ( https://codecov.io/gh/rabbitmq/rabbitmq-stream-dotnet-client )
88</div >
99
10- #@ Table of Contents
11-
10+ # Table of Contents
1211
1312---
1413
@@ -116,7 +115,7 @@ await system.DeleteStream(stream);
116115await system .Close ();
117116```
118117
119- ### Usage
118+ ## Usage
120119
121120---
122121
@@ -238,7 +237,7 @@ Consider a Producer instance like a long-lived object, do not create one to send
238237
239238Producer with a reference name stores the sequence id on the server .
240239It is possible to retrieve the id using `producer .GetLastPublishingId ()`
241- or more generic `system .QuerySequence (" reference" , " my_stream" )`
240+ or more generic `system .QuerySequence (" reference" , " my_stream" )`.
242241
243242### Publish Messages
244243
@@ -294,15 +293,19 @@ var producer = await system.CreateProducer(
294293 Stream = " my_stream" ,
295294 });
296295```
296+
297297then :
298+
298299```csharp
299300var publishingId = 0 ;
300301var message = new Message (Encoding .UTF8 .GetBytes ($" my deduplicate message {i }" ));
301302await producer .Send (publishingId , message );
302303```
303304
304305### Consume Messages
306+
305307Define a consumer :
308+
306309```csharp
307310var consumer = await system .CreateConsumer (
308311 new ConsumerConfig
@@ -317,8 +320,11 @@ var consumer = await system.CreateConsumer(
317320 }
318321});
319322```
323+
320324### Offset Types
325+
321326There are five types of Offset and they can be set by the `ConsumerConfig .OffsetSpec ` property that must be passed to the Consumer constructor , in the example we use `OffsetTypeFirst `:
327+
322328```csharp
323329var consumerOffsetTypeFirst = await system .CreateConsumer (
324330 new ConsumerConfig
@@ -333,29 +339,40 @@ var consumerOffsetTypeFirst = await system.CreateConsumer(
333339 }
334340 });
335341```
342+
336343The five types are :
337- - First : it takes messages from the first message of the stream .
344+ - First : it takes messages from the first message of the stream .
345+
338346```csharp
339347var offsetTypeFirst = new OffsetTypeFirst ();
340348```
349+
341350- Last : it takes messages from the last chunk of the stream , i .e . it doesn ’t start from the last message , but the last “group ” of messages .
351+
342352```csharp
343353var offsetTypeLast = new OffsetTypeLast ();
344354```
355+
345356- Next : it takes messages published after the consumer connection .
357+
346358```csharp
347359var offsetTypeNext = new OffsetTypeNext ()
348360```
361+
349362- Offset : it takes messages starting from the message with id equal to the passed value . If the value is less than the first message of the stream , it starts from the first (i .e . if you pass 0 , but the stream starts from 10 , it starts from 10 ). If the message with the id hasn ’t yet been published it waits until this publishingId is reached .
363+
350364```csharp
351365ulong iWantToStartFromPubId = 10 ;
352366var offsetTypeOffset = new OffsetTypeOffset (iWantToStartFromPubId );
353367```
368+
354369- Timestamp : it takes messages starting from the first message with timestamp bigger than the one passed
370+
355371```csharp
356372var anHourAgo = (long )DateTime .UtcNow .AddHours (- 1 ).Subtract (new DateTime (1970 , 1 , 1 )).TotalSeconds ;
357373var offsetTypeTimestamp = new OffsetTypeTimestamp (anHourAgo );
358374```
375+
359376### Track Offset
360377
361378The server can store the current delivered offset given a consumer with `StoreOffset ` in this way :
@@ -374,8 +391,7 @@ var consumer = await system.CreateConsumer(
374391 }
375392```
376393
377- Note : < / b >
378- ** Avoid ** to store the offset for each single message, it can reduce the performances.
394+ Note : ** Avoid ** storing the offset for every single message, it can reduce performance.
379395
380396It is possible to retrieve the offset with `QueryOffset`:
381397
@@ -389,9 +405,10 @@ var consumer = await system.CreateConsumer(
389405 OffsetSpec = new OffsetTypeOffset (trackedOffset ),
390406```
391407
392- OBS . if don 't have stored an offset for the consumer's reference on the stream you get an OffsetNotFoundException exception .
408+ Note : if you try to store an offset that doesn 't exist yet for the consumer's reference on the stream you get will get an ` OffsetNotFoundException ` exception .
393409
394410### Handle Close
411+
395412Producers / Consumers raise and event when the client is disconnected :
396413
397414```csharp
@@ -405,8 +422,10 @@ Producers/Consumers raise and event when the client is disconnected:
405422```
406423
407424### Handle Metadata Update
425+
408426Stream metadata update is raised when the stream topology changes or the stream is deleted.
409427You can use `MetadataHandler ` to handle it :
428+
410429```csharp
411430 new ProducerConfig / ConsumerConfig
412431 {
@@ -420,49 +439,60 @@ You can use `MetadataHandler` to handle it:
420439### Heartbeat
421440
422441It is possible to configure the heartbeat using :
442+
423443```csharp
424444 var config = new StreamSystemConfig ()
425445{
426446 Heartbeat = TimeSpan .FromSeconds (30 ),
427447}
428448```
449+
429450- `60 ` (`TimeSpan .FromSeconds (60 )`) seconds is the default value
430451- `0` (`TimeSpan .FromSeconds (0 )`) will advise server to disable heartbeat
431452
432453Heartbeat value shouldn 't be too low .
433454
434455### Reliable
435456 - Reliable Producer
436- - Reliable Consumer </p >
437- See the directory [Examples /Reliable ](./ Examples / Reliable )
457+ - Reliable Consumer
458+
459+ See the directory [Examples /Reliable ](./ Examples / Reliable ) for code examples .
438460
439461
440462### Reliable Producer
441- Reliable Producer is a smart layer built up of the standard `Producer `. </b >
442- The idea is to leave the user decides what to use , the standard or reliable producer . < / b >
463+
464+ Reliable Producer is a smart layer built up of the standard `Producer `.
465+
466+ The idea is to give the user ability to choose between the standard or reliable producer .
443467
444468The main features are :
469+
445470- Provide publishingID automatically
446471- Auto - Reconnect in case of disconnection
447472- Trace sent and received messages
448473- Invalidate messages
449474- [Handle the metadata Update ](#reliable - handle - metadata - update )
450475
451476#### Provide publishingID automatically
452- Reliable Producer retrieves the last publishingID given the producer name . < / b >
453- Zero (0 ) is the default value in case there is no a publishingID .
477+
478+ Reliable Producer retrieves the last publishingID given the producer name .
479+
480+ Zero (0 ) is the default value in case there is no publishingID for given producer reference .
454481
455482#### Auto-Reconnect
483+
456484Reliable Producer restores the TCP connection in case the Producer is disconnected for some reason .
457485During the reconnection it continues to store the messages in a local -list .
458486The user will receive back the confirmed or un -confirmed messages .
459487See [Reconnection Strategy ](#reconnection - strategy )
460488
461489#### Trace sent and received messages
462- Reliable Producer keeps in memory each sent message and remove from the memory when the message is confirmed or goes in timout .
490+
491+ Reliable Producer keeps in memory each sent message and removes it from the memory when the message is confirmed or times out .
463492`ConfirmationHandler ` receives the messages back with the status .
464493`confirmation .Status ` can have different values , but in general `ConfirmationStatus .Confirmed ` means the messages
465- is stored on the server other status means that there was a problem with the message /messages .
494+ is stored on the server . Other statuses mean that there was a problem with the message /messages under given publishing id .
495+
466496```csharp
467497ConfirmationHandler = confirmation =>
468498{
@@ -477,17 +507,34 @@ ConfirmationHandler = confirmation =>
477507 }
478508}
479509```
510+
511+ #### Currently defined confirmation statuses
512+
513+ | Status | Description | Source |
514+ |-----------------------|--------------------------------------------------------------------------------------------------------------|--------|
515+ | Confirmed | Message has been confirmed by the server and written to disk. | Server |
516+ | ClientTimeoutError | Client gave up waiting for the message (read more [here](#invalidate-messages)). | Client |
517+ | StreamNotAvailable | Stream was deleted or otherwise become unavailable . | Server |
518+ | InternalError | | Server |
519+ | AccessRefused | Provided credentials are invalid or you lack permissions for specific vhost / etc . | Server |
520+ | PreconditionFailed | Catch - all for validation on server (eg . requested to create stream with different parameters but same name ). | Server |
521+ | PublisherDoesNotExist | | Server |
522+ | UndefinedError | Catch - all for any new status that is not yet handled in the library . | Server |
523+
480524#### Invalidate messages
481- If the client doesn't receive a confirmation within 2 seconds Reliable Producer removes the message from the internal messages cache.
482- The user will receive `ConfirmationStatus.TimeoutError` in the `ConfirmationHandler`.
525+
526+ If the client doesn 't receive a confirmation within configured timeout (3 seconds by default), Reliable Producer removes the message from the internal messages cache.
527+ The user will receive `ConfirmationStatus .ClientTimeoutError ` in the `ConfirmationHandler `.
483528
484529#### Send API
485530Reliable Producer implements two `send (.. )`
531+
486532- `Send (Message message )` // standard
487533- `Send (List < Message > messages , CompressionType compressionType )` // sub-batching with compression
488534
489535
490536### Reliable Consumer
537+
491538Reliable Consumer is a smart layer built up of the standard `Consumer `. </b >
492539The idea is to leave the user decides what to use , the standard or reliable Consumer . < / b >
493540
@@ -497,17 +544,21 @@ The main features are:
497544- [Handle the metadata Update ](#reliable - handle - metadata - update )
498545
499546#### Auto-Reconnect
547+
500548Reliable Consumer restores the TCP connection in case the Producer is disconnected for some reason .
501549Reliable Consumer will restart consuming from the last offset stored .
502550See [Reconnection Strategy ](#reconnection - strategy )
503551
504552### Reconnection Strategy
553+
505554By default Reliable Producer / Consumer uses an `BackOffReconnectStrategy ` to reconnect the client .
506555You can customize the behaviour implementing the `IReconnectStrategy ` interface :
556+
507557```csharp
508558bool WhenDisconnected (string connectionInfo );
509559void WhenConnected (string connectionInfo );
510560```
561+
511562If `WhenDisconnected ` return is `true ` Producer /Consumer will be reconnected else closed .
512563`connectionInfo ` add information about the connection .
513564
@@ -519,8 +570,8 @@ var p = await ReliableProducer.CreateReliableProducer(new ReliableProducerConfig
519570ReconnectStrategy = MyReconnectStrategy
520571```
521572
522-
523573### Reliable handle metadata update
574+
524575If the streams changes the topology (ex :Stream deleted or add / remove follower ), the client receives an `MetadataUpdate ` event .
525576Reliable Producer detects the event and tries to reconnect the producer if the stream still exist else closes the producer / consumer .
526577
0 commit comments