diff --git a/rq/__init__.py b/rq/__init__.py index 95050f3..5139266 100644 --- a/rq/__init__.py +++ b/rq/__init__.py @@ -7,7 +7,7 @@ from .connections import (Connection, get_current_connection, pop_connection, from .job import cancel_job, get_current_job, requeue_job from .queue import get_failed_queue, Queue from .version import VERSION -from .worker import Worker +from .worker import Worker, SimpleWorker __all__ = [ 'use_connection', 'get_current_connection', diff --git a/rq/worker.py b/rq/worker.py index f800b28..be4a955 100644 --- a/rq/worker.py +++ b/rq/worker.py @@ -558,3 +558,17 @@ class Worker(object): def pop_exc_handler(self): """Pops the latest exception handler off of the exc handler stack.""" return self._exc_handlers.pop() + +class SimpleWorker(Worker): + def _install_signal_handlers(self, *args, **kwargs): + """Signal handlers are useless for test worker, as it + does not have fork() ability""" + pass + + def main_work_horse(self, *args, **kwargs): + raise NotImplementedError("Test worker does not implement this method") + + def execute_job(self, *args, **kwargs): + """Execute job in same thread/process, do not fork()""" + return self.perform_job(*args, **kwargs) + diff --git a/tests/fixtures.py b/tests/fixtures.py index 7a9ac58..fc7d64f 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -6,11 +6,14 @@ fixtures has a slighty different characteristics. from __future__ import (absolute_import, division, print_function, unicode_literals) +import os import time from rq import Connection, get_current_job from rq.decorators import job +def say_pid(): + return os.getpid() def say_hello(name=None): """A job with a single argument and a return value.""" diff --git a/tests/test_worker.py b/tests/test_worker.py index e02ee2a..8aef2ac 100644 --- a/tests/test_worker.py +++ b/tests/test_worker.py @@ -4,13 +4,13 @@ from __future__ import (absolute_import, division, print_function, import os -from rq import get_failed_queue, Queue, Worker +from rq import get_failed_queue, Queue, Worker, SimpleWorker from rq.compat import as_text from rq.job import Job, Status from tests import RQTestCase, slow from tests.fixtures import (create_file, create_file_after_timeout, div_by_zero, - say_hello) + say_hello, say_pid) from tests.helpers import strip_microseconds @@ -277,3 +277,17 @@ class TestWorker(RQTestCase): q = Queue() worker = Worker([q], job_class=CustomJob) self.assertEqual(worker.job_class, CustomJob) + + def test_work_via_simpleworker(self): + """Worker processes work, with forking disabled, + then returns.""" + fooq, barq = Queue('foo'), Queue('bar') + w = SimpleWorker([fooq, barq]) + self.assertEquals(w.work(burst=True), False, + 'Did not expect any work on the queue.') + + job = fooq.enqueue(say_pid) + self.assertEquals(w.work(burst=True), True, + 'Expected at least some work done.') + self.assertEquals(job.result, os.getpid(), + 'PID mismatch, fork() is not supposed to happen here')