first-steps-with-celery.rst 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. .. _tut-celery:
  2. ========================
  3. First steps with Celery
  4. ========================
  5. .. contents::
  6. :local:
  7. .. _celerytut-broker:
  8. Choosing a Broker
  9. =================
  10. Celery requires a solution to send and receive messages, this is called
  11. the *message transport*. Usually this comes in the form of a separate
  12. service called a *message broker*.
  13. There are several choices available, including:
  14. * :ref:`broker-rabbitmq`
  15. `RabbitMQ`_ is feature-complete, stable, durable and easy to install.
  16. * :ref:`broker-redis`
  17. `Redis`_ is also feature-complete, but is more susceptible to data loss in
  18. the event of abrupt termination or power failures.
  19. * :ref:`broker-sqlalchemy`
  20. * :ref:`broker-django`
  21. Using a database as a message queue is not recommended, but can be sufficient
  22. for very small installations. Celery can use the SQLAlchemy and Django ORM.
  23. * and more.
  24. In addition to the above, there are several other transport implementations
  25. to choose from, including :ref:`broker-couchdb`, :ref:`broker-beanstalk`,
  26. :ref:`broker-mongodb`, and SQS. There is a `Transport Comparison`_
  27. in the Kombu documentation.
  28. .. _`RabbitMQ`: http://www.rabbitmq.com/
  29. .. _`Redis`: http://redis.io/
  30. .. _`Transport Comparison`: http://kombu.rtfd.org/transport-comparison
  31. .. _celerytut-conf:
  32. Application
  33. ===========
  34. The first thing you need is a Celery instance. Since the instance is used as
  35. the entry-point for everything you want to do in Celery, like creating task and
  36. managing workers, it must be possible for other modules to import it.
  37. Some people create a dedicated module for it, but in this tutorial we will
  38. keep it in the same module used to start our worker::
  39. Let's create the file :file:`worker.py`:
  40. .. code-block:: python
  41. from celery import Celery
  42. celery = Celery(broker="amqp://guest:guest@localhost:5672")
  43. if __name__ == "__main__":
  44. celery.worker_main()
  45. The broker argument specifies the message broker we want to use, what
  46. we are using in this example is the default, but we keep it there for
  47. reference so you can see what the URLs look like.
  48. The backend argument specifies what we use to store and retrieve task
  49. states and results, it is disabled by default.
  50. For list of backends available and related options see
  51. :ref:`conf-result-backend`.
  52. That's all you need to get started!
  53. If you want to dig deeper there are lots of configuration possibilities that
  54. can be applied. For example you can set the default value for the workers
  55. `--concurrency`` argument, which is used to decide the number of pool worker
  56. processes, the name for this setting is :setting:`CELERYD_CONCURRENCY`:
  57. .. code-block:: python
  58. celery.conf.CELERY_CONCURRENCY = 10
  59. If you are configuring many settings then one practice is to have a separate module
  60. containing the configuration. You can tell your Celery instance to use
  61. this module, historically called ``celeryconfig.py``, with the
  62. :meth:`config_from_obj` method:
  63. .. code-block:: python
  64. celery.config_from_object("celeryconfig")
  65. For a complete reference of configuration options, see :ref:`configuration`.
  66. .. _celerytut-simple-tasks:
  67. Creating a simple task
  68. ======================
  69. In this tutorial we are creating a simple task that adds two
  70. numbers. Tasks are defined in normal Python modules.
  71. By convention we will call our module :file:`tasks.py`, and it looks
  72. like this:
  73. :file: `tasks.py`
  74. .. code-block:: python
  75. from worker import celery
  76. @celery.task
  77. def add(x, y):
  78. return x + y
  79. .. seealso::
  80. The full documentation on how to create tasks and task classes is in the
  81. :doc:`../userguide/tasks` part of the user guide.
  82. .. _celerytut-running-celeryd:
  83. Running the celery worker server
  84. ================================
  85. We can now run our ``worker.py`` program::
  86. $ python worker.py --loglevel=INFO
  87. In production you will probably want to run the worker in the
  88. background as a daemon. To do this you need to use the tools provided
  89. by your platform, or something like `supervisord`_ (see :ref:`daemonizing`
  90. for more information).
  91. For a complete listing of the command line options available, do::
  92. $ python worker.py --help
  93. .. _`supervisord`: http://supervisord.org
  94. .. _celerytut-executing-task:
  95. Executing the task
  96. ==================
  97. Whenever we want to execute our task, we use the
  98. :meth:`~celery.task.base.Task.delay` method of the task class.
  99. This is a handy shortcut to the :meth:`~celery.task.base.Task.apply_async`
  100. method which gives greater control of the task execution (see
  101. :ref:`guide-executing`).
  102. >>> from tasks import add
  103. >>> add.delay(4, 4)
  104. <AsyncResult: 889143a6-39a2-4e52-837b-d80d33efb22d>
  105. At this point, the task has been sent to the message broker. The message
  106. broker will hold on to the task until a worker server has consumed and
  107. executed it.
  108. Right now we have to check the worker log files to know what happened
  109. with the task. Applying a task returns an
  110. :class:`~celery.result.AsyncResult`, if you have configured a result store
  111. the :class:`~celery.result.AsyncResult` enables you to check the state of
  112. the task, wait for the task to finish, get its return value
  113. or exception/traceback if the task failed, and more.
  114. .. _celerytut-keeping-results:
  115. Keeping Results
  116. ---------------
  117. If you want to keep track of the tasks state, Celery needs to store or send
  118. the states somewhere. There are several
  119. built-in backends to choose from: SQLAlchemy/Django ORM, Memcached, Redis,
  120. AMQP, MongoDB, Tokyo Tyrant and Redis -- or you can define your own.
  121. For this example we will use the `amqp` result backend, which sends states
  122. as messages. The backend is configured via the :setting:`CELERY_RESULT_BACKEND`
  123. setting or using the ``backend`` argument to :class:`Celery`, in addition individual
  124. result backends may have additional settings
  125. you can configure::
  126. from celery.backends.amqp import AMQPBackend
  127. celery = Celery(backend=AMQPBackend(expires=300))
  128. To read more about result backends please see :ref:`task-result-backends`.
  129. Now with the result backend configured, let's execute the task again.
  130. This time we'll hold on to the :class:`~celery.result.AsyncResult`::
  131. >>> result = add.delay(4, 4)
  132. Here's some examples of what you can do when you have results::
  133. >>> result.ready() # returns True if the task has finished processing.
  134. False
  135. >>> result.result # task is not ready, so no return value yet.
  136. None
  137. >>> result.get() # Waits until the task is done and returns the retval.
  138. 8
  139. >>> result.result # direct access to result, doesn't re-raise errors.
  140. 8
  141. >>> result.successful() # returns True if the task didn't end in failure.
  142. True
  143. If the task raises an exception, the return value of `result.successful()`
  144. will be :const:`False`, and `result.result` will contain the exception instance
  145. raised by the task.
  146. Where to go from here
  147. =====================
  148. After this you should read the :ref:`guide`. Specifically
  149. :ref:`guide-tasks` and :ref:`guide-executing`.