vintasoftware / django-celerybeat-status

A library that integrates with django admin and shows in a simple GUI when your periodic are going to run next.
https://pypi.org/project/django-celerybeat-status
MIT License
103 stars 11 forks source link

`get_periodic_tasks_info` ignores beat scheduler config #18

Open tarasmatsyk opened 5 years ago

tarasmatsyk commented 5 years ago

Hi guys,

Thanks for the awesome package!

I was trying to configure a celery beat schedule view however could not make it work with customer scheduler like django_celery_beat.schedulers:DatabaseScheduler. The reason for it, from what I understand, is that configuration is ignored if no scheduler_cls passed here: https://github.com/vintasoftware/django-celerybeat-status/blob/master/celerybeat_status/helpers.py#L9

Not sure if this is related to celerybeat-status as I might be missing something

Here are a few screenshots from debug session

screen shot 2018-12-17 at 11 12 03 am screen shot 2018-12-17 at 11 12 27 am
amangpt777 commented 4 years ago

Hi @tarasmatsyk ,

Were you able to resolve this? I am facing exact same issue with DatabaseScheduler.

Following worked though:

from django_celery_beat.schedulers import DatabaseScheduler schedule = DatabaseScheduler(current_app).all_as_schedule()

https://django-celery-beat.readthedocs.io/en/stable/reference/django-celery-beat.schedulers.html

ZhaoQi99 commented 4 months ago

Hi @tarasmatsyk ,

Were you able to resolve this? I am facing exact same issue with DatabaseScheduler.

Following worked though:

from django_celery_beat.schedulers import DatabaseScheduler schedule = DatabaseScheduler(current_app).all_as_schedule()

https://django-celery-beat.readthedocs.io/en/stable/reference/django-celery-beat.schedulers.html

I tried with the following code, but it still doesn't work.

schedule = self.Service(
            app=current_app,
            max_interval=self.max_interval,
            scheduler_cls=self.scheduler_cls,
            schedule_filename=self.schedule,
        ).scheduler.get_schedule()

And I noticed that PersistentScheduler's get_schedule method is overrided. Maybe because of this? https://github.com/celery/celery/blob/4c3e5a1a25ee7d67cc50d9db560e0102e0b06c23/celery/beat.py#L590-L591

Finally, I solved the issue with the following code.

from celery.utils.imports import symbol_by_name

if symbol_by_name(self.scheduler_cls) == PersistentScheduler:
    schedule = self.Service(
        app=self.app,
        max_interval=self.max_interval,
        scheduler_cls=self.scheduler_cls,
        schedule_filename=self.schedule,
    ).scheduler.get_schedule()
else:
    from django_celery_beat.schedulers import DatabaseScheduler

    schedule = DatabaseScheduler(self.app,lazy=True).all_as_schedule()

Make sure to pass the lazy=True, otherwise it will keep updating PeriodicTasks.last_update when init DatabaseScheduler. So PeriodicTask which last_run_at is None and scheduler is IntervalSchedule will never be sent.