Merge "Remove logging from ProducerConnection._produce_message"

This commit is contained in:
Zuul 2022-12-21 07:46:22 +00:00 committed by Gerrit Code Review
commit 9f710ce6cd
3 changed files with 67 additions and 15 deletions

View File

@ -265,18 +265,17 @@ class ProducerConnection(Connection):
self.producer = None self.producer = None
self.producer_lock = threading.Lock() self.producer_lock = threading.Lock()
def _produce_message(self, topic, message): def _produce_message(self, topic, message, poll):
while True: if poll:
try: self.producer.poll(poll)
self.producer.produce(topic, message) try:
except KafkaException as e: self.producer.produce(topic, message)
LOG.error("Produce message failed: %s" % str(e)) except KafkaException as e:
except BufferError: self.producer.poll(0)
LOG.debug("Produce message queue full, waiting for deliveries") raise e
self.producer.poll(0.5) except BufferError as e:
continue # We'll have to poll next time
break raise e
self.producer.poll(0) self.producer.poll(0)
def notify_send(self, topic, ctxt, msg, retry): def notify_send(self, topic, ctxt, msg, retry):
@ -293,9 +292,22 @@ class ProducerConnection(Connection):
try: try:
self._ensure_producer() self._ensure_producer()
if eventletutils.is_monkey_patched('thread'): poll = 0
return tpool.execute(self._produce_message, topic, message) while True:
return self._produce_message(topic, message) try:
if eventletutils.is_monkey_patched('thread'):
return tpool.execute(self._produce_message, topic,
message, poll)
return self._produce_message(topic, message, poll)
except KafkaException as e:
LOG.error("Produce message failed: %s" % str(e))
break
except BufferError:
LOG.debug("Produce message queue full, "
"waiting for deliveries")
# We'll retry with .5s polling
poll = 0.5
except Exception: except Exception:
# NOTE(sileht): if something goes wrong close the producer # NOTE(sileht): if something goes wrong close the producer
# connection # connection

View File

@ -15,6 +15,8 @@
import testscenarios import testscenarios
from unittest import mock from unittest import mock
from confluent_kafka import KafkaException
import oslo_messaging import oslo_messaging
from oslo_messaging._drivers import impl_kafka as kafka_driver from oslo_messaging._drivers import impl_kafka as kafka_driver
from oslo_messaging.tests import utils as test_utils from oslo_messaging.tests import utils as test_utils
@ -120,6 +122,36 @@ class TestKafkaDriver(test_utils.BaseTestCase):
'ssl.key.password': '', 'ssl.key.password': '',
}) })
def test_send_notification_retries_on_buffer_error(self):
target = oslo_messaging.Target(topic="topic_test")
with mock.patch("confluent_kafka.Producer") as producer:
fake_producer = mock.MagicMock()
fake_producer.produce = mock.Mock(
side_effect=[BufferError, BufferError, None])
producer.return_value = fake_producer
self.driver.send_notification(
target, {}, {"payload": ["test_1"]},
None, retry=3)
assert fake_producer.produce.call_count == 3
def test_send_notification_stops_on_kafka_error(self):
target = oslo_messaging.Target(topic="topic_test")
with mock.patch("confluent_kafka.Producer") as producer:
fake_producer = mock.MagicMock()
fake_producer.produce = mock.Mock(
side_effect=[KafkaException, None])
producer.return_value = fake_producer
self.driver.send_notification(
target, {}, {"payload": ["test_1"]},
None, retry=3)
assert fake_producer.produce.call_count == 1
def test_listen(self): def test_listen(self):
target = oslo_messaging.Target(topic="topic_test") target = oslo_messaging.Target(topic="topic_test")
self.assertRaises(NotImplementedError, self.driver.listen, target, self.assertRaises(NotImplementedError, self.driver.listen, target,

View File

@ -0,0 +1,8 @@
---
fixes:
- |
[`bug 1981093 <https://bugs.launchpad.net/oslo.messaging/+bug/1981093>`_]
Pulls calls to logging functions out of ``impl_kafka._produce_message``.
Since ``_produce_message`` is called through tpool.execute, calling logging
functions inside ``_produce_message`` could cause subsequent calls to
logging functions to deadlock.