1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- # -*- coding: utf-8 -*-
- """
- celery.routes
- ~~~~~~~~~~~~~
-
- Contains utilities for working with task routers,
- (:setting:`CELERY_ROUTES`).
-
- """
- from __future__ import absolute_import
-
- from celery.exceptions import QueueNotFound
- from celery.five import string_t
- from celery.utils import lpmerge
- from celery.utils.functional import firstmethod, mlazy
- from celery.utils.imports import instantiate
-
- __all__ = ['MapRoute', 'Router', 'prepare']
-
- _first_route = firstmethod('route_for_task')
-
-
- class MapRoute(object):
- """Creates a router out of a :class:`dict`."""
-
- def __init__(self, map):
- self.map = map
-
- def route_for_task(self, task, *args, **kwargs):
- try:
- return dict(self.map[task])
- except KeyError:
- pass
- except ValueError:
- return {'queue': self.map[task]}
-
-
- class Router(object):
-
- def __init__(self, routes=None, queues=None,
- create_missing=False, app=None):
- self.app = app
- self.queues = {} if queues is None else queues
- self.routes = [] if routes is None else routes
- self.create_missing = create_missing
-
- def route(self, options, task, args=(), kwargs={}):
- options = self.expand_destination(options) # expands 'queue'
- if self.routes:
- route = self.lookup_route(task, args, kwargs)
- if route: # expands 'queue' in route.
- return lpmerge(self.expand_destination(route), options)
- if 'queue' not in options:
- options = lpmerge(self.expand_destination(
- self.app.conf.CELERY_DEFAULT_QUEUE), options)
- return options
-
- def expand_destination(self, route):
- # Route can be a queue name: convenient for direct exchanges.
- if isinstance(route, string_t):
- queue, route = route, {}
- else:
- # can use defaults from configured queue, but override specific
- # things (like the routing_key): great for topic exchanges.
- queue = route.pop('queue', None)
-
- if queue:
- try:
- Q = self.queues[queue] # noqa
- except KeyError:
- raise QueueNotFound(
- 'Queue {0!r} missing from CELERY_QUEUES'.format(queue))
- # needs to be declared by publisher
- route['queue'] = Q
- return route
-
- def lookup_route(self, task, args=None, kwargs=None):
- return _first_route(self.routes, task, args, kwargs)
-
-
- def prepare(routes):
- """Expands the :setting:`CELERY_ROUTES` setting."""
-
- def expand_route(route):
- if isinstance(route, dict):
- return MapRoute(route)
- if isinstance(route, string_t):
- return mlazy(instantiate, route)
- return route
-
- if routes is None:
- return ()
- if not isinstance(routes, (list, tuple)):
- routes = (routes, )
- return [expand_route(route) for route in routes]
|