zulip/scripts
Alex Vandiver c5200e8b05 deliver_scheduled_emails: Use a queue, instead of infinite retries.
`deliver_scheduled_emails` tries to deliver the email synchronously,
and if it fails, it retries after 10 seconds.  Since it does not track
retries, and always tries the earliest-scheduled-but-due message
first, the worker will not make forward progress if there is a
persistent failure with that message, and will retry indefinitely.
This can result in excessive network or email delivery charges from
the remote SMTP server.

Switch to delivering emails via a new queue worker.  The
`deliver_scheduled_emails` job now serves only to pull deferred jobs
out of the table once they are due, insert them into RabbitMQ, and
then delete them.  This limits the potential for head-of-queue
failures to failures inserting into RabbitMQ, which is more reasonable
than failures speaking to a complex external system we do not control.
Retries and any connections to the SMTP server are left to the
RabbitMQ consumer.

We build a new RabbitMQ queue, rather than use the existing
`email_senders` queue, because that queue is expected to be reasonably
low-latency, for things like missed message notifications.  The
`send_future_email` codepath which inserts into ScheduledEmails is
also (ab)used to digest emails, which are extremely bursty in their
frequency -- and a large burst could significantly delay emails behind
it in the queue.

The new queue is explicitly only for messages which were not initiated
by user actions (e.g., invitation reminders, digests, new account
follow-ups) which are thus not latency-sensitive.

Fixes: #32463.
2025-03-04 16:09:25 -08:00
..
lib deliver_scheduled_emails: Use a queue, instead of infinite retries. 2025-03-04 16:09:25 -08:00
nagios ruff: Fix PLC0206 Extracting value from dictionary without calling .items(). 2024-12-21 21:06:53 -08:00
setup kandra: Update Teleport version. 2025-02-21 10:16:33 -08:00
__init__.py Factor out venv-creating code from provision.py. 2016-06-21 11:25:41 -07:00
get-django-setting python: Normalize quotes with Black. 2021-02-12 13:11:19 -08:00
log-search requirements: Upgrade Python requirements. 2024-11-19 11:09:34 -08:00
purge-old-deployments ruff: Partially reformat Python with Ruff 0.9 (2025 style). 2025-01-14 09:42:16 -08:00
README.md docs: Apply bullet style changes from Prettier. 2021-09-08 12:06:24 -07:00
refresh-sharding-and-restart sharding: Configure Tornado sharding with nginx map. 2022-09-15 16:07:50 -07:00
reload-clients reload-clients: Log how many reload events were actually sent. 2024-03-01 09:31:20 -08:00
restart-server restart-server: Add a --only-django for rolling Django restarts. 2024-10-08 12:53:21 -07:00
start-server scripts: Add a start-server as well. 2021-04-21 10:24:08 -07:00
stop-server upload: Use tusd for resumable, larger uploads. 2024-09-19 11:37:29 -07:00
upgrade-zulip upgrade: Modify upgrade scripts to handle failure. 2021-06-23 08:42:20 -07:00
upgrade-zulip-from-git upgrade: Modify upgrade scripts to handle failure. 2021-06-23 08:42:20 -07:00
zulip-puppet-apply ruff: Fix SIM115 Use a context manager for opening files. 2024-10-20 18:16:27 -07:00

This directory contains scripts that:

  • Generally do not require access to Django or the database (those are "management commands"), and thus are suitable to run operationally.

  • Are useful for managing a production deployment of Zulip (many are also used in a Zulip development environment, though development-only scripts live in tools/).

For more details, see https://zulip.readthedocs.io/en/latest/overview/directory-structure.html.