booblik
Wiki

clients/dotnet/Booblik

Generated page

Model gemma-mtp, commit ef58254ca7be, 2026-08-16, sources: 6. Edit the code or the hand-written documentation instead.

Diagram

Connection

The core transport layer for communicating with the booblik broker via TCP. The Connection class manages a TcpClient and NetworkStream to send framed requests and receive responses Connection.cs:40. It uses a correlation ID to match responses to requests, ensuring that even if multiple requests were sent, the caller receives the correct answer Connection.cs:54.

More: Connection

Metadata and Topic Discovery

Retrieving partition information and topic existence from the broker. The MetadataAsync method sends a request containing a list of topic names and decodes the response into a dictionary of partition information Connection.cs:145. Users can also use TopicAsync to get a Topic object which encapsulates the partitions available for a specific name Connection.cs:292.

ProduceAsync and AckPolicy

Appending records to a partition and managing durability guarantees via AckPolicy. The ProduceAsync method allows sending a list of records to a specific partition Connection.cs:183. The durability of the write is determined by the following table:

AckPolicyValueDescription
None0Answers nothing; the broker may lose the record without the client knowing Connection.cs:15
Written1Answers once the record is in the log, before any durability barrier Connection.cs:18
Forced2Answers after the broker's force() operation Connection.cs:21

More: ProduceAsync and AckPolicy

FetchAsync and Consumer

Reading records from a partition, handling truncation, and managing the consumer position. The Consumer class maintains a Position which is the offset of the next record to be read Consumer.cs:55. The PollAsync method fetches records and advances the position, but it can throw a RecordExceedsMaxBytesException if a record is too large to fit within the MaxBytes limit Consumer.cs:94.

More: FetchAsync and Consumer

Topic Partitioning

Using FNV-1a hashing to map keys to specific partitions. The Partitioner class provides the Fnv1a32 hash function which uses an unchecked context to allow arithmetic wrapping Partitioner.cs:33. The PartitionFor method then folds this hash into the range of available partitions using the modulo operator Partitioner.cs:54.

Crc32C Verification

Checksum validation for record integrity using the Castagnoli polynomial. The Crc32C class implements the CRC-32C algorithm using a pre-computed table for efficiency Crc32C.cs:34. This is used during the Decode process in a Consumer to ensure that the bytes received match the checksum stored with the record Consumer.cs:214.

Error Handling and Protocol Exceptions

Distinguishing between broker refusals, protocol violations, and data corruption. The client distinguishes between different failure modes:

ExceptionTypeCause
BrokerExceptionRefusalThe broker understood the request but declined it (e.g., UnknownTopicOrPartition) Errors.cs:35
ProtocolExceptionViolationThe bytes on the connection do not make sense, such as a frame length out of range Errors.cs:42
CorruptRecordExceptionCorruptionA record's computed checksum does not match the stored checksum Errors.cs:52

Key files

FileLinesWhat is there
…/Booblik/Booblik.csproj1-33Project configuration and dependencies
…/Booblik/Connection.cs40-387The Connection, AckPolicy, PartitionInfo, ProduceResult, and Topic classes
…/Booblik/Consumer.cs38-227The Consumer class and Fetched record
…/Booblik/Crc32C.cs27-65The Crc32C static utility class
…/Booblik/Errors.cs4-64Error enums and custom exception types
…/Booblik/Partitioner.cs14-57The Partitioner static utility class

Behaviour that surprises

  • Connection.SendAsync increments a _correlation field to match requests and responses, meaning the connection is not safe for concurrent use Connection.cs:60.
  • Consumer.PollAsync advances the Position only after a successful fetch, and if a fetch is truncated, the partial record is dropped and the next poll starts from the beginning of that record Consumer.cs:106.
  • Partitioner.PartitionFor will throw an ArgumentOutOfRangeException if the number of partitions is not a positive integer Partitioner.cs:55.

On this page