Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Use supervisord to supervise Postgres and Caddy in the Complement image. #12480

Merged
merged 12 commits into from
Apr 27, 2022

Conversation

reivilibre
Copy link
Contributor

This is still leading to corrupt Postgres databases, need to investigate.

Signed-off-by: Olivier Wilkinson (reivilibre) <oliverw@matrix.org>
Copy link
Member

@richvdh richvdh left a comment

Choose a reason for hiding this comment

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

it looks like supervisord still isn't ending up as PID 1 within the container.

Try replacing the entrypoint with an explicit shell invocation:

ENTRYPOINT ["/bin/bash", "/start-complement-synapse-workers.sh"]

from https://docs.docker.com/engine/reference/builder/#entrypoint:

The shell form ... has the disadvantage that your ENTRYPOINT will be started as a subcommand of /bin/sh -c, which does not pass signals. This means that the executable will not be the container’s PID 1 - and will not receive Unix signals - so your executable will not receive a SIGTERM from docker stop <container>.

(TIL. We probably ought to do something similar in our other Dockerfiles)

docker/complement/conf-workers/postgres.supervisord.conf Outdated Show resolved Hide resolved
@reivilibre
Copy link
Contributor Author

reivilibre commented Apr 21, 2022

It looks like supervisord is now PID 1 and the container stops within 4 seconds.
Postgres itself exits very rapidly, but supervisord stops processes with a higher priority before stopping it.
We could consider having supervisord SIGKILL Caddy, Redis and the Synapse workers if we really wanted to be as expedient as possible? Everything in there should be volatile, more or less, anyway. Do you think that sounds worthwhile?

@reivilibre reivilibre requested a review from richvdh April 21, 2022 13:11
@reivilibre reivilibre marked this pull request as ready for review April 21, 2022 13:11
@reivilibre reivilibre requested a review from a team as a code owner April 21, 2022 13:11
@reivilibre reivilibre removed the request for review from a team April 21, 2022 13:15
@richvdh
Copy link
Member

richvdh commented Apr 27, 2022

Postgres itself exits very rapidly, but supervisord stops processes with a higher priority before stopping it.

Do we actually need postgres to be a higher prority than synapse? It's not like there's any guarantee that doing so will mean that postgres is ready before synapse starts.

We could consider having supervisord SIGKILL Caddy, Redis and the Synapse workers if we really wanted to be as expedient as possible? Everything in there should be volatile, more or less, anyway. Do you think that sounds worthwhile?

Is it just synapse that is slow? I could be persuaded that SIGKILLing it might be good. Think I'd make it a separate PR though.

Copy link
Member

@richvdh richvdh left a comment

Choose a reason for hiding this comment

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

lgtm otherwise

docker/prefix-log Show resolved Hide resolved
changelog.d/12480.misc Outdated Show resolved Hide resolved
@reivilibre
Copy link
Contributor Author

reivilibre commented Apr 27, 2022

Do we actually need postgres to be a higher prority than synapse? It's not like there's any guarantee that doing so will mean that postgres is ready before synapse starts.

