@@ -36,7 +36,7 @@ class RdKafkaContext implements Context
3636 private $ conf ;
3737
3838 /**
39- * @var Producer
39+ * @var RdKafkaProducer
4040 */
4141 private $ producer ;
4242
@@ -96,7 +96,23 @@ public function createTemporaryQueue(): Queue
9696 */
9797 public function createProducer (): Producer
9898 {
99- return new RdKafkaProducer ($ this ->getProducer (), $ this ->getSerializer ());
99+ if (!isset ($ this ->producer )) {
100+ $ producer = new VendorProducer ($ this ->getConf ());
101+
102+ if (isset ($ this ->config ['log_level ' ])) {
103+ $ producer ->setLogLevel ($ this ->config ['log_level ' ]);
104+ }
105+
106+ $ this ->producer = new RdKafkaProducer ($ producer , $ this ->getSerializer ());
107+
108+ // Once created RdKafkaProducer can store messages internally that need to be delivered before PHP shuts
109+ // down. Otherwise, we are bound to lose messages in transit.
110+ // Note that it is generally preferable to call "close" method explicitly before shutdown starts, since
111+ // otherwise we might not have access to some objects, like database connections.
112+ register_shutdown_function ([$ this ->producer , 'flush ' ], $ this ->config ['shutdown_timeout ' ] ?? -1 );
113+ }
114+
115+ return $ this ->producer ;
100116 }
101117
102118 /**
@@ -139,6 +155,11 @@ public function close(): void
139155 foreach ($ kafkaConsumers as $ kafkaConsumer ) {
140156 $ kafkaConsumer ->unsubscribe ();
141157 }
158+
159+ // Compatibility with phprdkafka 4.0.
160+ if (isset ($ this ->producer )) {
161+ $ this ->producer ->flush ($ this ->config ['shutdown_timeout ' ] ?? -1 );
162+ }
142163 }
143164
144165 public function createSubscriptionConsumer (): SubscriptionConsumer
@@ -163,19 +184,6 @@ public static function getLibrdKafkaVersion(): string
163184 return "$ major. $ minor. $ patch " ;
164185 }
165186
166- private function getProducer (): VendorProducer
167- {
168- if (null === $ this ->producer ) {
169- $ this ->producer = new VendorProducer ($ this ->getConf ());
170-
171- if (isset ($ this ->config ['log_level ' ])) {
172- $ this ->producer ->setLogLevel ($ this ->config ['log_level ' ]);
173- }
174- }
175-
176- return $ this ->producer ;
177- }
178-
179187 private function getConf (): Conf
180188 {
181189 if (null === $ this ->conf ) {
0 commit comments