Chain tasks together. Each tasks follows one another, by being applied as a callback of the previous task. Note: If called with only one argument, then that argument must be an iterable of tasks to chain: this allows us to use generator expressions. Example
| 1306 | |
| 1307 | |
| 1308 | class chain(_chain): |
| 1309 | """Chain tasks together. |
| 1310 | |
| 1311 | Each tasks follows one another, |
| 1312 | by being applied as a callback of the previous task. |
| 1313 | |
| 1314 | Note: |
| 1315 | If called with only one argument, then that argument must |
| 1316 | be an iterable of tasks to chain: this allows us |
| 1317 | to use generator expressions. |
| 1318 | |
| 1319 | Example: |
| 1320 | This is effectively :math:`((2 + 2) + 4)`: |
| 1321 | |
| 1322 | .. code-block:: pycon |
| 1323 | |
| 1324 | >>> res = chain(add.s(2, 2), add.s(4))() |
| 1325 | >>> res.get() |
| 1326 | 8 |
| 1327 | |
| 1328 | Calling a chain will return the result of the last task in the chain. |
| 1329 | You can get to the other tasks by following the ``result.parent``'s: |
| 1330 | |
| 1331 | .. code-block:: pycon |
| 1332 | |
| 1333 | >>> res.parent.get() |
| 1334 | 4 |
| 1335 | |
| 1336 | Using a generator expression: |
| 1337 | |
| 1338 | .. code-block:: pycon |
| 1339 | |
| 1340 | >>> lazy_chain = chain(add.s(i) for i in range(10)) |
| 1341 | >>> res = lazy_chain(3) |
| 1342 | |
| 1343 | Arguments: |
| 1344 | *tasks (Signature): List of task signatures to chain. |
| 1345 | If only one argument is passed and that argument is |
| 1346 | an iterable, then that'll be used as the list of signatures |
| 1347 | to chain instead. This means that you can use a generator |
| 1348 | expression. |
| 1349 | |
| 1350 | Returns: |
| 1351 | ~celery.chain: A lazy signature that can be called to apply the first |
| 1352 | task in the chain. When that task succeeds the next task in the |
| 1353 | chain is applied, and so on. |
| 1354 | """ |
| 1355 | |
| 1356 | # could be function, but must be able to reference as :class:`chain`. |
| 1357 | def __new__(cls, *tasks, **kwargs): |
| 1358 | # This forces `chain(X, Y, Z)` to work the same way as `X | Y | Z` |
| 1359 | if not kwargs and tasks: |
| 1360 | if len(tasks) != 1 or is_list(tasks[0]): |
| 1361 | tasks = tasks[0] if len(tasks) == 1 else tasks |
| 1362 | # if is_list(tasks) and len(tasks) == 1: |
| 1363 | # return super(chain, cls).__new__(cls, tasks, **kwargs) |
| 1364 | new_instance = reduce(operator.or_, tasks, _chain()) |
| 1365 | if cls != chain and isinstance(new_instance, _chain) and not isinstance(new_instance, cls): |
no outgoing calls
searching dependent graphs…