@@ -83,7 +83,7 @@ public class DefaultKafkaProducerFactory<K, V> implements ProducerFactory<K, V>,
8383
8484 private final BlockingQueue <CloseSafeProducer <K , V >> cache = new LinkedBlockingQueue <>();
8585
86- private final Map <String , Producer <K , V >> consumerProducers = new HashMap <>();
86+ private final Map <String , CloseSafeProducer <K , V >> consumerProducers = new HashMap <>();
8787
8888 private volatile CloseSafeProducer <K , V > producer ;
8989
@@ -187,8 +187,8 @@ public void destroy() throws Exception { //NOSONAR
187187 producer = this .cache .poll ();
188188 }
189189 synchronized (this .consumerProducers ) {
190- for (Entry <String , Producer <K , V >> entry : this .consumerProducers .entrySet ()) {
191- (( CloseSafeProducer < K , V >) entry .getValue () ).delegate
190+ for (Entry <String , CloseSafeProducer <K , V >> entry : this .consumerProducers .entrySet ()) {
191+ entry .getValue ().delegate
192192 .close (this .physicalCloseTimeout , TimeUnit .SECONDS );
193193 }
194194 this .consumerProducers .clear ();
@@ -255,7 +255,7 @@ private Producer<K, V> createTransactionalProducerForPartition() {
255255 else {
256256 synchronized (this .consumerProducers ) {
257257 if (!this .consumerProducers .containsKey (suffix )) {
258- Producer <K , V > newProducer = doCreateTxProducer (suffix );
258+ CloseSafeProducer <K , V > newProducer = doCreateTxProducer (suffix );
259259 this .consumerProducers .put (suffix , newProducer );
260260 return newProducer ;
261261 }
@@ -282,7 +282,7 @@ protected Producer<K, V> createTransactionalProducer() {
282282 }
283283 }
284284
285- private Producer <K , V > doCreateTxProducer (String suffix ) {
285+ private CloseSafeProducer <K , V > doCreateTxProducer (String suffix ) {
286286 Producer <K , V > producer ;
287287 Map <String , Object > configs = new HashMap <>(this .configs );
288288 configs .put (ProducerConfig .TRANSACTIONAL_ID_CONFIG , this .transactionIdPrefix + suffix );
@@ -295,6 +295,17 @@ protected BlockingQueue<CloseSafeProducer<K, V>> getCache() {
295295 return this .cache ;
296296 }
297297
298+ public void closeProducerFor (String transactionIdSuffix ) {
299+ if (this .producerPerConsumerPartition ) {
300+ synchronized (this .consumerProducers ) {
301+ CloseSafeProducer <K , V > removed = this .consumerProducers .remove (transactionIdSuffix );
302+ if (removed != null ) {
303+ removed .delegate .close (this .physicalCloseTimeout , TimeUnit .SECONDS );
304+ }
305+ }
306+ }
307+ }
308+
298309 /**
299310 * A wrapper class for the delegate.
300311 *
@@ -308,7 +319,7 @@ protected static class CloseSafeProducer<K, V> implements Producer<K, V> {
308319
309320 private final BlockingQueue <CloseSafeProducer <K , V >> cache ;
310321
311- private final Map <String , Producer <K , V >> consumerProducers ;
322+ private final Map <String , CloseSafeProducer <K , V >> consumerProducers ;
312323
313324 private volatile boolean txFailed ;
314325
@@ -322,7 +333,7 @@ protected static class CloseSafeProducer<K, V> implements Producer<K, V> {
322333 }
323334
324335 CloseSafeProducer (Producer <K , V > delegate , BlockingQueue <CloseSafeProducer <K , V >> cache ,
325- Map <String , Producer <K , V >> consumerProducers ) {
336+ Map <String , CloseSafeProducer <K , V >> consumerProducers ) {
326337 this .delegate = delegate ;
327338 this .cache = cache ;
328339 this .consumerProducers = consumerProducers ;
@@ -426,7 +437,8 @@ public void close(long timeout, TimeUnit unit) {
426437
427438 private void removeConsumerProducer () {
428439 synchronized (this .consumerProducers ) {
429- Iterator <Entry <String , Producer <K , V >>> iterator = this .consumerProducers .entrySet ().iterator ();
440+ Iterator <Entry <String , CloseSafeProducer <K , V >>> iterator = this .consumerProducers .entrySet ()
441+ .iterator ();
430442 while (iterator .hasNext ()) {
431443 if (iterator .next ().getValue ().equals (this )) {
432444 iterator .remove ();
0 commit comments