A Book about Pythonic Application Architecture Patterns for Managing Complexity. Cosmos is the Opposite of Chaos you see. O'R. wouldn't actually let us call it "Cosmic Python" tho.
Comments on sections where there may be footguns related to messaging.
Section 5.6 Version Numbers
If two uow's conflict, what should the loser do? Fail-fast and punt to the client? Refresh its data and re-try the business logic again? (Not exactly about reliable messaging, but maybe worth a blog post).
Section 7.4.2 A New Method on the Domain Model
Section 8.4 Recovering from Errors Synchronously
The new domain model has introduced an edge case in error handling. To handle a change in batch quantity, two UoWs must complete sequentially. If the first succeeds, and the second fails (due to network issues) etc. Then the allocation will be lost. The Outbox Pattern is one helpful solution here.
Section 9.4 Redis pubsub
Redis PUBSUB is not reliable and your application will implement at-most once processing. If this is not OK, then implement at-least once publishing use RPOPLPUSH to ensure that messages aren't lost. The listeners should then be idempotent.
Other queue technologies will have similar ways of handling (ack/nak in RabbitMQ).
Queues like Kafka implement a a different model, based on tailing a log. (Note: The "publishing part" of the Outbox message could be implemented as log tailing.) When a client fails, it restarts processing by seeking to an offset into the log.
Comments on sections where there may be footguns related to messaging.
Section 5.6 Version Numbers
Section 7.4.2 A New Method on the Domain Model Section 8.4 Recovering from Errors Synchronously
Section 9.4 Redis pubsub