No, though Synapse's configuration already defined it at priority 500 so it seemed like this was the intention.
(I just realised: The main Synapse process' priority is actually defined as 10; Redis' is 1. Postgres should probably be on the same level as Redis if we're going to have priority ordering?)
I would have thought that Postgres being up first might avoid some noisy errors in Synapse's logs.

Supervisor by default will check that a process is up for 1 second before considering it 'up' (see startsecs). Hence starting Postgres first is probably good enough for the intention of avoiding noisy connection errors.

I'm not sure, but if we give everything the same priority (or remove the option to use the 999 default), I imagine everything will start and stop concurrently?1 What would you prefer?

Is it just synapse that is slow? I could be persuaded that SIGKILLing it might be good. Think I'd make it a separate PR though.

I couldn't remember, so I tried it again. This is the timeline of stopping:

2022-04-27 12:21:44,105 WARN received SIGTERM indicating exit request
2022-04-27 12:21:44,106 INFO waiting for redis, synapse_main, nginx, synapse_appservice1, synapse_background_worker1, synapse_event_creator1, synapse_event_persister1, synapse_event_persister2, synapse_federation_inbound1, synapse_federation_reader1, synapse_federation_sender1, synapse_frontend_proxy1, synapse_media_repository1, synapse_pusher1, synapse_synchrotron1, synapse_user_dir1, caddy, postgres to die
2022-04-27 12:21:44,219 INFO stopped: postgres (exit status 0)
2022-04-27 12:21:45,723 INFO stopped: caddy (exit status 0)
2022-04-27 12:21:45,776 INFO stopped: synapse_user_dir1 (exit status 0)
2022-04-27 12:21:45,799 INFO stopped: synapse_synchrotron1 (exit status 0)
2022-04-27 12:21:45,838 INFO stopped: synapse_pusher1 (exit status 0)
2022-04-27 12:21:45,875 INFO stopped: synapse_media_repository1 (exit status 0)
2022-04-27 12:21:45,916 INFO stopped: synapse_frontend_proxy1 (exit status 0)
2022-04-27 12:21:45,961 INFO stopped: synapse_federation_sender1 (exit status 0)
2022-04-27 12:21:46,006 INFO stopped: synapse_federation_reader1 (exit status 0)
2022-04-27 12:21:46,035 INFO stopped: synapse_federation_inbound1 (exit status 0)
2022-04-27 12:21:46,099 INFO stopped: synapse_event_persister2 (exit status 0)
2022-04-27 12:21:46,126 INFO stopped: synapse_event_persister1 (exit status 0)
2022-04-27 12:21:46,154 INFO stopped: synapse_event_creator1 (exit status 0)
2022-04-27 12:21:46,176 INFO stopped: synapse_background_worker1 (exit status 0)
2022-04-27 12:21:46,207 INFO stopped: synapse_appservice1 (exit status 0)
2022-04-27 12:21:46,210 INFO stopped: nginx (exit status 0)
2022-04-27 12:21:46,237 INFO stopped: synapse_main (exit status 0)
2022-04-27 12:21:46,293 INFO stopped: redis (exit status 0)

It seems faster than I was thinking, so maybe it's not a problem. (That's 2.1 seconds from stop signal to stopped.)
SIGKILLing all the Synapses would just mean we don't need to wait a short while for each of them to shut down.
(It'd also be interesting to know why there's both a Caddy and an nginx in there...)

Footnotes

  1. I'm not sure, actually. Shutdown seems to be sequential even amongst Synapse workers which have the same priority.

reivilibre and others added 3 commits April 27, 2022 13:59
Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
@reivilibre reivilibre requested a review from richvdh April 27, 2022 13:02
Comment on lines 4 to 5
# Lower priority number = starts first
priority=100
Copy link
Member

Choose a reason for hiding this comment

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

following up on #12480 (comment):

Do we actually need postgres to be a higher prority than synapse? It's not like there's any guarantee that doing so will mean that postgres is ready before synapse starts.

No, though Synapse's configuration already defined it at priority 500 so it seemed like this was the intention.

I'm not sure the priority was particularly carefully chosen, tbh. (ftr, this bit came from #9162).

(I just realised: The main Synapse process' priority is actually defined as 10; Redis' is 1. Postgres should probably be on the same level as Redis if we're going to have priority ordering?)

If we're going to have priority ordering, then yes it ought to be lower than Synapse.

I would have thought that Postgres being up first might avoid some noisy errors in Synapse's logs.

If it actually manages to start up in 1 second, then yes maybe. TBH though I would optimise for fastest runtime rather than lack of noise in the logs.

Copy link
Member

Choose a reason for hiding this comment

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

let's set this to be the same as Redis for now, and get this PR merged.

Copy link
Member

Choose a reason for hiding this comment

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

oh you're way ahead of me

@richvdh
Copy link
Member

richvdh commented Apr 27, 2022

Re SIGKILL:

It seems faster than I was thinking, so maybe it's not a problem. (That's 2.1 seconds from stop signal to stopped.)

