Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Router on postgres #389

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft

Router on postgres #389

wants to merge 3 commits into from

Conversation

Tetrino
Copy link
Contributor

@Tetrino Tetrino commented Aug 22, 2023

The underlying functionality is the same, but we are moving away from
mongo to postgres to ensure we can continue to maintain the app.

We no longer keep soft copies of the data read from the database,
instead reading each row from memory.

We no longer rely on comparing OpTime from Mongo changes, instead relying
on PSQL's LISTEN/NOTIFY process to notify us of changes. However, in order
to avoid overloading with constant update requests, we still poll
the update every two seconds.

https://trello.com/c/YJro3BGj

@Tetrino Tetrino force-pushed the router-on-postgres branch 18 times, most recently from 4596254 to 268d251 Compare August 23, 2023 13:33
@Tetrino Tetrino force-pushed the router-on-postgres branch 7 times, most recently from 2b73fb8 to cff0771 Compare September 5, 2023 11:08
@Tetrino Tetrino force-pushed the router-on-postgres branch 3 times, most recently from e2a0e19 to 266ed28 Compare September 6, 2023 10:54
pq is a standard library for interacting with postgresql databases in
golang. It is currently in maintenance mode so is as stable as it can
be for the foreseeable future.
The underlying functionality is the same, but we are moving away from
mongo to postgres to ensure we can continue to maintain the app.

We no longer keep soft copies of the data read from the database,
instead reading each row from memory.

We no longer rely on comparing OpTime from Mongo changes, instead relying
on PSQL's LISTEN/NOTIFY process to notify us of changes. However, in order
to avoid overloading with constant update requests, we still poll
the update every two seconds.
Makefile Outdated
--health-start-period 5s \
postgres:14; \
echo Waiting for postgres to be up; \
until [ "`docker inspect -f '{{.State.Health.Status}}' router-postgres-test-db`" = "healthy" ]; do \
Copy link
Contributor

@sengi sengi Sep 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional: if Docker or the container fails then this could get stuck for a long time (6h on GitHub Actions), so could so with for _ in $(seq 30) so we fail faster

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry that was meant to be sent along with the review rather than as a one-off (I hit the wrong button)

Copy link
Contributor

@sengi sengi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool — I like the minimal approach.

Makefile Outdated
--health-start-period 5s \
postgres:14; \
echo Waiting for postgres to be up; \
until [ "`docker inspect -f '{{.State.Health.Status}}' router-postgres-test-db`" = "healthy" ]; do \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry that was meant to be sent along with the review rather than as a one-off (I hit the wrong button)

RedirectType string `bson:"redirect_type"`
SegmentsMode string `bson:"segments_mode"`
Disabled bool `bson:"disabled"`
IncomingPath sql.NullString
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

optional: it'd be neat if we could use plain old strings here and deal with the nullability in loadRoutes or wherever, then we could delete this struct's evil twin in integration_tests/route_helpers.go. (Would also mean you wouldn't need to deal with nulls in all the places that use struct Route.)

for _, instance := range replicaSet.Members {
if instance.Current {
currentInstance = append(currentInstance, instance)
func (rt *Router) shouldReload(listener *pq.Listener) bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is so much neater — I love it

localdb_init.sql Outdated
FOR EACH ROW
EXECUTE PROCEDURE notify_listeners();

CREATE TRIGGER rotues_notify_trigger
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

harmless typo

Suggested change
CREATE TRIGGER rotues_notify_trigger
CREATE TRIGGER routes_notify_trigger

@@ -0,0 +1,67 @@
DROP DATABASE IF EXISTS router_test;
Copy link
Contributor

@sengi sengi Sep 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(no action needed) It's kind of a shame we need this almost-but-not-quite-identical copy of the schema here, but I agree it's probably the right call in the interests of time rather than revamping the way the tests work to pull in the real schema from router-api 👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @sengi

The very slight downside of having router-api being the source of the database is that it makes everything in govuk-docker that depends on router now also dependent on router-api. But the advantages of having it as an ordinary rails migration outweighs that (plus the fact that router/router-api doesn't really work on govuk-docker at the moment anyway, and converting to PG might unblock that problem).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That just sounds like a govuk-docker bug/flaw tbh :) I hope next quarter we'll be able to make govuk-helm-charts portable enough to replace at least some govuk-docker use cases in local development / testing.

@sengi
Copy link
Contributor

sengi commented Sep 20, 2023

my optionals are genuinely optional btw — totally fine if you prefer not to do them (and no need to justify!)

Very little of the tests themselves had to be rewritten to reflect
the system being postgres, however a number of tests that relied on
mocking Mongo are no longer valid in the Postgres implementation
and have been removed.

We now spin up a test PSQL database container using an initialiser
sql file to test against.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants