From 590fa9edc056d6f3b00000bc40fb46a3036ab187 Mon Sep 17 00:00:00 2001 From: Sean Morley Date: Wed, 21 Aug 2024 09:48:47 -0400 Subject: [PATCH] Auto schedule Django APScheduler --- backend/Dockerfile | 14 +--------- backend/server/adventures/apps.py | 11 +++++--- backend/server/adventures/scheduler.py | 36 ++++++++++++++++++++++++++ backend/server/main/settings.py | 36 +++++++++++++++++++++++++- backend/server/requirements.txt | 3 ++- 5 files changed, 82 insertions(+), 18 deletions(-) create mode 100644 backend/server/adventures/scheduler.py diff --git a/backend/Dockerfile b/backend/Dockerfile index faa018a..eee8966 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -13,7 +13,7 @@ WORKDIR /code # Install system dependencies RUN apt-get update \ - && apt-get install -y git postgresql-client cron \ + && apt-get install -y git postgresql-client \ && apt-get clean # Install Python dependencies @@ -27,18 +27,6 @@ COPY ./server /code/ # Collect static files RUN python3 manage.py collectstatic --noinput --verbosity 2 -# Setup cron to run python3 manage.py worldtravel-seed every day at 00:00 -RUN echo "0 0 * * * python3 /code/manage.py worldtravel-seed --force >> /var/log/cron.log 2>&1" > /etc/cron.d/worldtravel-seed - -# Give execution rights on the cron job -RUN chmod 0644 /etc/cron.d/worldtravel-seed - -# Apply cron job -RUN crontab /etc/cron.d/worldtravel-seed - -# Ensure cron is started in the foreground when the container starts -CMD ["cron", "-f"] - # Set the entrypoint script COPY ./entrypoint.sh /code/entrypoint.sh RUN chmod +x /code/entrypoint.sh diff --git a/backend/server/adventures/apps.py b/backend/server/adventures/apps.py index 67a6b8c..393e5ad 100644 --- a/backend/server/adventures/apps.py +++ b/backend/server/adventures/apps.py @@ -1,6 +1,11 @@ from django.apps import AppConfig - +from django.conf import settings class AdventuresConfig(AppConfig): - default_auto_field = "django.db.models.BigAutoField" - name = "adventures" + default_auto_field = 'django.db.models.BigAutoField' + name = 'adventures' + + def ready(self): + if settings.SCHEDULER_AUTOSTART: + from .scheduler import start_scheduler + start_scheduler() \ No newline at end of file diff --git a/backend/server/adventures/scheduler.py b/backend/server/adventures/scheduler.py new file mode 100644 index 0000000..fc087a4 --- /dev/null +++ b/backend/server/adventures/scheduler.py @@ -0,0 +1,36 @@ +# scheduler.py + +import logging +from apscheduler.schedulers.background import BackgroundScheduler +from django_apscheduler.jobstores import DjangoJobStore +from django_apscheduler import util +from django.conf import settings +from django.core.management import call_command + +logger = logging.getLogger(__name__) + +def run_worldtravel_seed(): + logger.info("Starting worldtravel-seed job") + try: + call_command('worldtravel-seed', '--force') + logger.info("worldtravel-seed job completed successfully") + except Exception as e: + logger.error(f"Error in worldtravel-seed job: {str(e)}") + +@util.close_old_connections +def start_scheduler(): + scheduler = BackgroundScheduler(timezone=settings.TIME_ZONE) + scheduler.add_jobstore(DjangoJobStore(), "default") + + scheduler.add_job( + run_worldtravel_seed, + trigger="interval", + hours=24, + id="worldtravel_seed", + max_instances=1, + replace_existing=True, + ) + + logger.info("Starting scheduler...") + scheduler.start() + return scheduler \ No newline at end of file diff --git a/backend/server/main/settings.py b/backend/server/main/settings.py index 71c1525..6abaa35 100644 --- a/backend/server/main/settings.py +++ b/backend/server/main/settings.py @@ -58,6 +58,7 @@ INSTALLED_APPS = ( 'adventures', 'worldtravel', 'users', + 'django_apscheduler', ) @@ -71,12 +72,18 @@ MIDDLEWARE = ( 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'allauth.account.middleware.AccountMiddleware', - ) # disable verifications for new users ACCOUNT_EMAIL_VERIFICATION = 'none' +CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + } +} + + # For backwards compatibility for Django 1.8 MIDDLEWARE_CLASSES = MIDDLEWARE @@ -230,3 +237,30 @@ from os import getenv CSRF_TRUSTED_ORIGINS = [origin.strip() for origin in getenv('CSRF_TRUSTED_ORIGINS', 'http://localhost').split(',') if origin.strip()] DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' + +LOGGING = { + 'version': 1, + 'disable_existing_loggers': False, + 'handlers': { + 'console': { + 'class': 'logging.StreamHandler', + }, + 'file': { + 'class': 'logging.FileHandler', + 'filename': 'scheduler.log', + }, + }, + 'root': { + 'handlers': ['console', 'file'], + 'level': 'INFO', + }, + 'loggers': { + 'django': { + 'handlers': ['console', 'file'], + 'level': 'INFO', + 'propagate': False, + }, + }, +} + +SCHEDULER_AUTOSTART = True \ No newline at end of file diff --git a/backend/server/requirements.txt b/backend/server/requirements.txt index 2bd5846..179ef7e 100644 --- a/backend/server/requirements.txt +++ b/backend/server/requirements.txt @@ -10,4 +10,5 @@ python-dotenv psycopg2-binary Pillow whitenoise -django-resized \ No newline at end of file +django-resized +django-apscheduler \ No newline at end of file