You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -59,84 +59,12 @@ To use database storage for events:
59
59
60
60
Events can be distributed via an AMQP messaging system. This messaging system enables new
61
61
integrations to subscribe to the events. The system supports either RabbitMQ or Azure Service Bus.
62
+
For a detailed look at the architecture and technical details, see
63
+
[the documentation in the server repo](https://github.com/bitwarden/server/tree/6800bc57f3eb492222e128cffcd00e16b29cc155/src/Core/AdminConsole/Services/Implementations/EventIntegrations).
62
64
63
-
### Listener / Handler pattern
64
-
65
-
The goal of moving to distributed events is to build additional service integrations that consume
66
-
events. To make it easy to support multiple AMQP services (RabbitMQ and Azure Service Bus), the act
67
-
of listening to the stream of events is decoupled from the act of responding to an event.
68
-
69
-
**Listeners**
70
-
71
-
- One listener per communication platform (e.g. one for RabbitMQ, one for Azure Service Bus).
72
-
- Multiple instances can be configured to run independently, each with its own handler and
73
-
subscription / queue.
74
-
- Perform all the aspects of setup / teardown, subscription, etc. for the messaging platform, but do
75
-
not directly process any events themselves. Instead, they delegate to the handler with which they
76
-
are configured.
77
-
78
-
**Handlers**
79
-
80
-
- One handler per integration (e.g. HTTP post or event database repository).
81
-
- Completely isolated from and know nothing of the messaging platform in use. This allows them to be
82
-
freely reused across different communication platforms.
83
-
- Perform all aspects of handling an event.
84
-
- Allows them to be highly testable as they are isolated and decoupled from the more complicated
85
-
aspects of messaging.
86
-
87
-
This combination allows for a configuration inside of `Startup.cs` that pairs instances of the
88
-
listener service for the currently running messaging platform with any number of handlers. It also
89
-
allows for quick development of new handlers as they are focused only on the task of handling a
90
-
specific event.
91
-
92
-
### RabbitMQ implementation
93
-
94
-
The RabbitMQ implementation adds a step that refactors the way events are handled when running
95
-
locally or self-hosted. Instead of writing directly to the `Events` table via the
96
-
`EventsRepository`, each event is broadcast to a RabbitMQ exchange. A new
97
-
`RabbitMqEventListenerService` instance, configured with an `EventRepositoryHandler`, subscribes to
98
-
the RabbitMQ exchange and writes to the `Events` table via the `EventsRepository`. The end result is
99
-
the same (events are stored in the database), but the addition of the RabbitMQ exchange allows for
100
-
other integrations to subscribe.
101
-
102
-
Additional handlers - each paired with their own `RabbitMqEventListenerService` and listening to
103
-
their own queue - are available to be configured as well.
104
-
105
-
-`SlackEventHandler` posts messages to Slack channels or DMs.
106
-
-`WebhookEventHandler``POST`s each event to a configurable URL.
107
-
108
-
```kroki type=mermaid
109
-
graph TD
110
-
subgraph With RabbitMQ
111
-
B1[EventService]
112
-
B2[RabbitMQEventWriteService]
113
-
B3[RabbitMQ exchange]
114
-
B4[EventRepositoryHandler]
115
-
B5[WebhookEventHandler]
116
-
B6[Events Database Table]
117
-
B7[HTTP Server]
118
-
B8[SlackEventHandler]
119
-
B9[Slack]
120
-
121
-
B1 -->|IEventWriteService| B2 --> B3
122
-
B3-->|RabbitMqEventListenerService| B4 --> B6
123
-
B3-->|RabbitMqEventListenerService| B5
124
-
B5 -->|HTTP POST| B7
125
-
B3-->|RabbitMqEventListenerService| B8
126
-
B8 -->|HTTP POST| B9
127
-
end
128
-
129
-
subgraph Without RabbitMQ
130
-
A1[EventService]
131
-
A2[RepositoryEventWriteService]
132
-
A3[Events Database Table]
133
-
134
-
A1 -->|IEventWriteService| A2 --> A3
135
-
136
-
end
137
-
```
65
+
### RabbitMQ
138
66
139
-
#### Running the RabbitMQ container
67
+
#### Running the RabbitMQ container (default using fixed-delay queues)
140
68
141
69
1. Verify that you've set a username and password in the `.env` file (see `.env.example` for an
142
70
example)
@@ -154,6 +82,36 @@ end
154
82
3. To verify this is running, open `http://localhost:15672` in a browser and login with the
155
83
username and password in your `.env` file.
156
84
85
+
#### Running the RabbitMQ container (with optional delay plugin)
86
+
87
+
The standard installation of RabbitMQ does not support delaying message delivery. Our default option
88
+
instead uses retry queues with a fixed amount of delay and checks the `DelayUntilDate` in each
89
+
message to see if it is time for them to br processed. This provides the delay needed for retries
90
+
(with backoff and jitter applied), but it does require more processing.
91
+
92
+
As an alternate approach, we have support for RabbitMQ's optional delay plugin - which does support
93
+
adding a precise delay to a message and handles publishing at the specified time. It does require
94
+
the plugin to be installed and enabled before running and is therefore not the default setup. To
0 commit comments