Skip to content

Commit d8f57e4

Browse files
committed
14: Setup channel again with current callbacks whenever channel goes down.
1 parent 4b1459b commit d8f57e4

File tree

1 file changed

+33
-19
lines changed

1 file changed

+33
-19
lines changed

src/nwnsdk/rabbitmq/rabbitmq_client.py

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import logging
44
import threading
55
from enum import Enum
6-
from typing import Callable, Dict
6+
from typing import Callable, Dict, Optional
77
from uuid import uuid4
88

99
import pika
@@ -37,18 +37,21 @@ def from_workflow_type(workflow_type: WorkFlowType) -> "Queue":
3737

3838

3939
class RabbitmqClient(threading.Thread):
40+
rabbitmq_callbacks: Dict[Queue, PikaCallback]
4041
rabbitmq_is_running: bool
4142
rabbitmq_config: RabbitmqConfig
4243
rabbitmq_exchange: str
43-
connection: pika.BlockingConnection
44-
channel: BlockingChannel
45-
queue: str
44+
rabbitmq_connection: Optional[pika.BlockingConnection]
45+
rabbitmq_channel: Optional[BlockingChannel]
4646

4747
def __init__(self, config: RabbitmqConfig):
4848
super().__init__()
49+
self.rabbitmq_callbacks = {}
4950
self.rabbitmq_is_running = False
5051
self.rabbitmq_config = config
5152
self.rabbitmq_exchange = config.exchange_name
53+
self.rabbitmq_connection = None
54+
self.rabbitmq_channel = None
5255

5356
def _connect_rabbitmq(self):
5457
# initialize rabbitmq connection
@@ -69,25 +72,33 @@ def _connect_rabbitmq(self):
6972
connection_attempts=10,
7073
)
7174

72-
self.connection = pika.BlockingConnection(parameters)
73-
74-
self.channel = self.connection.channel()
75-
self.channel.basic_qos(prefetch_size=0, prefetch_count=1)
76-
self.channel.exchange_declare(exchange=self.rabbitmq_exchange, exchange_type="topic")
77-
for queue_item in Queue:
78-
queue = self.channel.queue_declare(queue_item.value, exclusive=False).method.queue
79-
self.channel.queue_bind(queue, self.rabbitmq_exchange, routing_key=queue_item.value)
75+
if not self.rabbitmq_connection or self.rabbitmq_connection.is_closed:
76+
LOGGER.info("Setting up a new connection to RabbitMQ.")
77+
self.rabbitmq_connection = pika.BlockingConnection(parameters)
78+
79+
if not self.rabbitmq_channel or self.rabbitmq_channel.is_closed:
80+
LOGGER.info("Setting up a new channel to RabbitMQ.")
81+
self.rabbitmq_channel = self.rabbitmq_connection.channel()
82+
self.rabbitmq_channel.basic_qos(prefetch_size=0, prefetch_count=1)
83+
self.rabbitmq_channel.exchange_declare(exchange=self.rabbitmq_exchange, exchange_type="topic")
84+
for queue_item in Queue:
85+
queue = self.rabbitmq_channel.queue_declare(queue_item.value, exclusive=False).method.queue
86+
self.rabbitmq_channel.queue_bind(queue, self.rabbitmq_exchange, routing_key=queue_item.value)
87+
88+
for queue, callback in self.rabbitmq_callbacks.items():
89+
self.rabbitmq_channel.basic_consume(queue=queue.value, on_message_callback=callback, auto_ack=False)
8090
LOGGER.info("Connected to RabbitMQ")
8191

8292
def _start_rabbitmq(self):
8393
self._connect_rabbitmq()
8494
self.start()
8595

8696
def set_callbacks(self, callbacks: Dict[Queue, PikaCallback]):
97+
self.rabbitmq_callbacks.update(callbacks)
8798
for queue, callback in callbacks.items():
88-
self.connection.add_callback_threadsafe(
99+
self.rabbitmq_connection.add_callback_threadsafe(
89100
functools.partial(
90-
self.channel.basic_consume, queue=queue.value, on_message_callback=callback, auto_ack=False
101+
self.rabbitmq_channel.basic_consume, queue=queue.value, on_message_callback=callback, auto_ack=False
91102
)
92103
)
93104

@@ -98,9 +109,12 @@ def run(self):
98109
try:
99110
LOGGER.info("Waiting for input...")
100111
while self.rabbitmq_is_running:
101-
self.connection.process_data_events(time_limit=1)
112+
self.rabbitmq_channel._process_data_events(time_limit=1)
102113
except pika.exceptions.ConnectionClosedByBroker as exc:
103114
LOGGER.info('Connection was closed by broker. Reason: "%s". Shutting down...', exc.reply_text)
115+
except pika.exceptions.ChannelClosedByBroker as exc:
116+
LOGGER.info('Channel was closed by broker. Reason: "%s". retrying...', exc.reply_text)
117+
self._connect_rabbitmq()
104118
except pika.exceptions.AMQPConnectionError:
105119
LOGGER.info("Connection was lost, retrying...")
106120
self._connect_rabbitmq()
@@ -113,13 +127,13 @@ def _send_start_work_flow(self, job_id: uuid4, work_flow_type: WorkFlowType):
113127

114128
def _send_output(self, queue: Queue, message: str):
115129
body: bytes = message.encode("utf-8")
116-
self.connection.add_callback_threadsafe(
130+
self.rabbitmq_connection.add_callback_threadsafe(
117131
functools.partial(
118-
self.channel.basic_publish, exchange=self.rabbitmq_exchange, routing_key=queue.value, body=body
132+
self.rabbitmq_channel.basic_publish, exchange=self.rabbitmq_exchange, routing_key=queue.value, body=body
119133
)
120134
)
121135

122136
def _stop_rabbitmq(self):
123137
self.rabbitmq_is_running = False
124-
if self.connection:
125-
self.connection.add_callback_threadsafe(self.connection.close)
138+
if self.rabbitmq_connection:
139+
self.rabbitmq_connection.add_callback_threadsafe(self.rabbitmq_connection.close)

0 commit comments

Comments
 (0)