()
| 105 | let producerConnectPromise: Promise<Producer> | null = null; |
| 106 | |
| 107 | const getProducer = async (): Promise<Producer> => { |
| 108 | if (producer) { |
| 109 | return producer; |
| 110 | } |
| 111 | if (!producerConnectPromise) { |
| 112 | const client = getKafka(); |
| 113 | const p = client.producer({ |
| 114 | idempotent: true, |
| 115 | // 1 (not 5) to avoid in-flight reordering after a transient broker hiccup: |
| 116 | // with idempotency on and low retries, reordered batches trip |
| 117 | // OUT_OF_ORDER_SEQUENCE_NUMBER and stick the producer per-partition. |
| 118 | maxInFlightRequests: 1, |
| 119 | allowAutoTopicCreation: true, |
| 120 | retry: { |
| 121 | retries: KAFKA_PRODUCER_RETRIES, |
| 122 | initialRetryTime: KAFKA_PRODUCER_INITIAL_RETRY_MS, |
| 123 | maxRetryTime: KAFKA_PRODUCER_MAX_RETRY_MS, |
| 124 | factor: 2, |
| 125 | }, |
| 126 | }); |
| 127 | producerConnectPromise = p |
| 128 | .connect() |
| 129 | .then(() => { |
| 130 | producer = p; |
| 131 | kafkaLogger.info( |
| 132 | { brokers: KAFKA_BROKERS, topic: KAFKA_EVENTS_TOPIC }, |
| 133 | 'kafka producer connected' |
| 134 | ); |
| 135 | return p; |
| 136 | }) |
| 137 | .catch((err) => { |
| 138 | producerConnectPromise = null; |
| 139 | throw err; |
| 140 | }); |
| 141 | } |
| 142 | return producerConnectPromise; |
| 143 | }; |
| 144 | |
| 145 | // Kafka error codes that mean the producer's PID/sequence state is |
| 146 | // permanently out of sync with the broker for some partition — only a |
no test coverage detected