0

Below is the function called for scheduling a job on server start.

But somehow the scheduled job is getting called again and again, and this is causing too many calls to that respective function.

Either this is happening because of multiple function calls or something else? Suggestions please.

def redis_schedule():
    with current_app.app_context():
        redis_url = current_app.config["REDIS_URL"]
        with Connection(redis.from_url(redis_url)):
            q = Queue("notification")
            from ..tasks.notification import send_notifs
            task = q.enqueue_in(timedelta(minutes=5), send_notifs)
zion
  • 391
  • 5
  • 22

2 Answers2

0

Refer - https://python-rq.org/docs/job_registries/

Needed to read scheduled_job_registry and retrieve jobids. Currently below logic works for me as I only have a single scheduled_job. But in case of multiple jobs, I will need to loop these jobids to find the right job exists or not.

def redis_schedule():
    with current_app.app_context():
        redis_url = current_app.config["REDIS_URL"]
        with Connection(redis.from_url(redis_url)):
            q = Queue("notification")

            if len(q.scheduled_job_registry.get_job_ids()) == 0:
                from ..tasks.notification import send_notifs
                task = q.enqueue_in(timedelta(seconds=30), send_notifs)
zion
  • 391
  • 5
  • 22
0

Here’s a quite clean alternative to inspecting all jobs:

You may assign a manual ID to a job, e.g. by passing q.enqueue(job_id="send-mail-notifications").

Below is a snippet that checks if a job with a given ID already exists; it also cleans up any old jobs with the same ID to avoid false positives.

    def job_exists(job_id, cleanup_stale=True):
        try:
            job = Job.fetch(id=job_id, connection=Redis())
        except NoSuchJobError:
            return False

        status = job.get_status()

        if status in {JobStatus.QUEUED, JobStatus.SCHEDULED}:
            # Job exists and will be run.
            return True

        # Delete old jobs that have been completed, cancelled, stopped etc.
        job.delete()

        return False

It makes sense to run tasks with a delay, e.g. five seconds, to make sure that fast running jobs aren’t enqueued in rapid succession.

Let me know if it helps.

Julian
  • 33
  • 4