2013-08-29 23:41:03 +02:00
|
|
|
from __future__ import absolute_import
|
|
|
|
|
2016-07-30 05:23:46 +02:00
|
|
|
from types import FrameType
|
2017-05-28 08:17:29 +02:00
|
|
|
from typing import Any, List
|
2016-06-04 16:52:18 +02:00
|
|
|
|
|
|
|
from argparse import ArgumentParser
|
2013-08-29 23:41:03 +02:00
|
|
|
from django.core.management.base import BaseCommand
|
|
|
|
from django.core.management import CommandError
|
|
|
|
from django.conf import settings
|
2016-06-23 20:00:27 +02:00
|
|
|
from django.utils import autoreload
|
2015-11-24 07:01:35 +01:00
|
|
|
from zerver.worker.queue_processors import get_worker, get_active_worker_queues
|
2013-08-29 23:41:03 +02:00
|
|
|
import sys
|
|
|
|
import signal
|
|
|
|
import logging
|
2015-11-24 07:01:35 +01:00
|
|
|
import threading
|
2013-08-29 23:41:03 +02:00
|
|
|
|
|
|
|
class Command(BaseCommand):
|
2015-08-21 02:10:41 +02:00
|
|
|
def add_arguments(self, parser):
|
2016-06-04 16:52:18 +02:00
|
|
|
# type: (ArgumentParser) -> None
|
2015-11-24 07:01:35 +01:00
|
|
|
parser.add_argument('--queue_name', metavar='<queue name>', type=str,
|
2015-08-21 02:10:41 +02:00
|
|
|
help="queue to process")
|
2015-11-24 07:01:35 +01:00
|
|
|
parser.add_argument('--worker_num', metavar='<worker number>', type=int, nargs='?', default=0,
|
2015-08-21 02:10:41 +02:00
|
|
|
help="worker label")
|
2015-11-24 07:01:35 +01:00
|
|
|
parser.add_argument('--all', dest="all", action="store_true", default=False,
|
|
|
|
help="run all queues")
|
2017-05-28 08:17:29 +02:00
|
|
|
parser.add_argument('--multi_threaded', nargs='+',
|
|
|
|
metavar='<list of queue name>',
|
|
|
|
type=str, required=False,
|
|
|
|
help="list of queue to process")
|
2015-08-21 02:10:41 +02:00
|
|
|
|
2013-08-29 23:41:03 +02:00
|
|
|
help = "Runs a queue processing worker"
|
2016-11-29 07:22:02 +01:00
|
|
|
|
2013-08-29 23:41:03 +02:00
|
|
|
def handle(self, *args, **options):
|
2016-06-04 16:52:18 +02:00
|
|
|
# type: (*Any, **Any) -> None
|
2013-08-29 23:41:03 +02:00
|
|
|
logging.basicConfig()
|
|
|
|
logger = logging.getLogger('process_queue')
|
|
|
|
|
2013-10-23 21:14:17 +02:00
|
|
|
if not settings.USING_RABBITMQ:
|
2016-10-27 21:35:36 +02:00
|
|
|
# Make the warning silent when running the tests
|
|
|
|
if settings.TEST_SUITE:
|
|
|
|
logger.info("Not using RabbitMQ queue workers in the test suite.")
|
|
|
|
else:
|
|
|
|
logger.error("Cannot run a queue processor when USING_RABBITMQ is False!")
|
2013-10-23 21:14:17 +02:00
|
|
|
sys.exit(1)
|
|
|
|
|
2017-05-28 08:17:29 +02:00
|
|
|
def run_threaded_workers(queues, logger):
|
|
|
|
# type: (List[str], logging.Logger) -> None
|
2016-11-16 21:05:54 +01:00
|
|
|
cnt = 0
|
2017-05-28 08:17:29 +02:00
|
|
|
for queue_name in queues:
|
2016-11-16 21:05:54 +01:00
|
|
|
if not settings.DEVELOPMENT:
|
|
|
|
logger.info('launching queue worker thread ' + queue_name)
|
|
|
|
cnt += 1
|
2015-11-24 07:01:35 +01:00
|
|
|
td = Threaded_worker(queue_name)
|
|
|
|
td.start()
|
2017-05-28 08:17:29 +02:00
|
|
|
assert len(queues) == cnt
|
2016-11-16 21:05:54 +01:00
|
|
|
logger.info('%d queue worker threads were launched' % (cnt,))
|
2016-06-23 20:00:27 +02:00
|
|
|
|
|
|
|
if options['all']:
|
2017-05-28 08:17:29 +02:00
|
|
|
autoreload.main(run_threaded_workers, (get_active_worker_queues(), logger))
|
|
|
|
elif options['multi_threaded']:
|
|
|
|
queues = options['multi_threaded']
|
|
|
|
autoreload.main(run_threaded_workers, (queues, logger))
|
2015-11-24 07:01:35 +01:00
|
|
|
else:
|
|
|
|
queue_name = options['queue_name']
|
|
|
|
worker_num = options['worker_num']
|
|
|
|
|
|
|
|
logger.info("Worker %d connecting to queue %s" % (worker_num, queue_name))
|
|
|
|
worker = get_worker(queue_name)
|
2016-03-28 08:16:57 +02:00
|
|
|
worker.setup()
|
2015-11-24 07:01:35 +01:00
|
|
|
|
|
|
|
def signal_handler(signal, frame):
|
2016-07-30 05:23:46 +02:00
|
|
|
# type: (int, FrameType) -> None
|
2015-11-24 07:01:35 +01:00
|
|
|
logger.info("Worker %d disconnecting from queue %s" % (worker_num, queue_name))
|
|
|
|
worker.stop()
|
|
|
|
sys.exit(0)
|
|
|
|
signal.signal(signal.SIGTERM, signal_handler)
|
|
|
|
signal.signal(signal.SIGINT, signal_handler)
|
|
|
|
|
|
|
|
worker.start()
|
|
|
|
|
|
|
|
class Threaded_worker(threading.Thread):
|
|
|
|
def __init__(self, queue_name):
|
2016-06-04 16:52:18 +02:00
|
|
|
# type: (str) -> None
|
2015-11-24 07:01:35 +01:00
|
|
|
threading.Thread.__init__(self)
|
|
|
|
self.worker = get_worker(queue_name)
|
|
|
|
|
|
|
|
def run(self):
|
2016-06-04 16:52:18 +02:00
|
|
|
# type: () -> None
|
2015-11-24 07:01:35 +01:00
|
|
|
self.worker.setup()
|
|
|
|
logging.debug('starting consuming ' + self.worker.queue_name)
|
|
|
|
self.worker.start()
|