In this case it looks like it's stopping postgres before synapse stops? Had you already changed the priorities? I can imagine that stopping postgres will encourage synapse to stop quickly. (I can also imagine the opposite...)

Let's leave this for now, either way.

@richvdh
Copy link
Member

richvdh commented Apr 27, 2022

(It'd also be interesting to know why there's both a Caddy and an nginx in there...)

This was added in matrix-org/complement#62. My understanding is that the basic synapse-workers image uses an nginx to route between the workers. The Complement wrapper adds caddy to do the SSL termination (in particular, generating a TLS cert for the test server). Personally, I'd have used openssl commandline to sort out the certs instead, but caddy does the job.

Copy link
Member

@richvdh richvdh left a comment

Choose a reason for hiding this comment

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

lgtm!

@reivilibre
Copy link
Contributor Author

In this case it looks like it's stopping postgres before synapse stops? Had you already changed the priorities?

This was taken from Postgres not having an explicit priority (so priority 999), in which case it starts after Synapse and stops before it.

With priority = 1 (same as Redis):

$ COMPLEMENT_DEBUG=1 WORKERS=1 COMPLEMENT_ALWAYS_PRINT_SERVER_LOGS=1 COMPLEMENT_DIR=`pwd`/../complement ./scripts-dev/complement.sh -run TestInboundFederationKeys 2>&1 | tee /tmp/comlog
... (Use hacked complement that has a long sleep before actually stopping the container. Wait for it to say complement is running.)
$ docker stop -t 500 complement_fed.alice.hs1
$ docker logs complement_fed.alice.hs1 2>&1 | grep -E 'WARN rece|INFO stop|INFO wait'
2022-04-27 13:15:27,058 WARN received SIGTERM indicating exit request
2022-04-27 13:15:27,058 INFO waiting for postgres, redis, synapse_main, nginx, synapse_appservice1, synapse_background_worker1, synapse_event_creator1, synapse_event_persister1, synapse_event_persister2, synapse_federation_inbound1, synapse_federation_reader1, synapse_federation_sender1, synapse_frontend_proxy1, synapse_media_repository1, synapse_pusher1, synapse_synchrotron1, synapse_user_dir1, caddy to die
2022-04-27 13:15:28,561 INFO stopped: caddy (exit status 0)
2022-04-27 13:15:28,584 INFO stopped: synapse_user_dir1 (exit status 0)
2022-04-27 13:15:28,605 INFO stopped: synapse_synchrotron1 (exit status 0)
2022-04-27 13:15:28,627 INFO stopped: synapse_pusher1 (exit status 0)
2022-04-27 13:15:28,650 INFO stopped: synapse_media_repository1 (exit status 0)
2022-04-27 13:15:28,671 INFO stopped: synapse_frontend_proxy1 (exit status 0)
2022-04-27 13:15:28,694 INFO stopped: synapse_federation_sender1 (exit status 0)
2022-04-27 13:15:28,715 INFO stopped: synapse_federation_reader1 (exit status 0)
2022-04-27 13:15:28,738 INFO stopped: synapse_federation_inbound1 (exit status 0)
2022-04-27 13:15:28,762 INFO stopped: synapse_event_persister2 (exit status 0)
2022-04-27 13:15:28,783 INFO stopped: synapse_event_persister1 (exit status 0)
2022-04-27 13:15:28,805 INFO stopped: synapse_event_creator1 (exit status 0)
2022-04-27 13:15:28,828 INFO stopped: synapse_background_worker1 (exit status 0)
2022-04-27 13:15:28,850 INFO stopped: synapse_appservice1 (exit status 0)
2022-04-27 13:15:28,853 INFO stopped: nginx (exit status 0)
2022-04-27 13:15:28,873 INFO stopped: synapse_main (exit status 0)
2022-04-27 13:15:28,916 INFO stopped: redis (exit status 0)
2022-04-27 13:15:29,004 INFO stopped: postgres (exit status 0)

