[
https://issues.apache.org/jira/browse/CAMEL-24779?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen resolved CAMEL-24779.
---------------------------------
Resolution: Fixed
> camel-kafka - reduce per-message allocations on the producer, consumer and
> transform hot paths
> ----------------------------------------------------------------------------------------------
>
> Key: CAMEL-24779
> URL: https://issues.apache.org/jira/browse/CAMEL-24779
> Project: Camel
> Issue Type: Improvement
> Components: camel-kafka
> Reporter: Andrea Cosentino
> Assignee: Andrea Cosentino
> Priority: Major
> Fix For: 4.23.0
>
>
> This is a small, behaviour-preserving performance clean-up that bundles three
> per-message hot-path allocation reductions in camel-kafka. No public API or
> option changes.
> h3. 1. Producer: redundant callback allocation on the single-message async
> path
> {{KafkaProducer.process(Exchange, AsyncCallback)}} sends a single record via
> {{doSend(exchange, record, producerCallBack)}}. Because the key (the
> exchange) is non-null, {{doSend}} allocates a
> {{KafkaProducerMetadataCallBack}} *and* a {{DelegatingCallback}} for every
> message. For the single-message case this is redundant: the parent
> {{KafkaProducerCallBack}} already sets the exception and the
> {{CamelKafkaRecordMeta}} header (a {{List<RecordMetadata>}}) on the same
> exchange. Sending with the parent callback alone removes two short-lived
> allocations per message and produces an identical {{CamelKafkaRecordMeta}}
> result. The iterator/batch path is left unchanged (it genuinely needs a
> per-element metadata callback).
> h3. 2. Consumer: per-record Stream/lambda allocations in header propagation
> {{KafkaRecordProcessor.propagateHeaders}} builds a {{Stream}} + spliterator +
> two capturing lambdas for every consumed record, and re-resolves
> {{exchange.getIn()}} per header. Replacing it with a plain enhanced-for loop
> over {{consumerRecord.headers()}} with a hoisted {{Message}} removes the
> per-record pipeline and lambda garbage. Behaviour is identical.
> h3. 3. Transforms: ObjectMapper allocated per message
> Six transform classes ({{HoistField}}, {{MaskField}}, {{ExtractField}},
> {{ReplaceField}}, {{MessageTimestampRouter}}, {{ValueToKey}}) construct a
> {{new ObjectMapper()}} on every invocation. {{ObjectMapper}} is expensive to
> construct and thread-safe once configured; these back the corresponding
> Kamelet actions and therefore run per message. Reusing a single shared static
> {{ObjectMapper}} removes the allocation.
> All three changes are behaviour-preserving and covered by existing unit tests
> plus additions.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)