mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
feat(portal): Receive WAL events (#8909)
Firezone's control plane is a realtime, distributed system that relies on a broadcast/subscribe system to function. In many cases, these events are broadcasted whenever relevant data in the DB changes, such as an actor losing access to a policy, a membership being deleted, and so forth. Today, this is handled in the application layer, typically happening at the place where the relevant DB call is made (i.e. in an `after_commit`). While this approach has worked thus far, it has several issues: 1. We have no guarantee that the DB change will issue a broadcast. If the application is deployed or the process crashes after the DB changes are made but before the broadcast happens, we will have potentially failed to update any connected clients or gateways with the changes. 2. We have no guarantee that the order of DB updates will be maintained in order for broadcasts. In other words, app server A could win its DB operation against app server B, but then proceed to lose being the first to broadcast. 3. If the cluster is in a bad state where broadcasts may return an error (i.e. https://github.com/firezone/firezone/issues/8660), we will never retry the broadcast. To fix the above issues, we introduce a WAL logical decoder that process the event stream one message at a time and performs any needed work. Serializability is guaranteed since we only process the WAL in a single, cluster-global process, `ReplicationConnection`. Durability is also guaranteed since we only ACK WAL segments after we've successfully ingested the event. This means we will only advance the position of our WAL stream after successfully broadcasting the event. This PR only introduces the WAL stream processing system but does not introduce any changes to our current broadcasting behavior - that's saved for another PR.
This commit is contained in:
40
.github/actions/setup-postgres/action.yml
vendored
Normal file
40
.github/actions/setup-postgres/action.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
name: "Setup Postgres"
|
||||
description: "Starts a Postgres container"
|
||||
inputs:
|
||||
version:
|
||||
default: "latest"
|
||||
description: "Postgres version"
|
||||
required: false
|
||||
port:
|
||||
default: "5432"
|
||||
description: "Port to expose"
|
||||
required: false
|
||||
username:
|
||||
default: "postgres"
|
||||
description: "Username"
|
||||
required: false
|
||||
password:
|
||||
default: "postgres"
|
||||
description: "Password"
|
||||
required: false
|
||||
options:
|
||||
default: ""
|
||||
description: "Additional options to pass to the container"
|
||||
required: false
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Start Postgres
|
||||
id: start-postgres
|
||||
shell: bash
|
||||
run: |
|
||||
docker run \
|
||||
--name postgres \
|
||||
--env POSTGRES_USER=${{ inputs.username }} \
|
||||
--env POSTGRES_PASSWORD=${{ inputs.password }} \
|
||||
--publish ${{ inputs.port }}:5432 \
|
||||
--health-cmd pg_isready \
|
||||
--health-interval 10s \
|
||||
--health-timeout 5s \
|
||||
--health-retries 5 \
|
||||
--detach postgres:${{ inputs.version }} postgres -c "wal_level=logical"
|
||||
Reference in New Issue
Block a user