@CoffeeExpress sorry for the slow reply here.
You will run into this situation whenever the definition of a queue or exchange changes and they have already been declared. Unfortunately they are not mutable, so the only remedy is to remove the existing exchange and let it be redeclared with the new definition.
To make matters worse, if you delete the exchange while older versions of the services are still running, the older versions will either declare it with the old definition, or complain with the same error if the new service managed to redeclare first.
If you can tolerate downtime, you can stop all existing services, delete the exchange, and then roll out upgraded versions.
If not, you have to prevent the new services from trying to redeclare the event exchange. There is no good hook for this unfortunately, but you can do so by patching the get_event_exchange
function:
from nameko.events import event_handler
from unittest.mock import patch
def get_event_exchange(service_name):
from nameko.constants import PERSISTENT
from kombu import Exchange
exchange_name = "{}.events".format(service_name)
exchange = Exchange(
exchange_name,
type="topic",
durable=False,
delivery_mode=PERSISTENT,
no_declare=True,
)
return exchange
patch("nameko.events.get_event_exchange", new=get_event_exchange).start()
class Service:
name = "service"
@event_handler("foo", "bar")
def handle(self, evt):
pass
This is ugly but would allow you to release services using the latest version.
Once there’s no service automatically redeclaring the event exchange, you will be able to delete and redeclare it manually (with the correct policies) with little or no downtime.