One possible way is to store the tasks in the database and add remove tasks dynamically. You can use database backed celery beat scheduler for the same. Refer https://django-celery-beat.readthedocs.io/en/latest/. PeriodicTask database store the periodic tasks. You can manipulate the periodic task by using database commands (Django ORM).
This is how I handled the dynamic tasks (Create and stop tasks dynamically).
from django_celery_beat.models import PeriodicTask, IntervalSchedule, CrontabSchedule
chon_schedule = CrontabSchedule.objects.create(minute='40', hour='08', day_of_week='*', day_of_month='*', month_of_year='*') # To create a cron schedule.
schedule = IntervalSchedule.objects.create(every=10, period=IntervalSchedule.SECONDS) # To create a schedule to run everu 10 min.
PeriodicTask.objects.create(crontab=chon_schedule, name='name_to_identify_task',task='name_of_task') # It creates a entry in the database describing that periodic task (With cron schedule).
task = PeriodicTask.objects.create(interval=schedule, name='run for every 10 min', task='for_each_ten_min', ) # It creates a periodic task with interval schedule
Whenever you update a PeriodicTask a counter in this table is also
incremented, which tells the celery beat service to reload the
schedule from the database.
So you don't need to restart the or kill the beat.
If you want to stop a task when particular criteria met then
periodic_task = PeriodicTask.objects.get(name='run for every 10 min')
periodic_task.enabled = False
periodic_task.save()
When enabled is False then the periodic task becomes idle. You can again make it active by making enable = True
.
If you no longer needs the task then you can simply delete the entry.