whatsnew-2.6.rst 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. .. _whatsnew-2.6:
  2. ==========================
  3. What's new in Celery 2.6
  4. ==========================
  5. Celery aims to be a flexible and reliable, best-of-breed solution
  6. to process vast amounts of messages in a distributed fashion, while
  7. providing operations with the tools to maintain such a system.
  8. Celery has a large and diverse community of users and contributors,
  9. you should come join us :ref:`on IRC <irc-channel>`
  10. or :ref:`our mailing-list <mailing-list>`.
  11. To read more about Celery you should visit our `website`_.
  12. While this version is backward compatible with previous versions
  13. it is important that you read the following section.
  14. If you use Celery in combination with Django you must also
  15. read the `django-celery changelog`_ and upgrade to `django-celery 2.6`_.
  16. This version is officially supported on CPython 2.5, 2.6, 2.7, 3.2 and 3.3,
  17. as well as PyPy and Jython.
  18. .. _`website`: http://celeryproject.org/
  19. .. _`django-celery changelog`: http://bit.ly/djcelery-26-changelog
  20. .. _`django-celery 2.6`: http://pypi.python.org/pypi/django-celery/
  21. .. contents::
  22. :local:
  23. .. _v260-important:
  24. Important Notes
  25. ===============
  26. Eventloop
  27. ---------
  28. The worker is now running *without threads* when used with AMQP or Redis as a
  29. broker, resulting in::
  30. - Much better performance overall.
  31. - Fixes several edge case race conditions.
  32. - Sub-millisecond timer precision.
  33. - Faster shutdown times.
  34. The transports supported are: ``amqplib``, ``librabbitmq``, and ``redis``
  35. Hopefully this can be extended to include additional broker transports
  36. in the future.
  37. For increased reliability the :setting:`CELERY_FORCE_EXECV` setting is enabled
  38. by default if the eventloop is not used.
  39. Now depends on :mod:`billiard`.
  40. -------------------------------
  41. Billiard is a fork of the multiprocessing containing
  42. the no-execv patch by sbt (http://bugs.python.org/issue8713),
  43. and also contains the pool improvements previously located in Celery.
  44. This fork was necessary as changes to the C extension code was required
  45. for the no-execv patch to work.
  46. - Issue #625
  47. - Issue #627
  48. - Issue #640
  49. - `django-celery #122 <http://github.com/ask/django-celery/issues/122`
  50. - `django-celery #124 <http://github.com/ask/django-celery/issues/122`
  51. Last version to support Python 2.5
  52. ----------------------------------
  53. The 2.6 series will be last series to support Python 2.5.
  54. With several other distributions taking the step to discontinue
  55. Python 2.5 support, we feel that it is time too.
  56. Python 2.6 should be widely available at this point, and we urge
  57. you to upgrade, but if that is not possible you still have the option
  58. to continue using the Celery 2.6 series, and important bug fixes
  59. introduced in Celery 2.7 will be back-ported to Celery 2.6 upon request.
  60. .. _v260-news:
  61. News
  62. ====
  63. Chaining Tasks
  64. --------------
  65. Tasks can now have callbacks and errbacks, and dependencies are recorded
  66. - The task message format have been updated with two new extension keys
  67. Both keys can be empty/undefined or a list of subtasks.
  68. - ``callbacks``
  69. Applied if the task exits successfully, with the result
  70. of the task as an argument.
  71. - ``errbacks``
  72. Applied if an error occurred while executing the task,
  73. with the uuid of the task as an argument. Since it may not be possible
  74. to serialize the exception instance, it passes the uuid of the task
  75. instead. The uuid can then be used to retrieve the exception and
  76. traceback of the task from the result backend.
  77. - ``link`` and ``link_error`` keyword arguments has been added
  78. to ``apply_async``.
  79. The value passed can be either a subtask or a list of
  80. subtasks:
  81. .. code-block:: python
  82. add.apply_async((2, 2), link=mul.subtask())
  83. add.apply_async((2, 2), link=[mul.subtask(), echo.subtask()])
  84. Example error callback:
  85. .. code-block:: python
  86. @task
  87. def error_handler(uuid):
  88. result = AsyncResult(uuid)
  89. exc = result.get(propagate=False)
  90. print("Task %r raised exception: %r\n%r" % (
  91. exc, result.traceback))
  92. >>> add.apply_async((2, 2), link_error=error_handler)
  93. - We now track what subtasks a task sends, and some result backends
  94. supports retrieving this information.
  95. - task.request.children
  96. Contains the result instances of the subtasks
  97. the currently executing task has applied.
  98. - AsyncResult.children
  99. Returns the tasks dependencies, as a list of
  100. ``AsyncResult``/``ResultSet`` instances.
  101. - AsyncResult.iterdeps
  102. Recursively iterates over the tasks dependencies,
  103. yielding `(parent, node)` tuples.
  104. Raises IncompleteStream if any of the dependencies
  105. has not returned yet.
  106. - AsyncResult.graph
  107. A ``DependencyGraph`` of the tasks dependencies.
  108. This can also be used to convert to dot format:
  109. .. code-block:: python
  110. with open("graph.dot") as fh:
  111. result.graph.to_dot(fh)
  112. which can than be used to produce an image::
  113. $ dot -Tpng graph.dot -o graph.png
  114. - A new special subtask called ``chain`` is also included::
  115. .. code-block:: python
  116. >>> from celery import chain
  117. # (2 + 2) * 8 / 2
  118. >>> res = chain(add.subtask((4, 4)),
  119. mul.subtask((8, )),
  120. div.subtask((2,))).apply_async()
  121. >>> res.get() == 16
  122. >>> res.parent.get() == 32
  123. >>> res.parent.parent.get() == 4
  124. - Adds :meth:`AsyncResult.get_leaf`
  125. Waits and returns the result of the leaf subtask.
  126. That is the last node found when traversing the graph,
  127. but this means that the graph can be 1-dimensional only (in effect
  128. a list).
  129. - Adds ``subtask.link(subtask)`` + ``subtask.link_error(subtask)``
  130. Shortcut to ``s.options.setdefault("link", []).append(subtask)``
  131. - Adds ``subtask.flatten_links()``
  132. Returns a flattened list of all dependencies (recursively)
  133. `group`/`chord`/`chain` are now subtasks
  134. ----------------------------------------
  135. - The source code for these, including subtask, has been moved
  136. to new module celery.canvas.
  137. - group is no longer an alias to TaskSet, but new alltogether,
  138. since it was very difficult to migrate the TaskSet class to become
  139. a subtask.
  140. - A new shortcut has been added to tasks::
  141. >>> task.s(arg1, arg2, kw=1)
  142. as a shortcut to::
  143. >>> task.subtask((arg1, arg2), {"kw": 1})
  144. - Tasks can be chained by using the ``|`` operator::
  145. >>> (add.s(2, 2), pow.s(2)).apply_async()
  146. - Subtasks can be "evaluated" using the ``~`` operator::
  147. >>> ~add.s(2, 2)
  148. 4
  149. >>> ~(add.s(2, 2) | pow.s(2))
  150. is the same as::
  151. >>> chain(add.s(2, 2), pow.s(2)).apply_async().get()
  152. - A new subtask_type key has been added to the subtask dicts
  153. This can be the string "chord", "group", "chain", "chunks",
  154. "xmap", or "xstarmap".
  155. - maybe_subtask now uses subtask_type to reconstruct
  156. the object, to be used when using non-pickle serializers.
  157. - The logic for these operations have been moved to dedicated
  158. tasks celery.chord, celery.chain and celery.group.
  159. - subtask no longer inherits from AttributeDict.
  160. It's now a pure dict subclass with properties for attribute
  161. access to the relevant keys.
  162. - The repr's now outputs how the sequence would like imperatively::
  163. >>> from celery import chord
  164. >>> (chord([add.s(i, i) for i in xrange(10)], xsum.s())
  165. | pow.s(2))
  166. tasks.xsum([tasks.add(0, 0),
  167. tasks.add(1, 1),
  168. tasks.add(2, 2),
  169. tasks.add(3, 3),
  170. tasks.add(4, 4),
  171. tasks.add(5, 5),
  172. tasks.add(6, 6),
  173. tasks.add(7, 7),
  174. tasks.add(8, 8),
  175. tasks.add(9, 9)]) | tasks.pow(2)
  176. Crontab now supports Day of Month, and Month of Year arguments
  177. --------------------------------------------------------------
  178. See the updated list of examples at :ref:`beat-crontab`.
  179. Immutable subtasks
  180. ------------------
  181. ``subtask``'s can now be immutable, which means that the arguments
  182. will not be modified when applying callbacks::
  183. >>> chain(add.s(2, 2), clear_static_electricity.si())
  184. means it will not receive the argument of the parent task,
  185. and ``.si()`` is a shortcut to::
  186. >>> clear_static_electricity.subtask(immutable=True)
  187. Logging Improvements
  188. --------------------
  189. Logging support now conforms better with best practices.
  190. - Classes used by the worker no longer uses app.get_default_logger, but uses
  191. `celery.utils.log.get_logger` which simply gets the logger not setting the
  192. level, and adds a NullHandler.
  193. - Loggers are no longer passed around, instead every module using logging
  194. defines a module global logger that is used throughout.
  195. - All loggers inherit from a common logger called "celery".
  196. - Before task.get_logger would setup a new logger for every task,
  197. and even set the loglevel. This is no longer the case.
  198. - Instead all task loggers now inherit from a common "celery.task" logger
  199. that is set up when programs call `setup_logging_subsystem`.
  200. - Instead of using LoggerAdapter to augment the formatter with
  201. the task_id and task_name field, the task base logger now use
  202. a special formatter adding these values at runtime from the
  203. currently executing task.
  204. - Redirected output from stdout/stderr is now logged to a "celery.redirected"
  205. logger.
  206. - In addition a few warnings.warn have been replaced with logger.warn.
  207. - Now avoids the 'no handlers for logger multiprocessing' warning
  208. Task registry no longer global
  209. ------------------------------
  210. Every Celery instance now has its own task registry.
  211. You can make apps share registries by specifying it::
  212. >>> app1 = Celery()
  213. >>> app2 = Celery(tasks=app1.tasks)
  214. Note that tasks are shared between registries by default, so that
  215. tasks will be added to every subsequently created task registry.
  216. As an alternative tasks can be private to specific task registries
  217. by setting the ``shared`` argument to the ``@task`` decorator::
  218. @celery.task(shared=False)
  219. def add(x, y):
  220. return x + y
  221. Abstract tasks are now lazily bound.
  222. ------------------------------------
  223. The :class:`~celery.task.Task` class is no longer bound to an app
  224. by default, it will first be bound (and configured) when
  225. a concrete subclass is created.
  226. This means that you can safely import and make task base classes,
  227. without also initializing the default app environment::
  228. from celery.task import Task
  229. class DebugTask(Task):
  230. abstract = True
  231. def __call__(self, *args, **kwargs):
  232. print("CALLING %r" % (self, ))
  233. return self.run(*args, **kwargs)
  234. >>> DebugTask
  235. <unbound DebugTask>
  236. >>> @celery1.task(base=DebugTask)
  237. ... def add(x, y):
  238. ... return x + y
  239. >>> add.__class__
  240. <class add of <Celery default:0x101510d10>>
  241. Lazy task decorators
  242. --------------------
  243. The ``@task`` decorator is now lazy when used with custom apps.
  244. That is, if ``accept_magic_kwargs`` is enabled (herby called "compat mode"), the task
  245. decorator executes inline like before, however for custom apps the @task
  246. decorator now returns a special PromiseProxy object that is only evaluated
  247. on access.
  248. All promises will be evaluated when `app.finalize` is called, or implicitly
  249. when the task registry is first used.
  250. Smart `--app` option
  251. --------------------
  252. The :option:`--app` option now 'autodetects'
  253. - If the provided path is a module it tries to get an
  254. attribute named 'celery'.
  255. - If the provided path is a package it tries
  256. to import a submodule named 'celery',
  257. and get the celery attribute from that module.
  258. E.g. if you have a project named 'proj' where the
  259. celery app is located in 'from proj.celery import celery',
  260. then the following will be equivalent::
  261. $ celeryd --app=proj
  262. $ celeryd --app=proj.celery:
  263. $ celeryd --app=proj.celery:celery
  264. In Other News
  265. -------------
  266. - New :setting:`CELERYD_WORKER_LOST_WAIT` to control the timeout in
  267. seconds before :exc:`billiard.WorkerLostError` is raised
  268. when a worker can not be signalled (Issue #595).
  269. Contributed by Brendon Crawford.
  270. - Redis event monitor queues are now automatically deleted (Issue #436).
  271. - App instance factory methods have been converted to be cached
  272. descriptors that creates a new subclass on access.
  273. This means that e.g. ``celery.Worker`` is an actual class
  274. and will work as expected when::
  275. class Worker(celery.Worker):
  276. ...
  277. - New signal: :signal:`task-success`.
  278. - Multiprocessing logs are now only emitted if the :envvar:`MP_LOG`
  279. environment variable is set.
  280. - The Celery instance can now be created with a broker URL
  281. .. code-block:: python
  282. celery = Celery(broker="redis://")
  283. - Result backends can now be set using an URL
  284. Currently only supported by redis. Example use::
  285. CELERY_RESULT_BACKEND = "redis://localhost/1"
  286. - Heartbeat frequency now every 5s, and frequency sent with event
  287. The heartbeat frequency is now available in the worker event messages,
  288. so that clients can decide when to consider workers offline based on
  289. this value.
  290. - Module celery.actors has been removed, and will be part of cl instead.
  291. - Introduces new ``celery`` command, which is an entrypoint for all other
  292. commands.
  293. The main for this command can be run by calling ``celery.start()``.
  294. - Annotations now supports decorators if the key startswith '@'.
  295. E.g.:
  296. .. code-block:: python
  297. def debug_args(fun):
  298. @wraps(fun)
  299. def _inner(*args, **kwargs):
  300. print("ARGS: %r" % (args, ))
  301. return _inner
  302. CELERY_ANNOTATIONS = {
  303. "tasks.add": {"@__call__": debug_args},
  304. }
  305. Also tasks are now always bound by class so that
  306. annotated methods end up being bound.
  307. - Bugreport now available as a command and broadcast command
  308. - Get it from a Python repl::
  309. >>> import celery
  310. >>> print(celery.bugreport())
  311. - Use celeryctl::
  312. $ celeryctl report
  313. - Get it from remote workers::
  314. $ celeryctl inspect report
  315. - Module ``celery.log`` moved to :mod:`celery.app.log`.
  316. - Module ``celery.task.control`` moved to :mod:`celery.app.control`.
  317. - ``AsyncResult.task_id`` renamed to ``AsyncResult.id``
  318. - ``TasksetResult.taskset_id`` renamed to ``.id``
  319. - ``xmap(task, sequence)`` and ``xstarmap(task, sequence)``
  320. Returns a list of the results applying the task to every item
  321. in the sequence.
  322. Example::
  323. >>> from celery import xstarmap
  324. >>> xstarmap(add, zip(range(10), range(10)).apply_async()
  325. [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
  326. - ``chunks(task, sequence, chunksize)``
  327. - ``group.skew(start=, stop=, step=)``
  328. Skew will skew the countdown for the individual tasks in a group,
  329. e.g. with a group::
  330. >>> g = group(add.s(i, i) for i in xrange(10))
  331. Skewing the tasks from 0 seconds to 10 seconds::
  332. >>> g.skew(stop=10)
  333. Will have the first task execute in 0 seconds, the second in 1 second,
  334. the third in 2 seconds and so on.
  335. - 99% test Coverage
  336. - :setting:`CELERY_QUEUES` can now be a list/tuple of :class:`~kombu.Queue`
  337. instances.
  338. Internally :attr:`@amqp.queues` is now a mapping of name/Queue instances,
  339. instead of converting on the fly.
  340. * Can now specify connection for :class:`@control.inspect`.
  341. .. code-block:: python
  342. i = celery.control.inspect(connection=BrokerConnection("redis://"))
  343. i.active_queues()
  344. * Module :mod:`celery.app.task` is now a module instead of a package.
  345. The setup.py install script will try to remove the old package,
  346. if that doesn't work for some reason you have to remove
  347. it manually, you can do so by executing the command::
  348. $ rm -r $(dirname $(python -c '
  349. import celery;print(celery.__file__)'))/app/task/
  350. * :setting:`CELERY_FORCE_EXECV` is now enabled by default.
  351. If the old behavior is wanted the setting can be set to False,
  352. or the new :option:`--no-execv` to :program:`celeryd`.
  353. * Deprecated module ``celery.conf`` has been removed.
  354. * The :setting:`CELERY_TIMEZONE` now always require the :mod:`pytz`
  355. library to be installed (exept if the timezone is set to `UTC`).
  356. * The Tokyo Tyrant backend has been removed and is no longer supported.
  357. * Now uses :func:`~kombu.common.maybe_declare` to cache queue declarations.
  358. * There is no longer a global default for the
  359. :setting:`CELERYBEAT_MAX_LOOP_INTERVAL` setting, it is instead
  360. set by individual schedulers.
  361. * celeryd now truncates very long message bodies in error reports.
  362. * :envvar:`CELERY_BENCH` environment variable, will now also list
  363. memory usage statistics at celeryd shutdown.
  364. * celeryd now only ever use a single timer for all timing needs,
  365. and instead set different priorities.
  366. Internals
  367. ---------
  368. * Compat modules are now generated dynamically upon use.
  369. These modules are ``celery.messaging``, ``celery.log``,
  370. ``celery.decorators`` and ``celery.registry``.
  371. * :mod:`celery.utils` refactored into multiple modules:
  372. :mod:`celery.utils.text`
  373. :mod:`celery.utils.imports`
  374. :mod:`celery.utils.functional`
  375. * Now using :mod:`kombu.utils.encoding` instead of
  376. `:mod:`celery.utils.encoding`.
  377. * Renamed module ``celery.routes`` -> :mod:`celery.app.routes`.
  378. * Renamed package ``celery.db`` -> :mod:`celery.backends.database`.
  379. * Renamed module ``celery.abstract`` -> :mod:`celery.worker.abstract`.
  380. * Command-line docs are now parsed from the module docstrings.
  381. * Test suite directory has been reorganized.
  382. * :program:`setup.py` now reads docs from the :file:`requirements/` directory.
  383. .. _v260-experimental:
  384. Experimental
  385. ============
  386. :mod:`celery.contrib.methods`: Task decorator for methods
  387. ----------------------------------------------------------
  388. To use:
  389. .. code-block:: python
  390. from celery.contrib.methods import task
  391. class X(object):
  392. @task
  393. def add(self, x, y):
  394. return x + y
  395. or with any task decorator:
  396. .. code-block:: python
  397. from celery.contrib.methods import task_method
  398. class X(object):
  399. @celery.task(filter=task_method)
  400. def add(self, x, y):
  401. return x + y
  402. Caveats:
  403. - Automatic naming won't be able to know what the class name is.
  404. The name will still be module_name + task_name,
  405. so two methods with the same name in the same module will collide
  406. so that only one task can run::
  407. class A(object):
  408. @task
  409. def add(self, x, y):
  410. return x + y
  411. class B(object):
  412. @task
  413. def add(self, x, y):
  414. return x + y
  415. would have to be written as::
  416. class A(object):
  417. @task(name="A.add")
  418. def add(self, x, y):
  419. return x + y
  420. class B(object):
  421. @task(name="B.add")
  422. def add(self, x, y):
  423. return x + y
  424. .. _v260-deprecations:
  425. Deprecations
  426. ============
  427. - The following settings have been renamed:
  428. - ``CELERYD_ETA_SCHEDULER`` -> ``CELERYD_TIMER``
  429. - ``CELERYD_ETA_SCHEDULER_PRECISION`` -> ``CELERYD_TIMER_PRECISION``
  430. Fixes
  431. =====
  432. - Retry sqlalchemy backend operations on DatabaseError/OperationalError
  433. (Issue #634)