mirror of
https://github.com/suitenumerique/messages.git
synced 2026-08-29 03:09:37 +02:00
156 lines
4.8 KiB
Python
156 lines
4.8 KiB
Python
#!/usr/bin/env python
|
|
"""
|
|
Background task worker with sensible queue defaults.
|
|
|
|
Usage:
|
|
python worker.py # Process all queues with default priority
|
|
python worker.py --queues=inbound,default # Process only specific queues
|
|
python worker.py --exclude=reindex # Process all queues except reindex
|
|
python worker.py --concurrency=4 # Set worker concurrency
|
|
python worker.py --disable-scheduler # Disable the scheduler
|
|
|
|
Queue priority order (highest to lowest):
|
|
1. management - Admin/management tasks (migrations, cleanup)
|
|
2. inbound - Inbound email processing (time-sensitive)
|
|
3. outbound - Outbound email sending
|
|
4. default - General tasks
|
|
5. imports - File import processing (can be delayed)
|
|
6. reindex - Search indexing (lowest priority)
|
|
"""
|
|
|
|
import argparse
|
|
import logging
|
|
import os
|
|
import sys
|
|
|
|
# Setup Django before importing the task runner
|
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "messages.settings")
|
|
os.environ.setdefault("DJANGO_CONFIGURATION", "Development")
|
|
|
|
# Override $APP if set by the host (e.g. Scalingo), as Celery interprets it as the app module
|
|
os.environ.pop("APP", None)
|
|
|
|
from configurations.importer import install # pylint: disable=wrong-import-position
|
|
|
|
install(check_options=True)
|
|
|
|
from messages.celery_app import app # pylint: disable=wrong-import-position
|
|
|
|
# Queue definitions in priority order
|
|
ALL_QUEUES = ["management", "inbound", "outbound", "default", "imports", "reindex"]
|
|
DEFAULT_QUEUES = ALL_QUEUES # By default, process all queues
|
|
|
|
|
|
def get_default_concurrency():
|
|
"""Get default concurrency from environment variables."""
|
|
env_value = os.environ.get("WORKER_CONCURRENCY") or os.environ.get(
|
|
"CELERY_CONCURRENCY"
|
|
)
|
|
if env_value:
|
|
try:
|
|
return int(env_value)
|
|
except ValueError:
|
|
return None
|
|
return None
|
|
|
|
|
|
def parse_args():
|
|
"""Parse command-line arguments."""
|
|
parser = argparse.ArgumentParser(
|
|
description="Start a background task worker with sensible queue defaults.",
|
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
epilog=__doc__,
|
|
)
|
|
parser.add_argument(
|
|
"--queues",
|
|
"-Q",
|
|
type=str,
|
|
default=None,
|
|
help=f"Comma-separated list of queues to process. Default: {','.join(DEFAULT_QUEUES)}",
|
|
)
|
|
parser.add_argument(
|
|
"--exclude",
|
|
"-X",
|
|
type=str,
|
|
default=None,
|
|
help="Comma-separated list of queues to exclude from processing.",
|
|
)
|
|
parser.add_argument(
|
|
"--concurrency",
|
|
"-c",
|
|
type=int,
|
|
default=get_default_concurrency(),
|
|
help="Number of worker processes. Default: WORKER_CONCURRENCY env var or number of CPUs.",
|
|
)
|
|
parser.add_argument(
|
|
"--disable-scheduler",
|
|
action="store_true",
|
|
help="Disable the task scheduler (enabled by default).",
|
|
)
|
|
parser.add_argument(
|
|
"--loglevel",
|
|
"-l",
|
|
type=str,
|
|
default="INFO",
|
|
help="Logging level. Default: INFO",
|
|
)
|
|
return parser.parse_args()
|
|
|
|
|
|
def main():
|
|
"""Start the background task worker."""
|
|
logger = logging.getLogger(__name__)
|
|
args = parse_args()
|
|
|
|
# Determine which queues to process
|
|
if args.queues:
|
|
queues = [q.strip() for q in args.queues.split(",")]
|
|
# Validate queues
|
|
invalid = set(queues) - set(ALL_QUEUES)
|
|
if invalid:
|
|
sys.stderr.write(f"Error: Unknown queues: {', '.join(invalid)}\n")
|
|
sys.stderr.write(f"Valid queues are: {', '.join(ALL_QUEUES)}\n")
|
|
sys.exit(1)
|
|
else:
|
|
queues = DEFAULT_QUEUES.copy()
|
|
|
|
# Apply exclusions
|
|
if args.exclude:
|
|
exclude = [q.strip() for q in args.exclude.split(",")]
|
|
# Validate excluded queue names
|
|
invalid_exclude = set(exclude) - set(ALL_QUEUES)
|
|
if invalid_exclude:
|
|
sys.stderr.write(
|
|
f"Error: Unknown queues to exclude: {', '.join(invalid_exclude)}\n"
|
|
)
|
|
sys.stderr.write(f"Valid queues are: {', '.join(ALL_QUEUES)}\n")
|
|
sys.exit(1)
|
|
queues = [q for q in queues if q not in exclude]
|
|
|
|
if not queues:
|
|
sys.stderr.write("Error: No queues to process after exclusions.\n")
|
|
sys.exit(1)
|
|
|
|
# Build worker arguments
|
|
worker_args = [
|
|
"worker",
|
|
f"--queues={','.join(queues)}",
|
|
f"--loglevel={args.loglevel}",
|
|
]
|
|
|
|
if args.concurrency:
|
|
worker_args.append(f"--concurrency={args.concurrency}")
|
|
|
|
if not args.disable_scheduler:
|
|
worker_args.append("--beat")
|
|
|
|
# Always enable task events for monitoring
|
|
worker_args.append("--task-events")
|
|
|
|
logger.info("Starting worker with queues: %s", ", ".join(queues))
|
|
app.worker_main(argv=worker_args)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|