diff --git a/channels/asgi.py b/channels/asgi.py index 7e1629e..d11d0bf 100644 --- a/channels/asgi.py +++ b/channels/asgi.py @@ -5,6 +5,7 @@ from django.conf import settings from django.utils.module_loading import import_string from .consumer_registry import ConsumerRegistry +from .utils import name_that_thing class InvalidChannelLayerError(ValueError): @@ -71,6 +72,9 @@ class ChannelLayerWrapper(object): def __getattr__(self, name): return getattr(self.channel_layer, name) + def __str__(self): + return "%s (%s)" % (self.alias, name_that_thing(self.channel_layer)) + def get_channel_layer(alias="default"): """ diff --git a/channels/management/commands/runserver.py b/channels/management/commands/runserver.py index d78b899..b5e6bdd 100644 --- a/channels/management/commands/runserver.py +++ b/channels/management/commands/runserver.py @@ -16,6 +16,11 @@ from channels.worker import Worker class Command(RunserverCommand): + def add_arguments(self, parser): + super(Command, self).add_arguments(parser) + parser.add_argument('--noworker', action='store_false', dest='run_worker', default=True, + help='Tells Django not to run a worker thread; you\'ll need to run one separately.') + def handle(self, *args, **options): self.verbosity = options.get("verbosity", 1) self.logger = setup_logger('django.channels', self.verbosity) @@ -38,6 +43,7 @@ class Command(RunserverCommand): self.stdout.write(( "Django version %(version)s, using settings %(settings)r\n" "Starting Channels development server at http://%(addr)s:%(port)s/\n" + "Channel layer %(layer)s\n" "Quit the server with %(quit_command)s.\n" ) % { "version": self.get_version(), @@ -45,12 +51,14 @@ class Command(RunserverCommand): "addr": '[%s]' % self.addr if self._raw_ipv6 else self.addr, "port": self.port, "quit_command": quit_command, + "layer": self.channel_layer, }) # Launch worker as subthread - worker = WorkerThread(self.channel_layer, self.logger) - worker.daemon = True - worker.start() + if options.get("run_worker", True): + worker = WorkerThread(self.channel_layer, self.logger) + worker.daemon = True + worker.start() # Launch server in 'main' thread. Signals are disabled as it's still # actually a subthread under the autoreloader. self.logger.debug("Daphne running, listening on %s:%s", self.addr, self.port) @@ -60,9 +68,10 @@ class Command(RunserverCommand): channel_layer=self.channel_layer, host=self.addr, port=int(self.port), - signal_handlers=False, + signal_handlers=not options['use_reloader'], action_logger=self.log_action, ).run() + self.logger.debug("Daphne exited") except KeyboardInterrupt: shutdown_message = options.get('shutdown_message', '') if shutdown_message: @@ -118,3 +127,4 @@ class WorkerThread(threading.Thread): self.logger.debug("Worker thread running") worker = Worker(channel_layer=self.channel_layer) worker.run() + self.logger.debug("Worker thread exited") diff --git a/channels/management/commands/runworker.py b/channels/management/commands/runworker.py index 82ddace..40993d8 100644 --- a/channels/management/commands/runworker.py +++ b/channels/management/commands/runworker.py @@ -17,7 +17,7 @@ class Command(BaseCommand): # Check a handler is registered for http reqs self.channel_layer.registry.check_default() # Launch a worker - self.logger.info("Running worker against backend %s", self.channel_layer.alias) + self.logger.info("Running worker against backend %s", self.channel_layer) # Optionally provide an output callback callback = None if self.verbosity > 1: diff --git a/channels/utils.py b/channels/utils.py index 2cddb58..770f23e 100644 --- a/channels/utils.py +++ b/channels/utils.py @@ -11,4 +11,6 @@ def name_that_thing(thing): return name_that_thing(thing.__class__) if hasattr(thing, "__module__"): return "%s.%s" % (thing.__module__, thing.__name__) + if hasattr(thing, "__class__"): + return name_that_thing(thing.__class__) return repr(thing) diff --git a/channels/worker.py b/channels/worker.py index 5195271..c9567dd 100644 --- a/channels/worker.py +++ b/channels/worker.py @@ -25,7 +25,9 @@ class Worker(object): """ channels = self.channel_layer.registry.all_channel_names() while True: + logger.debug("Worker waiting for message") channel, content = self.channel_layer.receive_many(channels, block=True) + logger.debug("Worker got message on %s: repl %s", channel, content.get("reply_channel", "none")) # If no message, stall a little to avoid busy-looping then continue if channel is None: time.sleep(0.01)