2 sec, so no likely difference to the other way around. I'll go with this for now since it makes most sense.

I can imagine that stopping postgres will encourage synapse to stop quickly. (I can also imagine the opposite...)

Good point.

@reivilibre
Copy link
Contributor Author

The tests still fail:

--- FAIL: TestIsDirectFlagFederation (42.08s)
--- FAIL: TestEventAuth (19.81s)
--- FAIL: TestOutboundFederationProfile (22.62s)
    --- FAIL: TestOutboundFederationProfile/Outbound_federation_can_query_profile_data (10.02s)
--- FAIL: TestInboundFederationRejectsEventsWithRejectedAuthEvents (18.20s)
--- FAIL: TestGetMissingEventsGapFilling (20.82s)
--- FAIL: TestOutboundFederationIgnoresMissingEventWithBadJSONForRoomVersion6 (20.45s)
--- FAIL: TestFederationRejectInvite (65.22s)
--- FAIL: TestJoinViaRoomIDAndServerName (76.13s)
--- FAIL: TestJoinFederatedRoomWithUnverifiableEvents (49.18s)
    --- FAIL: TestJoinFederatedRoomWithUnverifiableEvents//send_join_response_missing_signatures_shouldn't_block_room_join (10.02s)
    --- FAIL: TestJoinFederatedRoomWithUnverifiableEvents//send_join_response_with_bad_signatures_shouldn't_block_room_join (10.01s)
    --- FAIL: TestJoinFederatedRoomWithUnverifiableEvents//send_join_response_with_unobtainable_keys_shouldn't_block_room_join (10.01s)
    --- FAIL: TestJoinFederatedRoomWithUnverifiableEvents//send_join_response_with_state_with_unverifiable_auth_events_shouldn't_block_room_join (10.01s)
--- FAIL: TestBannedUserCannotSendJoin (21.32s)
--- FAIL: TestCannotSendNonJoinViaSendJoinV1 (20.88s)
--- FAIL: TestCannotSendNonJoinViaSendJoinV2 (18.80s)
--- FAIL: TestCannotSendNonLeaveViaSendLeaveV1 (20.09s)
--- FAIL: TestCannotSendNonLeaveViaSendLeaveV2 (20.14s)
--- FAIL: TestSendJoinPartialStateResponse (19.84s)
--- FAIL: TestOutboundFederationSend (17.56s)
--- FAIL: TestUnrejectRejectedEvents (26.88s)
--- FAIL: TestKnocking (39.72s)
FAIL    github.com/matrix-org/complement/tests  602.251s
--- FAIL: TestCanRegisterAdmin (10.14s)
--- FAIL: TestServerNotices (6.49s)
--- FAIL: TestRegistration (8.52s)
    --- FAIL: TestRegistration/parallel (0.34s)
        --- FAIL: TestRegistration/parallel/POST_/_synapse/admin/v1/register_admin_with_shared_secret (0.01s)
        --- FAIL: TestRegistration/parallel/POST_/_synapse/admin/v1/register_with_shared_secret (0.01s)
        --- FAIL: TestRegistration/parallel/POST_/_synapse/admin/v1/register_with_shared_secret_disallows_symbols (0.01s)
        --- FAIL: TestRegistration/parallel/POST_/_synapse/admin/v1/register_with_shared_secret_downcases_capitals (0.01s)
--- FAIL: TestRoomImageRoundtrip (6.52s)
FAIL
FAIL    github.com/matrix-org/complement/tests/csapi    501.971s
FAIL

so there looks to be more work to do in further PRs.

