booblik
Wiki

clients/java

Generated page

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

What this module is responsible for

Documentation for the booblik Java client module.

Diagram

Connection and Topic Management

The lifecycle of a Connection is managed via a try-with-resources block, as seen in the usage examples in README.md:9-12. Topics are accessed through the connection via the topic(String) method, which retrieves partition information directly from the broker as described in README.md:10.

More: Connection and Topic Management

Producer Configuration and Batching

Performance is heavily dependent on the accumulator, where batching significantly increases throughput compared to sending single records (README.md:36-37). Users can tune the accumulator using ProducerConfig, which is defined in ProducerConfig.java:4.

The ProducerConfig parameters are:

ParameterTypeDescription
maxBatchSizeintThe maximum size of a batch
lingerMillislongTime to wait before sending a batch
ackAckPolicyThe acknowledgement policy

The default configuration is provided by ProducerConfig.defaults() in ProducerConfig.java:15.

More: Producer Configuration and Batching

ProduceResult and AckPolicy

A produce operation returns a ProduceResult, which contains the baseOffset and logEndOffset of the written batch (ProduceResult.java:4).

The AckPolicy determines the acknowledgement behavior:

ModeBehavior
WRITTENStandard acknowledgement
NONEReturns null or Producer.OFFSET_UNKNOWN; broker may drop records silently (README.md:59-64)

PartitionInfo and Partitioning

Metadata for a partition is encapsulated in the PartitionInfo record, which includes the partition index, the logStartOffset (the start of the live log after retention), and the highWatermark (PartitionInfo.java:7-9).

Partitioning logic is influenced by the key; while topic.send uses a key, the client's internal logic ensures that the key itself is not sent to the broker, but rather the partition index is determined by the key (README.md:65-67).

Consumer Iteration and Position Management

The Consumer implements Iterable<byte[]>, allowing for a standard for-each loop (README.md:90-92). The loop is blocking: hasNext() will block until data is available or the socket times out (README.md:101).

To ensure "at-least-once" delivery, the caller must manually track the position() of the consumer and persist it after the records are processed (README.md:93-94).

RecordExceedsMaxBytesException

If a record is larger than the client's configured maxBytes limit, a RecordExceedsMaxBytesException is thrown (README.md:115-116). This is a terminal error that cannot be resolved by retrying, as the record will never fit in the buffer (RecordExceedsMaxBytesException.java:10-13).

The exception contains the following fields:

FieldTypeDescription
offsetlongThe offset of the problematic record
recordBytesintThe size of the record in bytes
maxBytesintThe maximum allowed bytes

Key files

FileLinesWhat is there
…/java/ProduceResult.java4The ProduceResult record definition
…/java/PartitionInfo.java7-9Documentation for PartitionInfo fields
…/java/ProducerConfig.java4The ProducerConfig record definition
…/java/RecordExceedsMaxBytesException.java15The RecordExceedsMaxBytesException class definition
…/java/README.md9-12Example of connection and topic usage
…/java/build.gradle.kts34Compilation release version configuration

Behaviour that surprise

  • ProducerConfig.defaults(): A linger of zero is not the fastest setting; it sends every record individually, which is significantly slower than batching (README.md:10-12).
  • AckPolicy.NONE: This mode is the only one where the broker may drop an accepted record silently (README.md:63-64).
  • Consumer: The hasNext() method is always true and blocks until data is available because a partition has no defined end (README.md:101-102).

On this page