|
|
@ -5,6 +5,7 @@ from __future__ import (absolute_import, division, print_function,
|
|
|
|
from rq import get_failed_queue, Queue
|
|
|
|
from rq import get_failed_queue, Queue
|
|
|
|
from rq.exceptions import InvalidJobOperationError
|
|
|
|
from rq.exceptions import InvalidJobOperationError
|
|
|
|
from rq.job import Job, JobStatus
|
|
|
|
from rq.job import Job, JobStatus
|
|
|
|
|
|
|
|
from rq.registry import DeferredJobRegistry
|
|
|
|
from rq.worker import Worker
|
|
|
|
from rq.worker import Worker
|
|
|
|
|
|
|
|
|
|
|
|
from tests import RQTestCase
|
|
|
|
from tests import RQTestCase
|
|
|
@ -117,6 +118,7 @@ class TestQueue(RQTestCase):
|
|
|
|
# say_hello spec holds which queue this is sent to
|
|
|
|
# say_hello spec holds which queue this is sent to
|
|
|
|
job = q.enqueue(say_hello, 'Nick', foo='bar')
|
|
|
|
job = q.enqueue(say_hello, 'Nick', foo='bar')
|
|
|
|
job_id = job.id
|
|
|
|
job_id = job.id
|
|
|
|
|
|
|
|
self.assertEqual(job.origin, q.name)
|
|
|
|
|
|
|
|
|
|
|
|
# Inspect data inside Redis
|
|
|
|
# Inspect data inside Redis
|
|
|
|
q_key = 'rq:queue:default'
|
|
|
|
q_key = 'rq:queue:default'
|
|
|
@ -131,14 +133,12 @@ class TestQueue(RQTestCase):
|
|
|
|
job = Job.create(func=say_hello, args=('Nick',), kwargs=dict(foo='bar'))
|
|
|
|
job = Job.create(func=say_hello, args=('Nick',), kwargs=dict(foo='bar'))
|
|
|
|
|
|
|
|
|
|
|
|
# Preconditions
|
|
|
|
# Preconditions
|
|
|
|
self.assertIsNone(job.origin)
|
|
|
|
|
|
|
|
self.assertIsNone(job.enqueued_at)
|
|
|
|
self.assertIsNone(job.enqueued_at)
|
|
|
|
|
|
|
|
|
|
|
|
# Action
|
|
|
|
# Action
|
|
|
|
q.enqueue_job(job)
|
|
|
|
q.enqueue_job(job)
|
|
|
|
|
|
|
|
|
|
|
|
# Postconditions
|
|
|
|
# Postconditions
|
|
|
|
self.assertEquals(job.origin, q.name)
|
|
|
|
|
|
|
|
self.assertIsNotNone(job.enqueued_at)
|
|
|
|
self.assertIsNotNone(job.enqueued_at)
|
|
|
|
|
|
|
|
|
|
|
|
def test_pop_job_id(self):
|
|
|
|
def test_pop_job_id(self):
|
|
|
@ -320,30 +320,36 @@ class TestQueue(RQTestCase):
|
|
|
|
self.assertEquals(len(Queue.all()), 3)
|
|
|
|
self.assertEquals(len(Queue.all()), 3)
|
|
|
|
|
|
|
|
|
|
|
|
def test_enqueue_dependents(self):
|
|
|
|
def test_enqueue_dependents(self):
|
|
|
|
"""Enqueueing the dependent jobs pushes all jobs in the depends set to the queue."""
|
|
|
|
"""Enqueueing dependent jobs pushes all jobs in the depends set to the queue
|
|
|
|
|
|
|
|
and removes them from DeferredJobQueue."""
|
|
|
|
q = Queue()
|
|
|
|
q = Queue()
|
|
|
|
parent_job = Job.create(func=say_hello)
|
|
|
|
parent_job = Job.create(func=say_hello)
|
|
|
|
parent_job.save()
|
|
|
|
parent_job.save()
|
|
|
|
job_1 = Job.create(func=say_hello, depends_on=parent_job)
|
|
|
|
job_1 = q.enqueue(say_hello, depends_on=parent_job)
|
|
|
|
job_1.save()
|
|
|
|
job_2 = q.enqueue(say_hello, depends_on=parent_job)
|
|
|
|
job_1.register_dependency()
|
|
|
|
|
|
|
|
job_2 = Job.create(func=say_hello, depends_on=parent_job)
|
|
|
|
|
|
|
|
job_2.save()
|
|
|
|
|
|
|
|
job_2.register_dependency()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
registry = DeferredJobRegistry(q.name, connection=self.testconn)
|
|
|
|
|
|
|
|
self.assertEqual(
|
|
|
|
|
|
|
|
set(registry.get_job_ids()),
|
|
|
|
|
|
|
|
set([job_1.id, job_2.id])
|
|
|
|
|
|
|
|
)
|
|
|
|
# After dependents is enqueued, job_1 and job_2 should be in queue
|
|
|
|
# After dependents is enqueued, job_1 and job_2 should be in queue
|
|
|
|
self.assertEqual(q.job_ids, [])
|
|
|
|
self.assertEqual(q.job_ids, [])
|
|
|
|
q.enqueue_dependents(parent_job)
|
|
|
|
q.enqueue_dependents(parent_job)
|
|
|
|
self.assertEqual(set(q.job_ids), set([job_1.id, job_2.id]))
|
|
|
|
self.assertEqual(set(q.job_ids), set([job_2.id, job_1.id]))
|
|
|
|
self.assertFalse(self.testconn.exists(parent_job.dependents_key))
|
|
|
|
self.assertFalse(self.testconn.exists(parent_job.dependents_key))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# DeferredJobRegistry should also be empty
|
|
|
|
|
|
|
|
self.assertEqual(registry.get_job_ids(), [])
|
|
|
|
|
|
|
|
|
|
|
|
def test_enqueue_job_with_dependency(self):
|
|
|
|
def test_enqueue_job_with_dependency(self):
|
|
|
|
"""Jobs are enqueued only when their dependencies are finished."""
|
|
|
|
"""Jobs are enqueued only when their dependencies are finished."""
|
|
|
|
# Job with unfinished dependency is not immediately enqueued
|
|
|
|
# Job with unfinished dependency is not immediately enqueued
|
|
|
|
parent_job = Job.create(func=say_hello)
|
|
|
|
parent_job = Job.create(func=say_hello)
|
|
|
|
q = Queue()
|
|
|
|
q = Queue()
|
|
|
|
q.enqueue_call(say_hello, depends_on=parent_job)
|
|
|
|
job = q.enqueue_call(say_hello, depends_on=parent_job)
|
|
|
|
self.assertEqual(q.job_ids, [])
|
|
|
|
self.assertEqual(q.job_ids, [])
|
|
|
|
|
|
|
|
self.assertEqual(job.get_status(), JobStatus.DEFERRED)
|
|
|
|
|
|
|
|
|
|
|
|
# Jobs dependent on finished jobs are immediately enqueued
|
|
|
|
# Jobs dependent on finished jobs are immediately enqueued
|
|
|
|
parent_job.set_status(JobStatus.FINISHED)
|
|
|
|
parent_job.set_status(JobStatus.FINISHED)
|
|
|
@ -351,6 +357,7 @@ class TestQueue(RQTestCase):
|
|
|
|
job = q.enqueue_call(say_hello, depends_on=parent_job)
|
|
|
|
job = q.enqueue_call(say_hello, depends_on=parent_job)
|
|
|
|
self.assertEqual(q.job_ids, [job.id])
|
|
|
|
self.assertEqual(q.job_ids, [job.id])
|
|
|
|
self.assertEqual(job.timeout, Queue.DEFAULT_TIMEOUT)
|
|
|
|
self.assertEqual(job.timeout, Queue.DEFAULT_TIMEOUT)
|
|
|
|
|
|
|
|
self.assertEqual(job.get_status(), JobStatus.QUEUED)
|
|
|
|
|
|
|
|
|
|
|
|
def test_enqueue_job_with_dependency_by_id(self):
|
|
|
|
def test_enqueue_job_with_dependency_by_id(self):
|
|
|
|
"""Enqueueing jobs should work as expected by id as well as job-objects."""
|
|
|
|
"""Enqueueing jobs should work as expected by id as well as job-objects."""
|
|
|
@ -368,7 +375,7 @@ class TestQueue(RQTestCase):
|
|
|
|
self.assertEqual(job.timeout, Queue.DEFAULT_TIMEOUT)
|
|
|
|
self.assertEqual(job.timeout, Queue.DEFAULT_TIMEOUT)
|
|
|
|
|
|
|
|
|
|
|
|
def test_enqueue_job_with_dependency_and_timeout(self):
|
|
|
|
def test_enqueue_job_with_dependency_and_timeout(self):
|
|
|
|
"""Jobs still know their specified timeout after being scheduled as a dependency."""
|
|
|
|
"""Jobs remember their timeout when enqueued as a dependency."""
|
|
|
|
# Job with unfinished dependency is not immediately enqueued
|
|
|
|
# Job with unfinished dependency is not immediately enqueued
|
|
|
|
parent_job = Job.create(func=say_hello)
|
|
|
|
parent_job = Job.create(func=say_hello)
|
|
|
|
q = Queue()
|
|
|
|
q = Queue()
|
|
|
|