first-steps-with-only-celery.rst 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. ========================
  2. First steps with Celery
  3. ========================
  4. Creating a simple task
  5. ======================
  6. In this example we are creating a simple task that adds two
  7. numbers. Tasks are defined in a normal python module. The module can
  8. be named whatever you like, but the convention is to call it
  9. ``tasks.py``.
  10. Our addition task looks like this:
  11. ``tasks.py``:
  12. .. code-block:: python
  13. from celery.decorators import task
  14. @task
  15. def add(x, y):
  16. return x + y
  17. All celery tasks are classes that inherit from the ``Task``
  18. class. In this case we're using a decorator that wraps the add
  19. function in an appropriate class for us automatically. The full
  20. documentation on how to create tasks and task classes are in
  21. FIXMELINKHERE.
  22. Celery workers maintain a registry of all the available tasks. For it
  23. to be able to do this you need to give it a list of which modules it
  24. should import. FIXME: move this below?
  25. Configuration
  26. =============
  27. Celery is configured by using a configuration module. By convention,
  28. this module is called ``celeryconfig.py``. This module must be in the
  29. Python path so it can be imported.
  30. You can set a custom name for the configuration module with the
  31. ``CELERY_CONFIG_MODULE`` variable. In these examples we use the
  32. default name.
  33. Let's create our ``celeryconfig.py``.
  34. FIXME: Is the invocation below something people are expected to do,
  35. appending cwd to sys.path? It seems like something that would usually
  36. be handled elsewhere?
  37. 1. Start by making sure Python is able to import modules from the current
  38. directory::
  39. import os
  40. import sys
  41. sys.path.insert(0, os.getcwd())
  42. 2. Configure how we communicate with the broker::
  43. BROKER_HOST = "localhost"
  44. BROKER_PORT = 5672
  45. BROKER_USER = "myuser"
  46. BROKER_PASSWORD = "mypassword"
  47. BROKER_VHOST = "myvhost"
  48. 3. In this example we don't want to store the results of the tasks, so
  49. we'll use the simplest backend available; the AMQP backend::
  50. CELERY_BACKEND = "amqp"
  51. 4. Finally, we list the modules to import. We only have a single task
  52. module, ``tasks.py``, which we added earlier::
  53. CELERY_IMPORTS = ("tasks", )
  54. That's it.
  55. There are more options available, like how many processes you want to
  56. process work in parallel (the ``CELERY_CONCURRENCY`` setting), and we
  57. could use a persistent result store backend, but for now, this should
  58. do. For all of the options available, see the
  59. :doc:`configuration directive
  60. reference<../configuration>`.
  61. Running the celery worker server
  62. ================================
  63. To test we will run the worker server in the foreground, so we can
  64. see what's going on in the terminal::
  65. $ celeryd --loglevel=INFO
  66. However, in production you probably want to run the worker in the
  67. background as a daemon. To do this you need to use to tools provided
  68. by your platform, or something like `supervisord`_.
  69. For a complete listing of the command line options available, use the
  70. help command::
  71. $ celeryd --help
  72. FIXME: Move this to a FAQ section or something and link it from the
  73. supervisord line above:
  74. For example start-up scripts see ``contrib/debian/init.d`` for using
  75. ``start-stop-daemon`` on Debian/Ubuntu, or ``contrib/mac/org.celeryq.*`` for using
  76. ``launchd`` on Mac OS X.
  77. .. _`supervisord`: http://supervisord.org/
  78. Executing the task
  79. ==================
  80. Whenever we want to execute our task, we can use the ``delay`` method
  81. of the task class.
  82. This is a handy shortcut to the ``apply_async`` method which gives
  83. greater control of the task execution.
  84. See :doc:`Executing Tasks<../userguide/executing>` for more information.
  85. >>> from tasks import add
  86. >>> add.delay(4, 4)
  87. <AsyncResult: 889143a6-39a2-4e52-837b-d80d33efb22d>
  88. At this point, the task has been sent to the message broker. The message
  89. broker will hold on to the task until a celery worker server has successfully
  90. picked it up.
  91. *Note:* If everything is just hanging when you execute ``delay``, please check
  92. that RabbitMQ is running, and that the user/password has access to the virtual
  93. host you configured earlier.
  94. Right now we have to check the celery worker log files to know what happened
  95. with the task. This is because we didn't keep the ``AsyncResult`` object
  96. returned by ``delay``.
  97. The ``AsyncResult`` lets us find the state of the task, wait for the task to
  98. finish and get its return value (or exception if the task failed).
  99. So, let's execute the task again, but this time we'll keep track of the task:
  100. >>> result = add.delay(4, 4)
  101. >>> result.ready() # returns True if the task has finished processing.
  102. False
  103. >>> result.result # task is not ready, so no return value yet.
  104. None
  105. >>> result.get() # Waits until the task is done and returns the retval.
  106. 8
  107. >>> result.result # direct access to result, doesn't re-raise errors.
  108. 8
  109. >>> result.successful() # returns True if the task didn't end in failure.
  110. True
  111. If the task raises an exception, the return value of ``result.successful()``
  112. will be ``False``, and ``result.result`` will contain the exception instance
  113. raised by the task.
  114. That's all for now! After this you should probably read the :doc:`User
  115. Guide<../userguide/index>`.