|  | @@ -36,6 +36,24 @@ as well as PyPy and Jython.
 | 
	
		
			
				|  |  |  Important Notes
 | 
	
		
			
				|  |  |  ===============
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +Eventloop
 | 
	
		
			
				|  |  | +---------
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +The worker is now running *without threads* when used with AMQP or Redis as a
 | 
	
		
			
				|  |  | +broker, resulting in::
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    - Much better performance overall.
 | 
	
		
			
				|  |  | +    - Fixes several edge case race conditions.
 | 
	
		
			
				|  |  | +    - Sub-millisecond timer precision.
 | 
	
		
			
				|  |  | +    - Faster shutdown times.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +The transports supported are:  ``amqplib``, ``librabbitmq``, and ``redis``
 | 
	
		
			
				|  |  | +Hopefully this can be extended to include additional broker transports
 | 
	
		
			
				|  |  | +in the future.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +For increased reliability the :setting:`CELERY_FORCE_EXECV` setting is enabled
 | 
	
		
			
				|  |  | +by default if the eventloop is not used.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  Now depends on :mod:`billiard`.
 | 
	
		
			
				|  |  |  -------------------------------
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -52,6 +70,135 @@ for the no-execv patch to work.
 | 
	
		
			
				|  |  |  - `django-celery #122 <http://github.com/ask/django-celery/issues/122`
 | 
	
		
			
				|  |  |  - `django-celery #124 <http://github.com/ask/django-celery/issues/122`
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +Last version to support Python 2.5
 | 
	
		
			
				|  |  | +----------------------------------
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +The 2.6 series will be last series to support Python 2.5.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +With several other distributions taking the step to discontinue
 | 
	
		
			
				|  |  | +Python 2.5 support, we feel that it is time too.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +Python 2.6 should be widely available at this point, and we urge
 | 
	
		
			
				|  |  | +you to upgrade, but if that is not possible you still have the option
 | 
	
		
			
				|  |  | +to continue using the Celery 2.6 series, and important bug fixes
 | 
	
		
			
				|  |  | +introduced in Celery 2.7 will be back-ported to Celery 2.6 upon request.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +.. _v260-news:
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +News
 | 
	
		
			
				|  |  | +====
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +Chaining Tasks
 | 
	
		
			
				|  |  | +--------------
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +Tasks can now have callbacks and errbacks, and dependencies are recorded
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +- The task message format have been updated with two new extension keys
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    Both keys can be empty/undefined or a list of subtasks.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    - ``callbacks``
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Applied if the task exits successfully, with the result
 | 
	
		
			
				|  |  | +        of the task as an argument.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    - ``errbacks``
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Applied if an error occurred while executing the task,
 | 
	
		
			
				|  |  | +        with the uuid of the task as an argument.  Since it may not be possible
 | 
	
		
			
				|  |  | +        to serialize the exception instance, it passes the uuid of the task
 | 
	
		
			
				|  |  | +        instead.  The uuid can then be used to retrieve the exception and
 | 
	
		
			
				|  |  | +        traceback of the task from the result backend.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    - ``link`` and ``link_error`` keyword arguments has been added
 | 
	
		
			
				|  |  | +      to ``apply_async``.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        The value passed can be either a subtask or a list of
 | 
	
		
			
				|  |  | +        subtasks:
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        .. code-block:: python
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            add.apply_async((2, 2), link=mul.subtask())
 | 
	
		
			
				|  |  | +            add.apply_async((2, 2), link=[mul.subtask(), echo.subtask()])
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Example error callback:
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        .. code-block:: python
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            @task
 | 
	
		
			
				|  |  | +            def error_handler(uuid):
 | 
	
		
			
				|  |  | +                result = AsyncResult(uuid)
 | 
	
		
			
				|  |  | +                exc = result.get(propagate=False)
 | 
	
		
			
				|  |  | +                print("Task %r raised exception: %r\n%r" % (
 | 
	
		
			
				|  |  | +                    exc, result.traceback))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            >>> add.apply_async((2, 2), link_error=error_handler)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    - We now track what subtasks a task sends, and some result backends
 | 
	
		
			
				|  |  | +      supports retrieving this information.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        - task.request.children
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            Contains the result instances of the subtasks
 | 
	
		
			
				|  |  | +            the currently executing task has applied.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        - AsyncResult.children
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            Returns the tasks dependencies, as a list of
 | 
	
		
			
				|  |  | +            ``AsyncResult``/``ResultSet`` instances.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        - AsyncResult.iterdeps
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            Recursively iterates over the tasks dependencies,
 | 
	
		
			
				|  |  | +            yielding `(parent, node)` tuples.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            Raises IncompleteStream if any of the dependencies
 | 
	
		
			
				|  |  | +            has not returned yet.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +       - AsyncResult.graph
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            A ``DependencyGraph`` of the tasks dependencies.
 | 
	
		
			
				|  |  | +            This can also be used to convert to dot format:
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            .. code-block:: python
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                with open("graph.dot") as fh:
 | 
	
		
			
				|  |  | +                    result.graph.to_dot(fh)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            which can than be used to produce an image::
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                $ dot -Tpng graph.dot -o graph.png
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +- A new special subtask called ``chain`` is also included::
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    .. code-block:: python
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        >>> from celery import chain
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        # (2 + 2) * 8 / 2
 | 
	
		
			
				|  |  | +        >>> res = chain(add.subtask((4, 4)),
 | 
	
		
			
				|  |  | +                        mul.subtask((8, )),
 | 
	
		
			
				|  |  | +                        div.subtask((2,))).apply_async()
 | 
	
		
			
				|  |  | +        >>> res.get() == 16
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        >>> res.parent.get() == 32
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        >>> res.parent.parent.get() == 4
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +- Adds :meth:`AsyncResult.get_leaf`
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    Waits and returns the result of the leaf subtask.
 | 
	
		
			
				|  |  | +    That is the last node found when traversing the graph,
 | 
	
		
			
				|  |  | +    but this means that the graph can be 1-dimensional only (in effect
 | 
	
		
			
				|  |  | +    a list).
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +- Adds ``subtask.link(subtask)`` + ``subtask.link_error(subtask)``
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    Shortcut to ``s.options.setdefault("link", []).append(subtask)``
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +- Adds ``subtask.flatten_links()``
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    Returns a flattened list of all dependencies (recursively)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  `group`/`chord`/`chain` are now subtasks
 | 
	
		
			
				|  |  |  ----------------------------------------
 | 
	
	
		
			
				|  | @@ -119,20 +266,24 @@ for the no-execv patch to work.
 | 
	
		
			
				|  |  |                      tasks.add(8, 8),
 | 
	
		
			
				|  |  |                      tasks.add(9, 9)]) | tasks.pow(2)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* New :setting:`CELERYD_WORKER_LOST_WAIT` to control the timeout in
 | 
	
		
			
				|  |  | -  seconds before :exc:`billiard.WorkerLostError` is raised
 | 
	
		
			
				|  |  | -  when a worker can not be signalled (Issue #595).
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    Contributed by Brendon Crawford.
 | 
	
		
			
				|  |  | +Crontab now supports Day of Month, and Month of Year arguments
 | 
	
		
			
				|  |  | +--------------------------------------------------------------
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* App instance factory methods have been converted to be cached
 | 
	
		
			
				|  |  | -  descriptors that creates a new subclass on access.
 | 
	
		
			
				|  |  | +See the updated list of examples at :ref:`beat-crontab`.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    This means that e.g. ``celery.Worker`` is an actual class
 | 
	
		
			
				|  |  | -    and will work as expected when::
 | 
	
		
			
				|  |  | +Immutable subtasks
 | 
	
		
			
				|  |  | +------------------
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        class Worker(celery.Worker):
 | 
	
		
			
				|  |  | -            ...
 | 
	
		
			
				|  |  | +``subtask``'s can now be immutable, which means that the arguments
 | 
	
		
			
				|  |  | +will not be modified when applying callbacks::
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    >>> chain(add.s(2, 2), clear_static_electricity.si())
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +means it will not receive the argument of the parent task,
 | 
	
		
			
				|  |  | +and ``.si()`` is a shortcut to::
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    >>> clear_static_electricity.subtask(immutable=True)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  Logging Improvements
 | 
	
		
			
				|  |  |  --------------------
 | 
	
	
		
			
				|  | @@ -166,145 +317,160 @@ Logging support now conforms better with best practices.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  - Now avoids the 'no handlers for logger multiprocessing' warning
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -Unorganized
 | 
	
		
			
				|  |  | ------------
 | 
	
		
			
				|  |  | +Task registry no longer global
 | 
	
		
			
				|  |  | +------------------------------
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* Task registry is no longer a global.
 | 
	
		
			
				|  |  | +Every Celery instance now has its own task registry.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* celery.task.Task is no longer bound to an app by default,
 | 
	
		
			
				|  |  | -  so configuration of the task is lazy.
 | 
	
		
			
				|  |  | +You can make apps share registries by specifying it::
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* The @task decorator is now lazy when used with custom apps
 | 
	
		
			
				|  |  | +    >>> app1 = Celery()
 | 
	
		
			
				|  |  | +    >>> app2 = Celery(tasks=app1.tasks)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    If ``accept_magic_kwargs`` is enabled (herby called "compat mode"), the task
 | 
	
		
			
				|  |  | -    decorator executes inline like before, however for custom apps the @task
 | 
	
		
			
				|  |  | -    decorator now returns a special PromiseProxy object that is only evaluated
 | 
	
		
			
				|  |  | -    on access.
 | 
	
		
			
				|  |  | +Note that tasks are shared between registries by default, so that
 | 
	
		
			
				|  |  | +tasks will be added to every subsequently created task registry.
 | 
	
		
			
				|  |  | +As an alternative tasks can be private to specific task registries
 | 
	
		
			
				|  |  | +by setting the ``shared`` argument to the ``@task`` decorator::
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    All promises will be evaluated when `app.finalize` is called, or implicitly
 | 
	
		
			
				|  |  | -    when the task registry is first used.
 | 
	
		
			
				|  |  | +    @celery.task(shared=False)
 | 
	
		
			
				|  |  | +    def add(x, y):
 | 
	
		
			
				|  |  | +        return x + y
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* chain: Chain tasks together using callbacks under the hood.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    .. code-block:: python
 | 
	
		
			
				|  |  | +Abstract tasks are now lazily bound.
 | 
	
		
			
				|  |  | +------------------------------------
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        from celery import chain
 | 
	
		
			
				|  |  | +The :class:`~celery.task.Task` class is no longer bound to an app
 | 
	
		
			
				|  |  | +by default, it will first be bound (and configured) when
 | 
	
		
			
				|  |  | +a concrete subclass is created.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        # (2 + 2) * 8 / 2
 | 
	
		
			
				|  |  | -        res = chain(add.subtask((4, 4)),
 | 
	
		
			
				|  |  | -                    mul.subtask((8, )),
 | 
	
		
			
				|  |  | -                    div.subtask((2,))).apply_async()
 | 
	
		
			
				|  |  | -        res.get() == 16
 | 
	
		
			
				|  |  | +This means that you can safely import and make task base classes,
 | 
	
		
			
				|  |  | +without also initializing the default app environment::
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        res.parent.get() == 32
 | 
	
		
			
				|  |  | +    from celery.task import Task
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        res.parent.parent.get() == 4
 | 
	
		
			
				|  |  | +    class DebugTask(Task):
 | 
	
		
			
				|  |  | +        abstract = True
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        def __call__(self, *args, **kwargs):
 | 
	
		
			
				|  |  | +            print("CALLING %r" % (self, ))
 | 
	
		
			
				|  |  | +            return self.run(*args, **kwargs)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* The Celery instance can now be created with a broker URL
 | 
	
		
			
				|  |  | +    >>> DebugTask
 | 
	
		
			
				|  |  | +    <unbound DebugTask>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    .. code-block:: python
 | 
	
		
			
				|  |  | +    >>> @celery1.task(base=DebugTask)
 | 
	
		
			
				|  |  | +    ... def add(x, y):
 | 
	
		
			
				|  |  | +    ...     return x + y
 | 
	
		
			
				|  |  | +    >>> add.__class__
 | 
	
		
			
				|  |  | +    <class add of <Celery default:0x101510d10>>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        celery = Celery(broker="redis://")
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* Result backends can now be set using an URL
 | 
	
		
			
				|  |  | +Lazy task decorators
 | 
	
		
			
				|  |  | +--------------------
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    Currently only supported by redis.  Example use::
 | 
	
		
			
				|  |  | +The ``@task`` decorator is now lazy when used with custom apps.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        CELERY_RESULT_BACKEND = "redis://localhost/1"
 | 
	
		
			
				|  |  | +That is, if ``accept_magic_kwargs`` is enabled (herby called "compat mode"), the task
 | 
	
		
			
				|  |  | +decorator executes inline like before, however for custom apps the @task
 | 
	
		
			
				|  |  | +decorator now returns a special PromiseProxy object that is only evaluated
 | 
	
		
			
				|  |  | +on access.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* Heartbeat frequency now every 5s, and frequency sent with event
 | 
	
		
			
				|  |  | +All promises will be evaluated when `app.finalize` is called, or implicitly
 | 
	
		
			
				|  |  | +when the task registry is first used.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    The heartbeat frequency is now available in the worker event messages,
 | 
	
		
			
				|  |  | -    so that clients can decide when to consider workers offline based on
 | 
	
		
			
				|  |  | -    this value.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* Module celery.actors has been removed, and will be part of cl instead.
 | 
	
		
			
				|  |  | +Smart `--app` option
 | 
	
		
			
				|  |  | +--------------------
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* Introduces new ``celery`` command, which is an entrypoint for all other
 | 
	
		
			
				|  |  | -  commands.
 | 
	
		
			
				|  |  | +The :option:`--app` option now 'autodetects'
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    The main for this command can be run by calling ``celery.start()``.
 | 
	
		
			
				|  |  | +    - If the provided path is a module it tries to get an
 | 
	
		
			
				|  |  | +    attribute named 'celery'.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* Tasks can now have callbacks and errbacks, and dependencies are recorded
 | 
	
		
			
				|  |  | +    - If the provided path is a package it tries
 | 
	
		
			
				|  |  | +      to import a submodule named 'celery',
 | 
	
		
			
				|  |  | +      and get the celery attribute from that module.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    - The task message format have been updated with two new extension keys
 | 
	
		
			
				|  |  | +E.g. if you have a project named 'proj' where the
 | 
	
		
			
				|  |  | +celery app is located in 'from proj.celery import celery',
 | 
	
		
			
				|  |  | +then the following will be equivalent::
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        Both keys can be empty/undefined or a list of subtasks.
 | 
	
		
			
				|  |  | +        $ celeryd --app=proj
 | 
	
		
			
				|  |  | +        $ celeryd --app=proj.celery:
 | 
	
		
			
				|  |  | +        $ celeryd --app=proj.celery:celery
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        - ``callbacks``
 | 
	
		
			
				|  |  | +In Other News
 | 
	
		
			
				|  |  | +-------------
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            Applied if the task exits successfully, with the result
 | 
	
		
			
				|  |  | -            of the task as an argument.
 | 
	
		
			
				|  |  | +- New :setting:`CELERYD_WORKER_LOST_WAIT` to control the timeout in
 | 
	
		
			
				|  |  | +  seconds before :exc:`billiard.WorkerLostError` is raised
 | 
	
		
			
				|  |  | +  when a worker can not be signalled (Issue #595).
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        - ``errbacks``
 | 
	
		
			
				|  |  | +    Contributed by Brendon Crawford.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            Applied if an error occurred while executing the task,
 | 
	
		
			
				|  |  | -            with the uuid of the task as an argument.  Since it may not be possible
 | 
	
		
			
				|  |  | -            to serialize the exception instance, it passes the uuid of the task
 | 
	
		
			
				|  |  | -            instead.  The uuid can then be used to retrieve the exception and
 | 
	
		
			
				|  |  | -            traceback of the task from the result backend.
 | 
	
		
			
				|  |  | +- Redis event monitor queues are now automatically deleted (Issue #436).
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -   - ``link`` and ``link_error`` keyword arguments has been added
 | 
	
		
			
				|  |  | -      to ``apply_async``.
 | 
	
		
			
				|  |  | +- App instance factory methods have been converted to be cached
 | 
	
		
			
				|  |  | +  descriptors that creates a new subclass on access.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        The value passed can be either a subtask or a list of
 | 
	
		
			
				|  |  | -        subtasks:
 | 
	
		
			
				|  |  | +    This means that e.g. ``celery.Worker`` is an actual class
 | 
	
		
			
				|  |  | +    and will work as expected when::
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        .. code-block:: python
 | 
	
		
			
				|  |  | +        class Worker(celery.Worker):
 | 
	
		
			
				|  |  | +            ...
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            add.apply_async((2, 2), link=mul.subtask())
 | 
	
		
			
				|  |  | -            add.apply_async((2, 2), link=[mul.subtask(), echo.subtask()])
 | 
	
		
			
				|  |  | +- New signal: :signal:`task-success`.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        Example error callback:
 | 
	
		
			
				|  |  | +- Multiprocessing logs are now only emitted if the :envvar:`MP_LOG`
 | 
	
		
			
				|  |  | +  environment variable is set.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        .. code-block:: python
 | 
	
		
			
				|  |  | +- The Celery instance can now be created with a broker URL
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            @task
 | 
	
		
			
				|  |  | -            def error_handler(uuid):
 | 
	
		
			
				|  |  | -                result = AsyncResult(uuid)
 | 
	
		
			
				|  |  | -                exc = result.get(propagate=False)
 | 
	
		
			
				|  |  | -                print("Task %r raised exception: %r\n%r" % (
 | 
	
		
			
				|  |  | -                    exc, result.traceback))
 | 
	
		
			
				|  |  | +    .. code-block:: python
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            >>> add.apply_async((2, 2), link_error=error_handler)
 | 
	
		
			
				|  |  | +        celery = Celery(broker="redis://")
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    - We now track what subtasks a task sends, and some result backends
 | 
	
		
			
				|  |  | -      supports retrieving this information.
 | 
	
		
			
				|  |  | +- Result backends can now be set using an URL
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        - task.request.children
 | 
	
		
			
				|  |  | +    Currently only supported by redis.  Example use::
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            Contains the result instances of the subtasks
 | 
	
		
			
				|  |  | -            the currently executing task has applied.
 | 
	
		
			
				|  |  | +        CELERY_RESULT_BACKEND = "redis://localhost/1"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        - AsyncResult.children
 | 
	
		
			
				|  |  | +- Heartbeat frequency now every 5s, and frequency sent with event
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            Returns the tasks dependencies, as a list of
 | 
	
		
			
				|  |  | -            ``AsyncResult``/``ResultSet`` instances.
 | 
	
		
			
				|  |  | +    The heartbeat frequency is now available in the worker event messages,
 | 
	
		
			
				|  |  | +    so that clients can decide when to consider workers offline based on
 | 
	
		
			
				|  |  | +    this value.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        - AsyncResult.iterdeps
 | 
	
		
			
				|  |  | +- Module celery.actors has been removed, and will be part of cl instead.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            Recursively iterates over the tasks dependencies,
 | 
	
		
			
				|  |  | -            yielding `(parent, node)` tuples.
 | 
	
		
			
				|  |  | +- Introduces new ``celery`` command, which is an entrypoint for all other
 | 
	
		
			
				|  |  | +  commands.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            Raises IncompleteStream if any of the dependencies
 | 
	
		
			
				|  |  | -            has not returned yet.
 | 
	
		
			
				|  |  | +    The main for this command can be run by calling ``celery.start()``.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -       - AsyncResult.graph
 | 
	
		
			
				|  |  | +- Annotations now supports decorators if the key startswith '@'.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            A ``DependencyGraph`` of the tasks dependencies.
 | 
	
		
			
				|  |  | -            This can also be used to convert to dot format:
 | 
	
		
			
				|  |  | +    E.g.:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            .. code-block:: python
 | 
	
		
			
				|  |  | +    .. code-block:: python
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                with open("graph.dot") as fh:
 | 
	
		
			
				|  |  | -                    result.graph.to_dot(fh)
 | 
	
		
			
				|  |  | +        def debug_args(fun):
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            which can than be used to produce an image::
 | 
	
		
			
				|  |  | +            @wraps(fun)
 | 
	
		
			
				|  |  | +            def _inner(*args, **kwargs):
 | 
	
		
			
				|  |  | +                print("ARGS: %r" % (args, ))
 | 
	
		
			
				|  |  | +            return _inner
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                $ dot -Tpng graph.dot -o graph.png
 | 
	
		
			
				|  |  | +        CELERY_ANNOTATIONS = {
 | 
	
		
			
				|  |  | +            "tasks.add": {"@__call__": debug_args},
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* Bugreport now available as a command and broadcast command
 | 
	
		
			
				|  |  | +    Also tasks are now always bound by class so that
 | 
	
		
			
				|  |  | +    annotated methods end up being bound.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +- Bugreport now available as a command and broadcast command
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      - Get it from a Python repl::
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -319,29 +485,14 @@ Unorganized
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          $ celeryctl inspect report
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* Module ``celery.log`` moved to :mod:`celery.app.log`.
 | 
	
		
			
				|  |  | -* Module ``celery.task.control`` moved to :mod:`celery.app.control`.
 | 
	
		
			
				|  |  | +- Module ``celery.log`` moved to :mod:`celery.app.log`.
 | 
	
		
			
				|  |  | +- Module ``celery.task.control`` moved to :mod:`celery.app.control`.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* Adds :meth:`AsyncResult.get_leaf`
 | 
	
		
			
				|  |  | +- ``AsyncResult.task_id`` renamed to ``AsyncResult.id``
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    Waits and returns the result of the leaf subtask.
 | 
	
		
			
				|  |  | -    That is the last node found when traversing the graph,
 | 
	
		
			
				|  |  | -    but this means that the graph can be 1-dimensional only (in effect
 | 
	
		
			
				|  |  | -    a list).
 | 
	
		
			
				|  |  | +- ``TasksetResult.taskset_id`` renamed to ``.id``
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* Adds ``subtask.link(subtask)`` + ``subtask.link_error(subtask)``
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    Shortcut to ``s.options.setdefault("link", []).append(subtask)``
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -* Adds ``subtask.flatten_links()``
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    Returns a flattened list of all dependencies (recursively)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -* ``AsyncResult.task_id`` renamed to ``AsyncResult.id``
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -* ``TasksetResult.taskset_id`` renamed to ``.id``
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -* ``xmap(task, sequence)`` and ``xstarmap(task, sequence)``
 | 
	
		
			
				|  |  | +- ``xmap(task, sequence)`` and ``xstarmap(task, sequence)``
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      Returns a list of the results applying the task to every item
 | 
	
		
			
				|  |  |      in the sequence.
 | 
	
	
		
			
				|  | @@ -353,13 +504,25 @@ Unorganized
 | 
	
		
			
				|  |  |          >>> xstarmap(add, zip(range(10), range(10)).apply_async()
 | 
	
		
			
				|  |  |          [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* ``chunks(task, sequence, chunksize)``
 | 
	
		
			
				|  |  | +- ``chunks(task, sequence, chunksize)``
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +- ``group.skew(start=, stop=, step=)``
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  Skew will skew the countdown for the individual tasks in a group,
 | 
	
		
			
				|  |  | +  e.g. with a group::
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        >>> g = group(add.s(i, i) for i in xrange(10))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* ``group.skew()``
 | 
	
		
			
				|  |  | +  Skewing the tasks from 0 seconds to 10 seconds::
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* 99% Coverage
 | 
	
		
			
				|  |  | +        >>> g.skew(stop=10)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -* :setting:`CELERY_QUEUES` can now be a list/tuple of :class:`~kombu.Queue`
 | 
	
		
			
				|  |  | +  Will have the first task execute in 0 seconds, the second in 1 second,
 | 
	
		
			
				|  |  | +  the third in 2 seconds and so on.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +- 99% test Coverage
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +- :setting:`CELERY_QUEUES` can now be a list/tuple of :class:`~kombu.Queue`
 | 
	
		
			
				|  |  |    instances.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      Internally :attr:`@amqp.queues` is now a mapping of name/Queue instances,
 | 
	
	
		
			
				|  | @@ -399,6 +562,14 @@ Unorganized
 | 
	
		
			
				|  |  |    :setting:`CELERYBEAT_MAX_LOOP_INTERVAL` setting, it is instead
 | 
	
		
			
				|  |  |    set by individual schedulers.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +* celeryd now truncates very long message bodies in error reports.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +* :envvar:`CELERY_BENCH` environment variable, will now also list
 | 
	
		
			
				|  |  | +  memory usage statistics at celeryd shutdown.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +* celeryd now only ever use a single timer for all timing needs,
 | 
	
		
			
				|  |  | +  and instead set different priorities.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  Internals
 | 
	
		
			
				|  |  |  ---------
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -428,21 +599,81 @@ Internals
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  * :program:`setup.py` now reads docs from the :file:`requirements/` directory.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +.. _v260-experimental:
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +Experimental
 | 
	
		
			
				|  |  | +============
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +:mod:`celery.contrib.methods`:  Task decorator for methods
 | 
	
		
			
				|  |  | +----------------------------------------------------------
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +To use:
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +.. code-block:: python
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    from celery.contrib.methods import task
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    class X(object):
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    @task
 | 
	
		
			
				|  |  | +    def add(self, x, y):
 | 
	
		
			
				|  |  | +            return x + y
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +or with any task decorator:
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +.. code-block:: python
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    from celery.contrib.methods import task_method
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    class X(object):
 | 
	
		
			
				|  |  | +        @celery.task(filter=task_method)
 | 
	
		
			
				|  |  | +        def add(self, x, y):
 | 
	
		
			
				|  |  | +            return x + y
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +Caveats:
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +- Automatic naming won't be able to know what the class name is.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    The name will still be module_name + task_name,
 | 
	
		
			
				|  |  | +    so two methods with the same name in the same module will collide
 | 
	
		
			
				|  |  | +    so that only one task can run::
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        class A(object):
 | 
	
		
			
				|  |  | +            @task
 | 
	
		
			
				|  |  | +            def add(self, x, y):
 | 
	
		
			
				|  |  | +                return x + y
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        class B(object):
 | 
	
		
			
				|  |  | +            @task
 | 
	
		
			
				|  |  | +            def add(self, x, y):
 | 
	
		
			
				|  |  | +                return x + y
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    would have to be written as::
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        class A(object):
 | 
	
		
			
				|  |  | +            @task(name="A.add")
 | 
	
		
			
				|  |  | +            def add(self, x, y):
 | 
	
		
			
				|  |  | +                return x + y
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        class B(object):
 | 
	
		
			
				|  |  | +            @task(name="B.add")
 | 
	
		
			
				|  |  | +            def add(self, x, y):
 | 
	
		
			
				|  |  | +                return x + y
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  .. _v260-deprecations:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  Deprecations
 | 
	
		
			
				|  |  |  ============
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -.. _v260-news:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -News
 | 
	
		
			
				|  |  | -====
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -In Other News
 | 
	
		
			
				|  |  | --------------
 | 
	
		
			
				|  |  | +- The following settings have been renamed:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -- Now depends on Kombu 2.1.4
 | 
	
		
			
				|  |  | +    - ``CELERYD_ETA_SCHEDULER`` -> ``CELERYD_TIMER``
 | 
	
		
			
				|  |  | +    - ``CELERYD_ETA_SCHEDULER_PRECISION`` -> ``CELERYD_TIMER_PRECISION``
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  Fixes
 | 
	
		
			
				|  |  |  =====
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +- Retry sqlalchemy backend operations on DatabaseError/OperationalError
 | 
	
		
			
				|  |  | +  (Issue #634)
 |