@reivilibre reivilibre merged commit d743b25 into develop Apr 27, 2022
@reivilibre reivilibre deleted the rei/compl_supervise branch April 27, 2022 13:39
DMRobertson pushed a commit that referenced this pull request May 10, 2022
Synapse 1.59.0rc1 (2022-05-10)
==============================

This release makes several changes that server administrators should be aware of:

- Device name lookup over federation is now disabled by default. ([\#12616](#12616))
- The `synapse.app.appservice` and `synapse.app.user_dir` worker application types are now deprecated. ([\#12452](#12452), [\#12654](#12654))

See [the upgrade notes](https://github.com/matrix-org/synapse/blob/develop/docs/upgrade.md#upgrading-to-v1590) for more details.

Additionally, this release removes the non-standard `m.login.jwt` login type from Synapse. It can be replaced with `org.matrix.login.jwt` for identical behaviour. This is only used if `jwt_config.enabled` is set to `true` in the configuration. ([\#12597](#12597))

Features
--------

- Support [MSC3266](matrix-org/matrix-spec-proposals#3266) room summaries over federation. ([\#11507](#11507))
- Implement [changes](matrix-org/matrix-spec-proposals@4a77139) to [MSC2285 (hidden read receipts)](matrix-org/matrix-spec-proposals#2285). Contributed by @SimonBrandner. ([\#12168](#12168), [\#12635](#12635), [\#12636](#12636), [\#12670](#12670))
- Extend the [module API](https://github.com/matrix-org/synapse/blob/release-v1.59/synapse/module_api/__init__.py) to allow modules to change actions for existing push rules of local users. ([\#12406](#12406))
- Add the `notify_appservices_from_worker` configuration option (superseding `notify_appservices`) to allow a generic worker to be designated as the worker to send traffic to Application Services. ([\#12452](#12452))
- Add the `update_user_directory_from_worker` configuration option (superseding `update_user_directory`) to allow a generic worker to be designated as the worker to update the user directory. ([\#12654](#12654))
- Add new `enable_registration_token_3pid_bypass` configuration option to allow registrations via token as an alternative to verifying a 3pid. ([\#12526](#12526))
- Implement [MSC3786](matrix-org/matrix-spec-proposals#3786): Add a default push rule to ignore `m.room.server_acl` events. ([\#12601](#12601))
- Add new `mau_appservice_trial_days` configuration option to specify a different trial period for users registered via an appservice. ([\#12619](#12619))

Bugfixes
--------

- Fix a bug introduced in Synapse 1.48.0 where the latest thread reply provided failed to include the proper bundled aggregations. ([\#12273](#12273))
- Fix a bug introduced in Synapse 1.22.0 where attempting to send a large amount of read receipts to an application service all at once would result in duplicate content and abnormally high memory usage. Contributed by Brad & Nick @ Beeper. ([\#12544](#12544))
- Fix a bug introduced in Synapse 1.57.0 which could cause `Failed to calculate hosts in room` errors to be logged for outbound federation. ([\#12570](#12570))
- Fix a long-standing bug where status codes would almost always get logged as `200!`, irrespective of the actual status code, when clients disconnect before a request has finished processing. ([\#12580](#12580))
- Fix race when persisting an event and deleting a room that could lead to outbound federation breaking. ([\#12594](#12594))
- Fix a bug introduced in Synapse 1.53.0 where bundled aggregations for annotations/edits were incorrectly calculated. ([\#12633](#12633))
- Fix a long-standing bug where rooms containing power levels with string values could not be upgraded. ([\#12657](#12657))
- Prevent memory leak from reoccurring when presence is disabled. ([\#12656](#12656))

Updates to the Docker image
---------------------------

- Explicitly opt-in to using [BuildKit-specific features](https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/syntax.md) in the Dockerfile. This fixes issues with building images in some GitLab CI environments. ([\#12541](#12541))
- Update the "Build docker images" GitHub Actions workflow to use `docker/metadata-action` to generate docker image tags, instead of a custom shell script. Contributed by @henryclw. ([\#12573](#12573))

Improved Documentation
----------------------

- Update SQL statements and replace use of old table `user_stats_historical` in docs for Synapse Admins. ([\#12536](#12536))
- Add missing linebreak to `pipx` install instructions. ([\#12579](#12579))
- Add information about the TCP replication module to docs. ([\#12621](#12621))
- Fixes to the formatting of `README.rst`. ([\#12627](#12627))
- Fix docs on how to run specific Complement tests using the `complement.sh` test runner. ([\#12664](#12664))

Deprecations and Removals
-------------------------

- Remove unstable identifiers from [MSC3069](matrix-org/matrix-spec-proposals#3069). ([\#12596](#12596))
- Remove the unspecified `m.login.jwt` login type and the unstable `uk.half-shot.msc2778.login.application_service` from
  [MSC2778](matrix-org/matrix-spec-proposals#2778). ([\#12597](#12597))
- Synapse now requires at least Python 3.7.1 (up from 3.7.0), for compatibility with the latest Twisted trunk. ([\#12613](#12613))

Internal Changes
----------------

- Use supervisord to supervise Postgres and Caddy in the Complement image to reduce restart time. ([\#12480](#12480))
- Immediately retry any requests that have backed off when a server comes back online. ([\#12500](#12500))
- Use `make_awaitable` instead of `defer.succeed` for return values of mocks in tests. ([\#12505](#12505))
- Consistently check if an object is a `frozendict`. ([\#12564](#12564))
- Protect module callbacks with read semantics against cancellation. ([\#12568](#12568))
- Improve comments and error messages around access tokens. ([\#12577](#12577))
- Improve docstrings for the receipts store. ([\#12581](#12581))
- Use constants for read-receipts in tests. ([\#12582](#12582))
- Log status code of cancelled requests as 499 and avoid logging stack traces for them. ([\#12587](#12587), [\#12663](#12663))
- Remove special-case for `twisted` logger from default log config. ([\#12589](#12589))
- Use `getClientAddress` instead of the deprecated `getClientIP`. ([\#12599](#12599))
- Add link to documentation in Grafana Dashboard. ([\#12602](#12602))
- Reduce log spam when running multiple event persisters. ([\#12610](#12610))
- Add extra debug logging to federation sender. ([\#12614](#12614))
- Prevent remote homeservers from requesting local user device names by default. ([\#12616](#12616))
- Add a consistency check on events which we read from the database. ([\#12620](#12620))
- Remove use of the `constantly` library and switch to enums for `EventRedactBehaviour`. Contributed by @andrewdoh. ([\#12624](#12624))
- Remove unused code related to receipts. ([\#12632](#12632))
- Minor improvements to the scripts for running Synapse in worker mode under Complement. ([\#12637](#12637))
- Move `pympler` back in to the `all` extras. ([\#12652](#12652))
- Fix spelling of `M_UNRECOGNIZED` in comments. ([\#12665](#12665))
- Release script: confirm the commit to be tagged before tagging. ([\#12556](#12556))
- Fix a typo in the announcement text generated by the Synapse release development script. ([\#12612](#12612))

- Fix scripts-dev to pass typechecking. ([\#12356](#12356))
- Add some type hints to datastore. ([\#12485](#12485))
- Remove unused `# type: ignore`s. ([\#12531](#12531))
- Allow unused `# type: ignore` comments in bleeding edge CI jobs. ([\#12576](#12576))
- Remove redundant lines of config from `mypy.ini`. ([\#12608](#12608))
- Update to mypy 0.950. ([\#12650](#12650))
- Use `Concatenate` to better annotate `_do_execute`. ([\#12666](#12666))
- Use `ParamSpec` to refine type hints. ([\#12667](#12667))
- Fix mypy against latest pillow stubs. ([\#12671](#12671))
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants