| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 | ============================= "The Big Instance" Refactor=============================The `app` branch is a work-in-progress to removethe use of a global configuration in Celery.Celery can now be instantiated, which means severalinstances of Celery may exist in the same process space.Also, large parts can be customized without resorting to monkeypatching.Examples========Creating a Celery instance::    >>> from celery import Celery    >>> celery = Celery()    >>> celery.config_from_object("celeryconfig")    >>> celery.config_from_envvar("CELERY_CONFIG_MODULE")Creating tasks:.. code-block:: python    @celery.task    def add(x, y):        return x + yCreating custom Task subclasses:.. code-block:: python    Task = celery.create_task_cls()    class DebugTask(Task):        abstract = True        def on_failure(self, *args, **kwargs):            import pdb            pdb.set_trace()    @celery.task(base=DebugTask)    def add(x, y):        return x + yStarting a worker:.. code-block:: python    worker = celery.Worker(loglevel="INFO")Getting access to the configuration:.. code-block:: python    celery.conf.CELERY_ALWAYS_EAGER = True    celery.conf["CELERY_ALWAYS_EAGER"] = TrueControlling workers::    >>> celery.control.inspect().active()    >>> celery.control.rate_limit(add.name, "100/m")    >>> celery.control.broadcast("shutdown")    >>> celery.control.discard_all()Other interesting attributes::    # Establish broker connection.    >>> celery.broker_connection()    # AMQP Specific features.    >>> celery.amqp    >>> celery.amqp.Router    >>> celery.amqp.get_queues()    >>> celery.amqp.get_task_consumer()    # Loader    >>> celery.loader    # Default backend    >>> celery.backendAs you can probably see, this really opens up anotherdimension of customization abilities.Deprecations============* celery.task.ping  celery.task.PingTask  Inferior to the ping remote control command.  Will be removed in Celery 2.3.Removed deprecations====================* `celery.utils.timedelta_seconds`    Use: :func:`celery.utils.timeutils.timedelta_seconds`* `celery.utils.defaultdict`    Use: :func:`celery.utils.compat.defaultdict`* `celery.utils.all`    Use: :func:`celery.utils.compat.all`* `celery.task.apply_async`    Use app.send_task* `celery.task.tasks`    Use :data:`celery.registry.tasks`Aliases (Pending deprecation)=============================* celery.task.base    * .Task -> {app.create_task_cls}* celery.task.sets    * .TaskSet -> {app.TaskSet}* celery.decorators / celery.task    * .task -> {app.task}* celery.execute    * .apply_async -> {task.apply_async}    * .apply -> {task.apply}    * .send_task -> {app.send_task}    * .delay_task -> no alternative* celery.log    * .get_default_logger -> {app.log.get_default_logger}    * .setup_logger -> {app.log.setup_logger}    * .get_task_logger -> {app.log.get_task_logger}    * .setup_task_logger -> {app.log.setup_task_logger}    * .setup_logging_subsystem -> {app.log.setup_logging_subsystem}    * .redirect_stdouts_to_logger -> {app.log.redirect_stdouts_to_logger}* celery.messaging    * .establish_connection -> {app.broker_connection}    * .with_connection -> {app.with_connection}    * .get_consumer_set -> {app.amqp.get_task_consumer}    * .TaskPublisher -> {app.amqp.TaskPublisher}    * .TaskConsumer -> {app.amqp.TaskConsumer}    * .ConsumerSet -> {app.amqp.ConsumerSet}* celery.conf.* -> {app.conf}    **NOTE**: All configuration keys are now named the same    as in the configuration. So the key "CELERY_ALWAYS_EAGER"    is accessed as::        >>> app.conf.CELERY_ALWAYS_EAGER    instead of::        >>> from celery import conf        >>> conf.ALWAYS_EAGER    * .get_queues -> {app.amqp.get_queues}* celery.task.control    * .broadcast -> {app.control.broadcast}    * .rate_limit -> {app.control.rate_limit}    * .ping -> {app.control.ping}    * .revoke -> {app.control.revoke}    * .discard_all -> {app.control.discard_all}    * .inspect -> {app.control.inspect}* celery.utils.info    * .humanize_seconds -> celery.utils.timeutils.humanize_seconds    * .textindent -> celery.utils.textindent    * .get_broker_info -> {app.amqp.get_broker_info}    * .format_broker_info -> {app.amqp.format_broker_info}    * .format_queues -> {app.amqp.format_queues}Default App Usage=================To be backward compatible, it must be possibleto use all the classes/functions without passingan explicit app instance.This is achieved by having all app-dependent objectsuse :data:`~celery.app.default_app` if the app instanceis missing... code-block:: python    from celery.app import app_or_default    class SomeClass(object):        def __init__(self, app=None):            self.app = app_or_default(app)The problem with this approach is that there is a chancethat the app instance is lost along the way, and everythingseems to be working normally. Testing app instance leaksis hard. The environment variable :envvar:`CELERY_TRACE_APP`can be used, when this is enabled :func:`celery.app.app_or_default`will raise an exception whenever it has to go back to the default appinstance.App Dependency Tree-------------------* {app}    * celery.loaders.base.BaseLoader    * celery.backends.base.BaseBackend    * {app.TaskSet}        * celery.task.sets.TaskSet (app.TaskSet)    * [app.TaskSetResult]        * celery.result.TaskSetResult (app.TaskSetResult)* {app.AsyncResult}    * celery.result.BaseAsyncResult / celery.result.AsyncResult* celery.bin.celeryd.WorkerCommand    * celery.apps.worker.Worker        * celery.worker.WorkerController            * celery.worker.consumer.Consumer                * celery.worker.job.TaskRequest                * celery.events.EventDispatcher                * celery.worker.control.ControlDispatch                    * celery.woker.control.registry.Panel                    * celery.pidbox.BroadcastPublisher                * celery.pidbox.BroadcastConsumer            * celery.worker.controllers.Mediator            * celery.beat.EmbeddedService* celery.bin.celeryev.run_celeryev    * celery.events.snapshot.evcam        * celery.events.snapshot.Polaroid        * celery.events.EventReceiver    * celery.events.cursesmon.evtop        * celery.events.EventReceiver        * celery.events.cursesmon.CursesMonitor    * celery.events.dumper        * celery.events.EventReceiver* celery.bin.celeryctl.celeryctl    * celery.bin.celeryctl.Command* celery.bin.caqmadm.AMQPAdmin* celery.bin.celerybeat.BeatCommand    * celery.apps.beat.Beat        * celery.beat.Service            * celery.beat.Scheduler
 |