rq-scheduler icon indicating copy to clipboard operation
rq-scheduler copied to clipboard

Testing: how do I force the scheduler to empty out it's queue?

Open jmmills opened this issue 9 years ago • 9 comments

Use case: Testing a system where objects are expired from a database at scheduled times, how does one force the scheduler to run jobs?

Is it as simple as creating an RQ SimpleWorker attached to the "scheduled queue", or is there a better way?

jmmills avatar Jul 21 '15 01:07 jmmills

I solved this myself, one uses mock and patches the get_jobs_to_queue method.

E.g,

def return_all_jobs(scheduler):
    return scheduler.get_jobs()

@mock.patch('rq_scheduler.scheduler.Scheduler.get_jobs_to_queue', return_all_jobs)
def test_something_scheduled():
    # given that scheduler is an RQ scheduler
    # given that worker is a RQ SimpleWorker
    # scheduler.enqueue_in(...)

    scheduler.enqueue_jobs()
    worker.work(burst=True)

jmmills avatar Jul 21 '15 01:07 jmmills

I'm reopening this issue because I think we should have a scheduler.empty() method to do this easily.

selwin avatar Jul 21 '15 06:07 selwin

Hi @selwin,

what do you expect scheduler.empty() to do ? Just clear the queue, or execute the jobs then clear ?

mbodock avatar Aug 10 '15 17:08 mbodock

Running scheduler.empty() should just empty the scheduler, while running scheduler.empty(delete_jobs=True) should empty the scheduler and delete all jobs inside. Thanks :)

selwin avatar Aug 12 '15 01:08 selwin

so with empty it would look like something like (for testing):

worker = SimpleWorker()
scheduler.enqueue_in(...)
# some time later to test the results
scheduler.empty()
worker.work(burst=True)

However, in my case where I came across this, I have jobs scheduling new jobs... so this would be more like what I was doing:

while scheduler.empty():  # should return jobs that are now queued
    worker.work(burst=True)

jmmills avatar Aug 13 '15 22:08 jmmills

@jmmills there seems to be a miscommunication. What I think scheduler.empty should do is clearing the scheduler, not enqueueing all jobs in the scheduler. So it should be something like this:

scheduler.enqueue_in(...)
scheduler.count() # Returns 1
scheduler.empty()
scheduler.count() # Returns 0

selwin avatar Aug 14 '15 01:08 selwin

+1

jegesh avatar Dec 01 '16 09:12 jegesh

@selwin I know it's kind of late, but is this what you are looking for?

scheduled_jobs = scheduler.get_jobs()
for job in scheduled_jobs: 
    scheduler.cancel(job)

c-simpson avatar Oct 11 '17 17:10 c-simpson

@c-simpson scheduler.cancel just cancel scheduling job, but do not clear jobs already in queue.

BTW, I found the right way to empty queue:

  • When we create scheduler instance, we have set a queue name.
  • rq will use that queue name to create a Queue instance later, which support queue.empty already!

So the right way to empty queue is :

queue = Queue(the_same_queue_name_your_scheduler_using)
queue.empty()

linkdesu avatar Jun 29 '18 15:06 linkdesu