pablocom / PersonalSite.Backend

This repository is used to study Domain-Driven Design principles, practices and patterns.
4 stars 0 forks source link

Implement outbox pattern for publishing events #19

Closed pablocom closed 1 year ago

pablocom commented 1 year ago

Description

This PR contains the implementation of the outbox pattern as a demostration for reliable messaging in distributed systems. It basically uses the database transaction to store in a table all the integration events that later will be publish into a message bus. https://learn.microsoft.com/en-us/azure/architecture/best-practices/transactional-outbox-cosmos

The following two scenarios ilustrates how outbox pattern makes integration event publishing reliable in the case of a transient error on the connection with the message bus:

Without outbox pattern

sequenceDiagram
    CommandHandler->>Database: Save entities
    activate CommandHandler
    activate Database
    Database -->>CommandHandler: ok
    deactivate Database
    CommandHandler->>MessageBus: Publish integration events
    activate MessageBus
    rect rgb(200, 0, 0, 0.3)
    break when publish of events fail
        MessageBus-->>CommandHandler: Connection with message bus failed 
        Note right of Database: Other services won't have data updated.
    end
    end
    deactivate CommandHandler

With outbox pattern

sequenceDiagram
    CommandHandler->>Database: Save entities and integration events
    activate CommandHandler
    activate Database
    Database-->>CommandHandler: ok
    deactivate CommandHandler
    deactivate Database
    Worker->>Database: Read integration events to publish
    activate Database
    activate Worker
    Database -->>Worker: ok
    deactivate Database
    Worker->>MessageBus: Publish integration events
    rect rgb(200, 0, 0, 0.3)
    break when publish of events fail
        MessageBus-->>Worker: Connection with message bus failed
    end
    end
    deactivate Worker
    Worker->>Database: Read integration events to publish
    activate Worker
    activate Database
    Database -->>Worker: ok
    deactivate Database
    Worker->>MessageBus: Publish integration events
    MessageBus-->>Worker: ok
    deactivate Worker

Note: implementation in this PR It's mainly for learning and practicing purposes. Integration event publishing and event store data model must be adjusted depending on the messaging framework.