Skip to content

Multithreaded backend#6416

Merged
auvipy merged 4 commits intocelery:masterfrom
matusvalo:multithreaded-backend
Nov 22, 2020
Merged

Multithreaded backend#6416
auvipy merged 4 commits intocelery:masterfrom
matusvalo:multithreaded-backend

Conversation

@matusvalo
Copy link
Member

@matusvalo matusvalo commented Oct 15, 2020

Description

This PR contains two changes:

  1. Storing backend to separate thread local variable to avoid sharing underlying Connection object between threads. This means that now each thread has it's own Backend object.
  2. Change oid (Universally unique identifier) to be thread-based. Moreover, the oid is now different for each thread. This is causing that each thread has it's own reply-to queue (Before all threads shares one reply-to queue which was causing missing responses)

This PR fixes #6414 and probably also issues linked to it.

@matusvalo matusvalo closed this Oct 15, 2020
@matusvalo matusvalo reopened this Oct 15, 2020
@matusvalo matusvalo marked this pull request as draft October 15, 2020 17:50
@matusvalo
Copy link
Member Author

@auvipy @thedrow This is just a PoC not final solution. I prefer to fix it more propery (maybe create new decorator e.g. @thread_cached_property). Moreover, unittests needs to be added.

I prefer also to verify it against the reporters of the bugs. @auvipy can you help me with that?

@lgtm-com
Copy link

lgtm-com bot commented Oct 15, 2020

This pull request introduces 1 alert when merging 54a4165 into 05da357 - view on LGTM.com

new alerts:

  • 1 for Module is imported with 'import' and 'import from'

@matusvalo
Copy link
Member Author

I have one question regarding oid() property:

oid() is Universally unique identifier of the App. It is part of API but, after grep it seems that in the Celery codebase is used only for defining reply-to identifier. Hence, we have to options:

  1. Make oid property thread dependent (as it is implemented in this PR). It means that each thread will see different identifier of the app. This is breaking API. Even, But I feel that this is confusing behavior of oid property because it is not unique identifier of App
  2. Create new thread dependent property e.g. thread_oid and port all internal oid calls to thread_oid. This will not break the API but in this case oid is not used anymore and not sure if someone is using it elsewhere.
  3. Or possible solution can be introducing thread_oid and deprecating oid. But still I feel that for reporting is good to have oid information present.

What do you think is the best approach?

@stadelmanma
Copy link

@matusvalo I get a deadlocks using this fix since my test script freezes for awhile and then does a few things, freezes again and get the familiar amqp.exceptions.UnexpectedFrame: Received 0x20 while expecting 0xce error occasionally when it's processing requests.

@matusvalo
Copy link
Member Author

@stadelmanma could you provide that script?

@matusvalo
Copy link
Member Author

@stadelmanma I missed that you were reporting on py-amqp related issue :-). Is that the failing script one provided in this comment: celery/py-amqp#330 (comment)? I have used this script for debugging and fixing the issue. Before this PR the testing script was failing with timeouts and Unexpectedframe error but using this PR it is able to work with gunicorn using following settings without any problem:

THREADS=4 #1  # keeping threads at one, see celery/issues/6335
WORKERS=${WORKERS:-2}

The only difference maybe from your setup can be that I am reaching RabbitMQ broker not in localhost (and hence with higher latency). But still this does not explain why it was failing before the fix and after ran with no issue on my setup.

@auvipy auvipy requested a review from maybe-sybr October 29, 2020 14:12
Copy link
Contributor

@maybe-sybr maybe-sybr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this change makes sense. I feel like there's probably a bunch of other places where we're unlikely to be thread-safe but this is a good place to start.

I think we could definitely stand to add a more clever @cached_thread_local_property decorator, like you mention. In theory that decorator could enforce that the methods it decorates belong to a class definition with some metaclass which can provide the actual thread local storage object. @auvipy, should we make an issue to track that on kombu? In the meantime, just changing it to be a property and not having setter/deleter support seems fine, but I think we'll need to fix up some tests which assume they can set app.backend and will get AttributeErrored when they try now - e.g. t/unit/tasks/test_chord.py::test_add_to_chord::test_add_to_chord() breaks at the moment.

{0}="proj.celeryconfig"
"""

tlocal = threading.local()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be moved to live in the Celery class instance so that it gets cleaned up by our fixtures during testing and there's no inter-app cross-talk.

mskogorevrmc
mskogorevrmc previously approved these changes Nov 2, 2020
Copy link

@mskogorevrmc mskogorevrmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry, I didn't think I have enough rights to make the approval of this pull request.

Consider my comment and approval useless.

@auvipy
Copy link
Member

auvipy commented Nov 2, 2020

any constructive review is OK

@matusvalo
Copy link
Member Author

matusvalo commented Nov 12, 2020

Hi @stadelmanma, I have double check it via your script and still seems that this PR fixes the issue (I reran the test using only your script with RabbitMQ borker in localhost using docker)

results from master branch

  • client app is failing:
$ python load-test.py
Sending requests |                                | 0/100Request failed: 500-INTERNAL SERVER ERROR
Sending requests |                                | 1/100Request failed: 500-INTERNAL SERVER ERROR
Sending requests |                                | 2/100^C
Process ForkPoolWorker-6:
Process ForkPoolWorker-7:
Process ForkPoolWorker-8:
Process ForkPoolWorker-3:
Process ForkPoolWorker-1:
Process ForkPoolWorker-4:
Process ForkPoolWorker-2:
Process ForkPoolWorker-5:
Traceback (most recent call last):
  File "/usr/lib/python3.8/multiprocessing/pool.py", line 851, in next
    item = self._items.popleft()
IndexError: pop from an empty deque

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "load-test.py", line 40, in <module>
    main()
  File "load-test.py", line 34, in main
    response_times = [t for t in bar.iter(response_times)]
  File "load-test.py", line 34, in <listcomp>
    response_times = [t for t in bar.iter(response_times)]
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/progress/__init__.py", line 175, in iter
    for x in it:
  File "/usr/lib/python3.8/multiprocessing/pool.py", line 856, in next
    self._cond.wait(timeout)
  File "/usr/lib/python3.8/threading.py", line 302, in wait
    waiter.acquire()
KeyboardInterrupt
  • gunicorn server is failing with expected exception from the bug:
[2020-11-11 09:31:36,940] ERROR in app: Exception on /query [POST]
Traceback (most recent call last):
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
    raise value
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/matus/dev/pyamq-330-repro/src/pyampq330/app.py", line 12, in query
    return r.get()
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/celery-5.0.2-py3.8.egg/celery/result.py", line 223, in get
    return self.backend.wait_for_pending(
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/celery-5.0.2-py3.8.egg/celery/backends/asynchronous.py", line 199, in wait_for_pending
    for _ in self._wait_for_pending(result, **kwargs):
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/celery-5.0.2-py3.8.egg/celery/backends/asynchronous.py", line 265, in _wait_for_pending
    for _ in self.drain_events_until(
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/celery-5.0.2-py3.8.egg/celery/backends/asynchronous.py", line 54, in drain_events_until
    yield self.wait_for(p, wait, timeout=interval)
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/celery-5.0.2-py3.8.egg/celery/backends/asynchronous.py", line 63, in wait_for
    wait(timeout=timeout)
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/celery-5.0.2-py3.8.egg/celery/backends/rpc.py", line 59, in drain_events
    return self._connection.drain_events(timeout=timeout)
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/kombu/connection.py", line 318, in drain_events
    return self.transport.drain_events(self.connection, **kwargs)
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/kombu/transport/pyamqp.py", line 101, in drain_events
    return connection.drain_events(**kwargs)
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/amqp/connection.py", line 522, in drain_events
    while not self.blocking_read(timeout):
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/amqp/connection.py", line 527, in blocking_read
    frame = self.transport.read_frame()
  File "/home/matus/dev/celery3.8/lib/python3.8/site-packages/amqp/transport.py", line 316, in read_frame
    raise UnexpectedFrame(
amqp.exceptions.UnexpectedFrame: Received frame_end 0x01 while expecting 0xce

When PR branch with fix is used no issues were present

  • Client application finished without problems:
$ python load-test.py
Sending requests |################################| 100/100
  • The gunicorn app logs no errors.

Can someone double check and confirm my observation. I would like to be 100% sure that PR is not breaking something and also is fixing the issue.

@lgtm-com
Copy link

lgtm-com bot commented Nov 18, 2020

This pull request fixes 2 alerts when merging 2b0af5b into 28ebcce - view on LGTM.com

fixed alerts:

  • 1 for Non-exception in 'except' clause
  • 1 for Module is imported with 'import' and 'import from'

@matusvalo matusvalo force-pushed the multithreaded-backend branch from 15f9e06 to f6ea14a Compare November 21, 2020 23:17
@lgtm-com
Copy link

lgtm-com bot commented Nov 21, 2020

This pull request fixes 2 alerts when merging f6ea14a into 60ba379 - view on LGTM.com

fixed alerts:

  • 1 for Non-exception in 'except' clause
  • 1 for Module is imported with 'import' and 'import from'

@matusvalo matusvalo force-pushed the multithreaded-backend branch from f6ea14a to 75c2517 Compare November 22, 2020 13:38
@lgtm-com
Copy link

lgtm-com bot commented Nov 22, 2020

This pull request fixes 1 alert when merging 75c2517 into 60ba379 - view on LGTM.com

fixed alerts:

  • 1 for Module is imported with 'import' and 'import from'

@matusvalo matusvalo force-pushed the multithreaded-backend branch from 75c2517 to 519c832 Compare November 22, 2020 14:08
@codecov
Copy link

codecov bot commented Nov 22, 2020

Codecov Report

Merging #6416 (519c832) into master (60ba379) will increase coverage by 0.00%.
The diff coverage is 76.47%.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #6416   +/-   ##
=======================================
  Coverage   75.49%   75.50%           
=======================================
  Files         138      138           
  Lines       16383    16396   +13     
  Branches     2059     2059           
=======================================
+ Hits        12369    12379   +10     
- Misses       3792     3795    +3     
  Partials      222      222           
Impacted Files Coverage Δ
celery/app/base.py 58.85% <73.33%> (+0.45%) ⬆️
celery/backends/rpc.py 57.62% <100.00%> (ø)
celery/canvas.py 93.35% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 60ba379...519c832. Read the comment docs.

@auvipy auvipy added this to the 5.0.3 milestone Nov 22, 2020
@auvipy auvipy marked this pull request as ready for review November 22, 2020 14:40
@flying-sheep
Copy link

flying-sheep commented Dec 6, 2020

There’s still deadlocks, this shouldn’t have been merged yet: #6521

@auvipy
Copy link
Member

auvipy commented Dec 6, 2020

There’s still deadlocks, this shouldn’t have been merged yet: #6521

you can help find out & a possible fix for the remaining part. as no software is 100% perfect

@flying-sheep
Copy link

flying-sheep commented Dec 6, 2020

I know how it is! 😄 doing my part by investigating and spreading awareness, as threaded code isn’t my strong suit. I think you’re correct that a change like this should have gotten more test coverage.

It’s a great feature, but touching a lot of sensitive code.

@alterEgo123
Copy link

I am getting the same issue on one worker, the others work just fine.
How could that be possible?

Using celery 5.0.4

      File "/usr/local/lib/python3.6/site-packages/celery/app/task.py", line 421, in delay
        return self.apply_async(args, kwargs)
    
      File "/usr/local/lib/python3.6/site-packages/celery/app/task.py", line 565, in apply_async
        **options
    
      File "/usr/local/lib/python3.6/site-packages/celery/app/base.py", line 748, in send_task
        self.backend.on_task_call(P, task_id)
    
      File "/usr/local/lib/python3.6/site-packages/celery/backends/rpc.py", line 164, in on_task_call
        maybe_declare(self.binding(producer.channel), retry=True)
    
      File "/usr/local/lib/python3.6/site-packages/kombu/common.py", line 118, in maybe_declare
        return _imaybe_declare(entity, channel, **retry_policy)
    
      File "/usr/local/lib/python3.6/site-packages/kombu/common.py", line 174, in _imaybe_declare
        entity, _maybe_declare, **retry_policy)(entity, channel)
    
      File "/usr/local/lib/python3.6/site-packages/kombu/connection.py", line 525, in _ensured
        return fun(*args, **kwargs)
    
      File "/usr/local/lib/python3.6/site-packages/kombu/common.py", line 159, in _maybe_declare
        entity.declare(channel=channel)
    
      File "/usr/local/lib/python3.6/site-packages/kombu/entity.py", line 606, in declare
        self._create_queue(nowait=nowait, channel=channel)
    
      File "/usr/local/lib/python3.6/site-packages/kombu/entity.py", line 615, in _create_queue
        self.queue_declare(nowait=nowait, passive=False, channel=channel)
    
      File "/usr/local/lib/python3.6/site-packages/kombu/entity.py", line 650, in queue_declare
        nowait=nowait,
    
      File "/usr/local/lib/python3.6/site-packages/amqp/channel.py", line 1147, in queue_declare
        spec.Queue.DeclareOk, returns_tuple=True,
    
      File "/usr/local/lib/python3.6/site-packages/amqp/abstract_channel.py", line 86, in wait
        self.connection.drain_events(timeout=timeout)
    
      File "/usr/local/lib/python3.6/site-packages/amqp/connection.py", line 522, in drain_events
        while not self.blocking_read(timeout):
    
      File "/usr/local/lib/python3.6/site-packages/amqp/connection.py", line 527, in blocking_read
        frame = self.transport.read_frame()
    
      File "/usr/local/lib/python3.6/site-packages/amqp/transport.py", line 317, in read_frame
        f'Received frame_end {frame_end:#04x} while expecting 0xce')

sihrc added a commit to IndicoDataSolutions/celery that referenced this pull request Dec 23, 2020
* Remove defaults for unsupported Python runtimes.

* Remove obsolete test.

* Doc pytest plugin (celery#6289)

* update to new pytest name

* doc pytest plugin

* trim heading to the length of the new pytest name

* add warning against use of sort key on dynamodb table, closes celery#6332

* Remove celery.five and bump vine dep (celery#6338)

* improv: Replace `five.values` with `dict.values`

* improv: Use `time.monotonic()` in kombu tests

Also in the docs where it is used to demonstrate `memcache` timeouts.

* rm: Delete `celery.five`

`vine.five` is no longer present in `vine >= 5`.

* triv: Remove refs to `celery.five` in docs, &c

* build: Bump `vine` dependency to 5.0+

* Wheels are no longer universal.

* Remove failing before_install step.

* Update changelog.

* Bump version: 5.0.0rc2 → 5.0.0rc3

* Fix release date.

* Remove unused import.

* Correctly skip these tests when the relevant dependency is missing.

* Expose retry_policy for Redis result backend

Rather than adding a new top-level config option, I have used a new key
in the already existing setting `result_backend_transport_options`.

Closes celery#6166

* Update changelog for 4.3.1.

* fix typo (celery#6346)

* Travis CI: Test Python 3.9 release candidate 1 (celery#6328)

* Travis CI: Test Python 3.9 release candidate 1

* fixup! Travis CI: matrix --> jobs

* fixup! Fix indentation error

* fixup! tox.ini: 3.9 --> 3.9-dev

* Fix test failure in Python 3.9RC1.

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Fix the broken celery upgrade settings command.

* Fix celery migrate settings options.

* Remove Riak result backend settings.

* Rephrase to mention that 3.5 is also EOL.

* Add a note about the removal of the Riak result backend.

* Fix examples of starting a worker in comments (celery#6331)

* Remove deprecated function from app.log.Logging.

* Migration guide.

* Document breaking changes for the CLI in the Whats New document.

* Add a "port code to Python 3" migration step.

* Update supported Python versions in the introduction document.

* Update bash completion.

* Add note about new shell completion.

* Update daemonization docs.

* Remove amqp backend. (celery#6360)

Fixes celery#6356.

* Warn when deprecated settings are used (celery#6353)

* Warn when deprecated settings are used.

* Mention deprecation in docs.

* Refer to the right place in the documentation.

* Complete What's New.

* Add wall of contributors.

* Update codename.

* Fix alt text.

* isort.

* PyPy 3.7 is currently in alpha.

No need for that sentence.

* Mention the new pytest-celery plugin.

* Mention retry policy for the redis result backend.

* Fix phrasing.

* Mention ordered group results are now the default.

* pyupgrade.

* Complete release notes.

* Bump version: 5.0.0rc3 → 5.0.0

* Happify linters.

* Specify utf-8 as the encoding for log files.

Fixes celery#5144.

* Fixed some typos in readme

* Fix custom headers propagation for protocol 1 hybrid messages

* Retry after race during schema creation in database backend (celery#6298)

* Retry after race during schema creation in database backend

Fixes celery#6296

This race condition does not commonly present, since the schema creation
only needs to happen once per database. It's more likely to appear in
e.g. a test suite that uses a new database each time.

For context of the sleep times I chose, the schema creation takes ~50 ms
on my laptop.

I did a simulated test run of 50 concurrent calls to MetaData.create_all
repeated 200 times and the number of retries was:

- 0 retries: 8717x
- 1 retry:   1279x
- 2 retries  4x

* Add test for prepare_models retry error condition

* Add name to contributors

* Update daemonizing.rst

Fix daemonizing documentation for issue celery#6363 to put `multi` before `-A`

* Revert "Update daemonizing.rst" (celery#6376)

This reverts commit 96ec6db.

* bugfix: when set config result_expires = 0, chord.get will hang. (celery#6373)

* bugfix: when set config result_expires = 0, chord.get will hang.

`EXPIRE key 0` will delete a key in redis, then chord will never get the
result.

fix: celery#5237

* test: add testcase for expire when set config with zero.

* Display a custom error message whenever an attempt to use -A or --app as a sub-command option was made.

Fixes celery#6363

* Remove test dependencies for Python 2.7.

* Restore the celery worker --without-{gossip,mingle,heartbeat} flags (celery#6365)

In the previously used argparse arguments framework, these three options were
used as flags.

Since 5.0.0, they are options which need to take an argument (whose only
sensible value would be "true"). The error message coming up is also (very)
hard to understand, when running the celery worker command with an odd number
of flags:

  Error: Unable to parse extra configuration from command line.
  Reason: not enough values to unpack (expected 2, got 1)

When the celery worker is run with an even number of flags, the last one is
considered as an argument of the previous one, which is a subtle bug.

* Provide clearer error messages when app fails to load.

* fix pytest plugin registration documentation (celery#6387)

* fix pytest plugin registration documentation

* Update docs/userguide/testing.rst

Co-authored-by: Thomas Grainger <tagrain@gmail.com>

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Contains a workaround for the capitalized configuration issue (celery#6385)

* Contains a workaround for the capitalized configuration issue

* Update celery/apps/worker.py

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Update celery/apps/worker.py

Co-authored-by: Omer Katz <omer.drow@gmail.com>

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Remove old explanation regarding `absolute_import` (celery#6390)

Resolves celery#6389.

* Update canvas.rst (celery#6392)

* Update canvas.rst

Tiny fixes.

* Update docs/userguide/canvas.rst

Co-authored-by: Omer Katz <omer.drow@gmail.com>

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Remove duplicate words from docs (celery#6398)

Remove the duplicate usage of “required” in documentation (specifically, `introduction.rst`).

* Allow lowercase log levels. (celery#6396)

Fixes celery#6395.

* Detach now correctly passes options with more than one word. (celery#6394)

When specifying options such as `-E` the detached worker should receive the `--task-events` option.
Instead it got the `--task_events` option which doesn't exist and therefore silently failed.

This fixes celery#6362.

* The celery multi command now works as expected. (celery#6388)

* Contains the missed change requested by @thedrow

* Added a some celery configuration examples.

* fixed loglevel info->INFO in docs

* return list instead set in CommaSeparatedList

_broadcast method of kombu Mailbox. does not support set
https://github.com/celery/kombu/blob/7b2578b19ba4b1989b722f6f6e7efee2a1a4d86a/kombu/pidbox.py#L319

* Rewrite detaching logic (celery#6401)

* Rewrite detaching logic.

* Ignore empty arguments.

* Ensure the SystemD services are up to date.

* fix: Pass back real result for single task chains

When chains are delayed, they are first frozen as part of preparation
which causes the sub-tasks to also be frozen. Afterward, the final (0th
since we reverse the tasks/result order when freezing) result object
from the freezing process would be passed back to the caller. This
caused problems in signaling completion of groups contained in chains
because the group relies on a promise which is fulfilled by a barrier
linked to each of its applied subtasks. By constructing two
`GroupResult` objects (one during freezing, one when the chain sub-tasks
are applied), this resulted in there being two promises; only one of
which would actually be fulfilled by the group subtasks.

This change ensures that in the special case where a chain has a single
task, we pass back the result object constructed when the task was
actually applied. When that single child is a group which does not get
unrolled (ie. contains more than one child itself), this ensures that we
pass back a `GroupResult` object which will actually be fulfilled. The
caller can then await the result confidently!

* fix: Retain `group_id` when tasks get re-frozen

When a group task which is part of a chain was to be delayed by
`trace_task()`, it would be reconstructed from the serialized request.
Normally, this sets the `group_id` of encapsulated tasks to the ID of
the group being instantiated. However, in the specific situation of a
group that is the last task in a chain which contributes to the
completion of a chord, it is essential that the group ID of the top-most
group is used instead. This top-most group ID is used by the redis
backend to track the completions of "final elements" of a chord in the
`on_chord_part_return()` implementation. By overwriting the group ID
which was already set in the `options` dictionaries of the child tasks
being deserialized, the chord accounting done by the redis backend would
be made inaccurate and chords would never complete.

This change alters how options are overridden for signatures to ensure
that if a `group_id` has already been set, it cannot be overridden.
Since group ID should be generally opaque to users, this should not be
disruptive.

* fix: Count chord "final elements" correctly

This change amends the implementation of `chord.__length_hint__()` to
ensure that all child task types are correctly counted. Specifically:

 * all sub-tasks of a group are counted recursively
 * the final task of a chain is counted recursively
 * the body of a chord is counted recursively
 * all other simple signatures count as a single "final element"

There is also a deserialisation step if a `dict` is seen while counting
the final elements in a chord, however this should become less important
with the merge of celery#6342 which ensures that tasks are recursively
deserialized by `.from_dict()`.

* test: Add more integration tests for groups

These tests are intended to show that group unrolling should be
respected in various ways by all backends. They should make it more
clear what behaviour we should be expecting from nested canvas
components and ensure that all the implementations (mostly relevant to
chords and `on_chord_part_return()` code) behave sensibly.

* test: Fix old markings for chord tests

* fix: Make KV-store backends respect chord size

This avoids an issue where the `on_chord_part_return()` implementation
would check the the length of the result of a chain ending in a nested
group. This would manifest in behaviour where a worker would be blocked
waiting for for the result object it holds to complete since it would
attempt to `.join()` the result object. In situations with plenty of
workers, this wouldn't really cause any noticable issue apart from some
latency or unpredictable failures - but in concurrency constrained
situations like the integrations tests, it causes deadlocks.

We know from previous commits in this series that chord completion is
more complex than just waiting for a direct child, so we correct the
`size` value in `BaseKeyValueStoreBackend.on_chord_part_return()` to
respect the `chord_size` value from the request, falling back to the
length of the `deps` if that value is missing for some reason (this is
necessary to keep a number of the tests happy but it's not clear to me
if that will ever be the case in real life situations).

* fix: Retain chord header result structure in Redis

This change fixes the chord result flattening issue which manifested
when using the Redis backend due to its deliberate throwing away of
information about the header result structure. Rather than assuming that
all results which contribute to the finalisation of a chord should be
siblings, this change checks if any are complex (ie. `GroupResult`s) and
falls back to behaviour similar to that implemented in the
`KeyValueStoreBackend` which restores the original `GroupResult` object
and `join()`s it.

We retain the original behaviour which is billed as an optimisation in
f09b041. We could behave better in the complex header result case by not
bothering to stash the results of contributing tasks under the `.j` zset
since we won't be using them, but without checking for the presence of
the complex group result on every `on_chord_part_return()` call, we
can't be sure that we won't need those stashed results later on. This
would be an opportunity for optimisation in future if we were to use an
`EVAL` to only do the `zadd()` if the group result key doesn't exist.
However, avoiding the result encoding work in `on_chord_part_return()`
would be more complicated. For now, it's not worth the brainpower.

This change also slightly refactors the redis backend unit tests to make
it easier to build fixtures and hit both the complex and simple result
structure cases.

* Update obsolete --loglevel argument values in docs

* Set logfile, not loglevel.

* Mention removed deprecated modules in the release notes.

Fixes celery#6406.

* Copy __annotations__ when creating tasks

This will allow getting type hints.

Fixes celery#6186.

* test: Improve chord body group index freezing test

Add more elements to the body so we can verify that the `group_index`
counts up from 0 as expected. This change adds the `pytest-subtests`
package as a test dependency so we can define partially independent
subtests within test functions.

* test: Use all() for subtask checks in canvas tests

When we expect all of the tasks in some iterable to meet a conditional,
we should make that clear by using `all(condition for ...)`.

* test: Add more tests for `from_dict()` variants

Notably, this exposed the bug tracked in celery#6341 where groups are not
deeply deserialized by `group.from_dict()`.

* fix: Ensure group tasks are deeply deserialised

Fixes celery#6341

* Fix `celery shell` command

* predefined_queues_urls -> predefined_queues

* Update changelog.

* Bump version: 5.0.0 → 5.0.1

* [Fix celery#6361] Fixing documentation for RabbitMQ task_queue_ha_policy

* Fix _autodiscover_tasks_from_fixups function

* fixup! Fix _autodiscover_tasks_from_fixups function

* Correct configuration item: CELERY_RESULT_EXPIRES

Related issue: celery#4050
celery#4050 (comment)

* Flush worker prints, notably the banner

In some cases (kubernetes, root) the banner is only printed at the
end of the process execution, instead of at the beginning.

* [Fix celery#6361] Remove RabbitMQ ha_policy from queue

* ci: Fix TOXENV for pypy3 unit tests

Fixes celery#6409

* ci: Move Python 3.9 test base from dev to release

* docs: fix celery beat settings

* move to travis-ci.com

* fix: Ensure default fairness maps to `SCHED_FAIR` (celery#6447)

Fixes celery#6386

* Preserve callbacks when replacing a task with a chain (celery#6189)

* Preserve callbacks when replacing a task with a chain.

* Preserve callbacks when replacing a task with a chain.

* Added tests.

* Update celery/app/task.py

Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>

* Mark test as flaky.

* Fix race condition in CI.

* fix: Run linked tasks in original slot for replace

This change alters the handling of linked tasks for chains which are
used as the argument to a `.replace()` call for a task which itself has
a chain of signatures to call once it completes. We ensure that the
linked callback is not only retained but also called at the appropiate
point in the newly reconstructed chain comprised of tasks from both the
replacement chain and the tail of the encapsulating chain of the task
being replaced.

We amend some tests to validate this behaviour better and ensure that
call/errbacks behave as expected if the encapsulating chain has either
set. One test is marked with an `xfail` since errbacks of encapsulating
chains are not currently called as expected due to some ambiguity in
when an errback of a replaced task should be dropped or not (celery#6441).

Co-authored-by: Asif Saif Uddin <auvipy@gmail.com>
Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>

* Fix minor documentation omission (celery#6453)

Co-authored-by: Lewis Kabui <lewisemm@users.noreply.github.com>

* Fix max_retries override on self.retry (celery#6436)

* Fix max_retries override

* Fix max_retries override

* Fix max_retries override

* Update exceptions.py

typo

* Update autoretry.py

typo

* Update task.py

Prevent exception unpacking for tasks without autoretry_for

* Update test_tasks.py

Unit test

* Update test_tasks.py

Added a new test

* Update autoretry.py

Fox for explicit raise in tasks

* Update test_tasks.py

* Update autoretry.py

* Update task.py

* Update exceptions.py

* Update task.py

* Happify linter.

* Raise proper error when replacing with an empty chain. (celery#6452)

Fixes celery#6451.

* Update changelog.

* Bump version: 5.0.1 → 5.0.2

* Update daemonizing.rst

Improved systemd documentation for auto-start of the service, and mention the possibility to depend on RabbitMQ service. Also add Restart=always for Celery Beat example

* Update celerybeat.service

* Fix old celery beat variables

Change made 5 days ago in 7c3da03 is faulty, the correct celery beat variables do start with `CELERYBEAT` and not `CELERY_BEAT`

* Fix formatting.

* Fix formatting.

* fix: Make `--workdir` eager for early handling (celery#6457)

This change makes the `--workdir` options an eager one which `click`
will process early for us, before any of the others. At the same time,
we add a callback which ensures that the `chdir()` is run during
handling of the argument so that all subsequent actions (e.g. app
loading) occur in the specified working directory.

Fixes celery#6445

* Fix example.

Fixes celery#6459.

* When using the MongoDB backend, don't cleanup if result_expires is 0 or None. (celery#6462)

Fixes celery#6450.

* Add missing space (celery#6468)

* Fix passing queues into purge command (celery#6469)

In current wersion calling `celery --app my.celery_app purge -Q queue_name` is failing with following trace:

```
    names = (queues or set(app.amqp.queues.keys())) - exclude_queues
TypeError: unsupported operand type(s) for -: 'list' and 'list'
```

Becouse code is expecting set and `queues` is actually a list.

Here is a fix.

* Change donations sidebar to direct users to OpenCollective.

* Added pytest to extras.

Missed in 9a6c292.

* Restore app.start() and app.worker_main() (celery#6481)

* Restore `app.start()` and `app.worker_main()`.

* Update celery/app/base.py

Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>

* Fix spelling error.

Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>

* fix: `node_format()` logfile before detaching

Fixes celery#6426

* Multithreaded backend (celery#6416)

* Cache backend to thread local storage instead of global variable

* Cache oid to thread local storage instead of global variable

* Improve code returning thread_local data

* Move thread local storage to Celery class, introduced thread_oid and added unittests

* Remove python2 compatibility code

* Restore ability to extend the CLI with new sub-commands.

* Adjust documentation to demonstrate how to introduce sub-command plugins in 5.x.

Fixes celery#6439.

* autopep8 & isort.

* Linters now run using Python 3.9.

* Fix apply_async() in Calling Tasks userguide

* Fix dead links in contributing guide (celery#6506)

* Fix inconsistency in documentation for `link_error` (celery#6505)

* Make documentation of link_error consistent

Fixes celery#4099

* Fix undefined variable in example

* Add to contributors list

* Update testing.rst (celery#6507)

Use double back ticks for some code examples, so that quotes don't get converted into smart-quotes.

celery#6497

* Don't upgrade click to 8.x since click-repl doesn't support it yet.

Fixes celery#6511.
Upstream issue: click-contrib/click-repl#72

* Update documentation on changes to custom CLI options in 5.0.

Fixes celery#6380.

* update step to install homebrew

* redis: Support Sentinel with SSL

Use the SentinelManagedSSLConnection when SSL is enabled for the
transport. The redis-py project doesn't have a connection class for
SSL+Sentinel yet. So, create a class in redis.py to add that
functionality.

* Revert "redis: Support Sentinel with SSL" (celery#6518)

This reverts commit 18a0963.

* Reintroduce support for custom preload options (celery#6516)

* Restore preload options.

Fixes celery#6307.

* Document breaking changes for preload options in 5.0.

Fixes celery#6379.

* Changelog for 5.0.3.

* Bump version: 5.0.2 → 5.0.3

* Added integration tests for calling a task (celery#6523)

* DummyClient of cache+memory:// backend now shares state between threads (celery#6524)

* isort.

* Update changelog.

* Bump version: 5.0.3 → 5.0.4

* Change deprecated from collections import Mapping/MutableMapping to from collections.abc ... (celery#6532)

* fix celery#6047

* Fix type error in S3 backend (celery#6537)

* Convert key from bytes to str

* Add unit test for S3 delete of key with type bytes

* events.py: Remove duplicate decorator in wrong place (celery#6543)

`@handle_preload_options` was specified twice as a decorator of `events`, once at the top (wrong) and once at the bottom (right).
This fixes the `celery events` commands and also `celery --help`

* Update changelog.

* Bump version: 5.0.4 → 5.0.5

* ADD: indico additions - trails

* FIX: remove dev.txt dependencies

* ADD: handle revoke failures

* ADD: trailer_request support and better drain resolution

* ADD: merge options was overriding link_error values

* PATCH: DLX and reject behaviour

* FIX: amqp dependencies

Co-authored-by: Omer Katz <omer.drow@gmail.com>
Co-authored-by: Thomas Grainger <tagrain@gmail.com>
Co-authored-by: Martin Paulus <mpaulus@lequest.com>
Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>
Co-authored-by: Ash Berlin-Taylor <ash_github@firemirror.com>
Co-authored-by: qiaocc <jasonqiao36@gmail.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Weiliang Li <to.be.impressive@gmail.com>
Co-authored-by: Akash Agrawal <akashrocksha@gmail.com>
Co-authored-by: Michal Kuffa <michal.kuffa@sentry.io>
Co-authored-by: Frazer McLean <frazer@frazermclean.co.uk>
Co-authored-by: Maarten Fonville <mfonville@users.noreply.github.com>
Co-authored-by: laixintao <laixintaoo@gmail.com>
Co-authored-by: Nicolas Dandrimont <nicolas@dandrimont.eu>
Co-authored-by: Bas ten Berge <bas+github@tenberge-ict.nl>
Co-authored-by: Zvi Baratz <z.baratz@gmail.com>
Co-authored-by: Justinas Petuchovas <justinas.petuchovas@gmail.com>
Co-authored-by: bastb <bas@tenberge-ict.nl>
Co-authored-by: Artem Bernatskyi <artem.bernatskyy@gmail.com>
Co-authored-by: ZubAnt <ya.zubarevanton@yandex.ru>
Co-authored-by: Lewis Kabui <lewisemm@users.noreply.github.com>
Co-authored-by: David Pärsson <david@parsson.se>
Co-authored-by: Anthony Lukach <anthonylukach@gmail.com>
Co-authored-by: Safwan Rahman <safwan.rahman15@gmail.com>
Co-authored-by: Stepan Henek <stepan@henek.name>
Co-authored-by: KexZh <hanbaobao2005@gmail.com>
Co-authored-by: Thomas Riccardi <thomas@deepomatic.com>
Co-authored-by: Egor Sergeevich Poderiagin <egor@crazyrussian.pro>
Co-authored-by: Asif Saif Uddin (Auvi) <auvipy@gmail.com>
Co-authored-by: Lewis M. Kabui <13940255+lewisemm@users.noreply.github.com>
Co-authored-by: Ixiodor <Ixiodor@users.noreply.github.com>
Co-authored-by: Mathieu Rollet <matletix@gmail.com>
Co-authored-by: Mike DePalatis <depalatis@gmail.com>
Co-authored-by: partizan <serg.partizan@gmail.com>
Co-authored-by: Nick Pope <nick.pope@flightdataservices.com>
Co-authored-by: Matus Valo <matusvalo@users.noreply.github.com>
Co-authored-by: Matus Valo <matusvalo@gmail.com>
Co-authored-by: henribru <6639509+henribru@users.noreply.github.com>
Co-authored-by: Stuart Axon <stuaxo2@yahoo.com>
Co-authored-by: Sonya Chhabra <sonyakc.2007@gmail.com>
Co-authored-by: AbdealiJK <abdealikothari@gmail.com>
Co-authored-by: František Zatloukal <Zatloukal.Frantisek@gmail.com>
Co-authored-by: elonzh <elonzh@qq.com>
Co-authored-by: Sven Koitka <razorx89@users.noreply.github.com>
Co-authored-by: Arnon Yaari <wiggin15@yahoo.com>
sihrc added a commit to IndicoDataSolutions/celery that referenced this pull request Feb 17, 2021
* Remove defaults for unsupported Python runtimes.

* Remove obsolete test.

* Doc pytest plugin (celery#6289)

* update to new pytest name

* doc pytest plugin

* trim heading to the length of the new pytest name

* add warning against use of sort key on dynamodb table, closes celery#6332

* Remove celery.five and bump vine dep (celery#6338)

* improv: Replace `five.values` with `dict.values`

* improv: Use `time.monotonic()` in kombu tests

Also in the docs where it is used to demonstrate `memcache` timeouts.

* rm: Delete `celery.five`

`vine.five` is no longer present in `vine >= 5`.

* triv: Remove refs to `celery.five` in docs, &c

* build: Bump `vine` dependency to 5.0+

* Wheels are no longer universal.

* Remove failing before_install step.

* Update changelog.

* Bump version: 5.0.0rc2 → 5.0.0rc3

* Fix release date.

* Remove unused import.

* Correctly skip these tests when the relevant dependency is missing.

* Expose retry_policy for Redis result backend

Rather than adding a new top-level config option, I have used a new key
in the already existing setting `result_backend_transport_options`.

Closes celery#6166

* Update changelog for 4.3.1.

* fix typo (celery#6346)

* Travis CI: Test Python 3.9 release candidate 1 (celery#6328)

* Travis CI: Test Python 3.9 release candidate 1

* fixup! Travis CI: matrix --> jobs

* fixup! Fix indentation error

* fixup! tox.ini: 3.9 --> 3.9-dev

* Fix test failure in Python 3.9RC1.

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Fix the broken celery upgrade settings command.

* Fix celery migrate settings options.

* Remove Riak result backend settings.

* Rephrase to mention that 3.5 is also EOL.

* Add a note about the removal of the Riak result backend.

* Fix examples of starting a worker in comments (celery#6331)

* Remove deprecated function from app.log.Logging.

* Migration guide.

* Document breaking changes for the CLI in the Whats New document.

* Add a "port code to Python 3" migration step.

* Update supported Python versions in the introduction document.

* Update bash completion.

* Add note about new shell completion.

* Update daemonization docs.

* Remove amqp backend. (celery#6360)

Fixes celery#6356.

* Warn when deprecated settings are used (celery#6353)

* Warn when deprecated settings are used.

* Mention deprecation in docs.

* Refer to the right place in the documentation.

* Complete What's New.

* Add wall of contributors.

* Update codename.

* Fix alt text.

* isort.

* PyPy 3.7 is currently in alpha.

No need for that sentence.

* Mention the new pytest-celery plugin.

* Mention retry policy for the redis result backend.

* Fix phrasing.

* Mention ordered group results are now the default.

* pyupgrade.

* Complete release notes.

* Bump version: 5.0.0rc3 → 5.0.0

* Happify linters.

* Specify utf-8 as the encoding for log files.

Fixes celery#5144.

* Fixed some typos in readme

* Fix custom headers propagation for protocol 1 hybrid messages

* Retry after race during schema creation in database backend (celery#6298)

* Retry after race during schema creation in database backend

Fixes celery#6296

This race condition does not commonly present, since the schema creation
only needs to happen once per database. It's more likely to appear in
e.g. a test suite that uses a new database each time.

For context of the sleep times I chose, the schema creation takes ~50 ms
on my laptop.

I did a simulated test run of 50 concurrent calls to MetaData.create_all
repeated 200 times and the number of retries was:

- 0 retries: 8717x
- 1 retry:   1279x
- 2 retries  4x

* Add test for prepare_models retry error condition

* Add name to contributors

* Update daemonizing.rst

Fix daemonizing documentation for issue celery#6363 to put `multi` before `-A`

* Revert "Update daemonizing.rst" (celery#6376)

This reverts commit 96ec6db.

* bugfix: when set config result_expires = 0, chord.get will hang. (celery#6373)

* bugfix: when set config result_expires = 0, chord.get will hang.

`EXPIRE key 0` will delete a key in redis, then chord will never get the
result.

fix: celery#5237

* test: add testcase for expire when set config with zero.

* Display a custom error message whenever an attempt to use -A or --app as a sub-command option was made.

Fixes celery#6363

* Remove test dependencies for Python 2.7.

* Restore the celery worker --without-{gossip,mingle,heartbeat} flags (celery#6365)

In the previously used argparse arguments framework, these three options were
used as flags.

Since 5.0.0, they are options which need to take an argument (whose only
sensible value would be "true"). The error message coming up is also (very)
hard to understand, when running the celery worker command with an odd number
of flags:

  Error: Unable to parse extra configuration from command line.
  Reason: not enough values to unpack (expected 2, got 1)

When the celery worker is run with an even number of flags, the last one is
considered as an argument of the previous one, which is a subtle bug.

* Provide clearer error messages when app fails to load.

* fix pytest plugin registration documentation (celery#6387)

* fix pytest plugin registration documentation

* Update docs/userguide/testing.rst

Co-authored-by: Thomas Grainger <tagrain@gmail.com>

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Contains a workaround for the capitalized configuration issue (celery#6385)

* Contains a workaround for the capitalized configuration issue

* Update celery/apps/worker.py

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Update celery/apps/worker.py

Co-authored-by: Omer Katz <omer.drow@gmail.com>

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Remove old explanation regarding `absolute_import` (celery#6390)

Resolves celery#6389.

* Update canvas.rst (celery#6392)

* Update canvas.rst

Tiny fixes.

* Update docs/userguide/canvas.rst

Co-authored-by: Omer Katz <omer.drow@gmail.com>

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Remove duplicate words from docs (celery#6398)

Remove the duplicate usage of “required” in documentation (specifically, `introduction.rst`).

* Allow lowercase log levels. (celery#6396)

Fixes celery#6395.

* Detach now correctly passes options with more than one word. (celery#6394)

When specifying options such as `-E` the detached worker should receive the `--task-events` option.
Instead it got the `--task_events` option which doesn't exist and therefore silently failed.

This fixes celery#6362.

* The celery multi command now works as expected. (celery#6388)

* Contains the missed change requested by @thedrow

* Added a some celery configuration examples.

* fixed loglevel info->INFO in docs

* return list instead set in CommaSeparatedList

_broadcast method of kombu Mailbox. does not support set
https://github.com/celery/kombu/blob/7b2578b19ba4b1989b722f6f6e7efee2a1a4d86a/kombu/pidbox.py#L319

* Rewrite detaching logic (celery#6401)

* Rewrite detaching logic.

* Ignore empty arguments.

* Ensure the SystemD services are up to date.

* fix: Pass back real result for single task chains

When chains are delayed, they are first frozen as part of preparation
which causes the sub-tasks to also be frozen. Afterward, the final (0th
since we reverse the tasks/result order when freezing) result object
from the freezing process would be passed back to the caller. This
caused problems in signaling completion of groups contained in chains
because the group relies on a promise which is fulfilled by a barrier
linked to each of its applied subtasks. By constructing two
`GroupResult` objects (one during freezing, one when the chain sub-tasks
are applied), this resulted in there being two promises; only one of
which would actually be fulfilled by the group subtasks.

This change ensures that in the special case where a chain has a single
task, we pass back the result object constructed when the task was
actually applied. When that single child is a group which does not get
unrolled (ie. contains more than one child itself), this ensures that we
pass back a `GroupResult` object which will actually be fulfilled. The
caller can then await the result confidently!

* fix: Retain `group_id` when tasks get re-frozen

When a group task which is part of a chain was to be delayed by
`trace_task()`, it would be reconstructed from the serialized request.
Normally, this sets the `group_id` of encapsulated tasks to the ID of
the group being instantiated. However, in the specific situation of a
group that is the last task in a chain which contributes to the
completion of a chord, it is essential that the group ID of the top-most
group is used instead. This top-most group ID is used by the redis
backend to track the completions of "final elements" of a chord in the
`on_chord_part_return()` implementation. By overwriting the group ID
which was already set in the `options` dictionaries of the child tasks
being deserialized, the chord accounting done by the redis backend would
be made inaccurate and chords would never complete.

This change alters how options are overridden for signatures to ensure
that if a `group_id` has already been set, it cannot be overridden.
Since group ID should be generally opaque to users, this should not be
disruptive.

* fix: Count chord "final elements" correctly

This change amends the implementation of `chord.__length_hint__()` to
ensure that all child task types are correctly counted. Specifically:

 * all sub-tasks of a group are counted recursively
 * the final task of a chain is counted recursively
 * the body of a chord is counted recursively
 * all other simple signatures count as a single "final element"

There is also a deserialisation step if a `dict` is seen while counting
the final elements in a chord, however this should become less important
with the merge of celery#6342 which ensures that tasks are recursively
deserialized by `.from_dict()`.

* test: Add more integration tests for groups

These tests are intended to show that group unrolling should be
respected in various ways by all backends. They should make it more
clear what behaviour we should be expecting from nested canvas
components and ensure that all the implementations (mostly relevant to
chords and `on_chord_part_return()` code) behave sensibly.

* test: Fix old markings for chord tests

* fix: Make KV-store backends respect chord size

This avoids an issue where the `on_chord_part_return()` implementation
would check the the length of the result of a chain ending in a nested
group. This would manifest in behaviour where a worker would be blocked
waiting for for the result object it holds to complete since it would
attempt to `.join()` the result object. In situations with plenty of
workers, this wouldn't really cause any noticable issue apart from some
latency or unpredictable failures - but in concurrency constrained
situations like the integrations tests, it causes deadlocks.

We know from previous commits in this series that chord completion is
more complex than just waiting for a direct child, so we correct the
`size` value in `BaseKeyValueStoreBackend.on_chord_part_return()` to
respect the `chord_size` value from the request, falling back to the
length of the `deps` if that value is missing for some reason (this is
necessary to keep a number of the tests happy but it's not clear to me
if that will ever be the case in real life situations).

* fix: Retain chord header result structure in Redis

This change fixes the chord result flattening issue which manifested
when using the Redis backend due to its deliberate throwing away of
information about the header result structure. Rather than assuming that
all results which contribute to the finalisation of a chord should be
siblings, this change checks if any are complex (ie. `GroupResult`s) and
falls back to behaviour similar to that implemented in the
`KeyValueStoreBackend` which restores the original `GroupResult` object
and `join()`s it.

We retain the original behaviour which is billed as an optimisation in
f09b041. We could behave better in the complex header result case by not
bothering to stash the results of contributing tasks under the `.j` zset
since we won't be using them, but without checking for the presence of
the complex group result on every `on_chord_part_return()` call, we
can't be sure that we won't need those stashed results later on. This
would be an opportunity for optimisation in future if we were to use an
`EVAL` to only do the `zadd()` if the group result key doesn't exist.
However, avoiding the result encoding work in `on_chord_part_return()`
would be more complicated. For now, it's not worth the brainpower.

This change also slightly refactors the redis backend unit tests to make
it easier to build fixtures and hit both the complex and simple result
structure cases.

* Update obsolete --loglevel argument values in docs

* Set logfile, not loglevel.

* Mention removed deprecated modules in the release notes.

Fixes celery#6406.

* Copy __annotations__ when creating tasks

This will allow getting type hints.

Fixes celery#6186.

* test: Improve chord body group index freezing test

Add more elements to the body so we can verify that the `group_index`
counts up from 0 as expected. This change adds the `pytest-subtests`
package as a test dependency so we can define partially independent
subtests within test functions.

* test: Use all() for subtask checks in canvas tests

When we expect all of the tasks in some iterable to meet a conditional,
we should make that clear by using `all(condition for ...)`.

* test: Add more tests for `from_dict()` variants

Notably, this exposed the bug tracked in celery#6341 where groups are not
deeply deserialized by `group.from_dict()`.

* fix: Ensure group tasks are deeply deserialised

Fixes celery#6341

* Fix `celery shell` command

* predefined_queues_urls -> predefined_queues

* Update changelog.

* Bump version: 5.0.0 → 5.0.1

* [Fix celery#6361] Fixing documentation for RabbitMQ task_queue_ha_policy

* Fix _autodiscover_tasks_from_fixups function

* fixup! Fix _autodiscover_tasks_from_fixups function

* Correct configuration item: CELERY_RESULT_EXPIRES

Related issue: celery#4050
celery#4050 (comment)

* Flush worker prints, notably the banner

In some cases (kubernetes, root) the banner is only printed at the
end of the process execution, instead of at the beginning.

* [Fix celery#6361] Remove RabbitMQ ha_policy from queue

* ci: Fix TOXENV for pypy3 unit tests

Fixes celery#6409

* ci: Move Python 3.9 test base from dev to release

* docs: fix celery beat settings

* move to travis-ci.com

* fix: Ensure default fairness maps to `SCHED_FAIR` (celery#6447)

Fixes celery#6386

* Preserve callbacks when replacing a task with a chain (celery#6189)

* Preserve callbacks when replacing a task with a chain.

* Preserve callbacks when replacing a task with a chain.

* Added tests.

* Update celery/app/task.py

Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>

* Mark test as flaky.

* Fix race condition in CI.

* fix: Run linked tasks in original slot for replace

This change alters the handling of linked tasks for chains which are
used as the argument to a `.replace()` call for a task which itself has
a chain of signatures to call once it completes. We ensure that the
linked callback is not only retained but also called at the appropiate
point in the newly reconstructed chain comprised of tasks from both the
replacement chain and the tail of the encapsulating chain of the task
being replaced.

We amend some tests to validate this behaviour better and ensure that
call/errbacks behave as expected if the encapsulating chain has either
set. One test is marked with an `xfail` since errbacks of encapsulating
chains are not currently called as expected due to some ambiguity in
when an errback of a replaced task should be dropped or not (celery#6441).

Co-authored-by: Asif Saif Uddin <auvipy@gmail.com>
Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>

* Fix minor documentation omission (celery#6453)

Co-authored-by: Lewis Kabui <lewisemm@users.noreply.github.com>

* Fix max_retries override on self.retry (celery#6436)

* Fix max_retries override

* Fix max_retries override

* Fix max_retries override

* Update exceptions.py

typo

* Update autoretry.py

typo

* Update task.py

Prevent exception unpacking for tasks without autoretry_for

* Update test_tasks.py

Unit test

* Update test_tasks.py

Added a new test

* Update autoretry.py

Fox for explicit raise in tasks

* Update test_tasks.py

* Update autoretry.py

* Update task.py

* Update exceptions.py

* Update task.py

* Happify linter.

* Raise proper error when replacing with an empty chain. (celery#6452)

Fixes celery#6451.

* Update changelog.

* Bump version: 5.0.1 → 5.0.2

* Update daemonizing.rst

Improved systemd documentation for auto-start of the service, and mention the possibility to depend on RabbitMQ service. Also add Restart=always for Celery Beat example

* Update celerybeat.service

* Fix old celery beat variables

Change made 5 days ago in 7c3da03 is faulty, the correct celery beat variables do start with `CELERYBEAT` and not `CELERY_BEAT`

* Fix formatting.

* Fix formatting.

* fix: Make `--workdir` eager for early handling (celery#6457)

This change makes the `--workdir` options an eager one which `click`
will process early for us, before any of the others. At the same time,
we add a callback which ensures that the `chdir()` is run during
handling of the argument so that all subsequent actions (e.g. app
loading) occur in the specified working directory.

Fixes celery#6445

* Fix example.

Fixes celery#6459.

* When using the MongoDB backend, don't cleanup if result_expires is 0 or None. (celery#6462)

Fixes celery#6450.

* Add missing space (celery#6468)

* Fix passing queues into purge command (celery#6469)

In current wersion calling `celery --app my.celery_app purge -Q queue_name` is failing with following trace:

```
    names = (queues or set(app.amqp.queues.keys())) - exclude_queues
TypeError: unsupported operand type(s) for -: 'list' and 'list'
```

Becouse code is expecting set and `queues` is actually a list.

Here is a fix.

* Change donations sidebar to direct users to OpenCollective.

* Added pytest to extras.

Missed in 9a6c292.

* Restore app.start() and app.worker_main() (celery#6481)

* Restore `app.start()` and `app.worker_main()`.

* Update celery/app/base.py

Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>

* Fix spelling error.

Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>

* fix: `node_format()` logfile before detaching

Fixes celery#6426

* Multithreaded backend (celery#6416)

* Cache backend to thread local storage instead of global variable

* Cache oid to thread local storage instead of global variable

* Improve code returning thread_local data

* Move thread local storage to Celery class, introduced thread_oid and added unittests

* Remove python2 compatibility code

* Restore ability to extend the CLI with new sub-commands.

* Adjust documentation to demonstrate how to introduce sub-command plugins in 5.x.

Fixes celery#6439.

* autopep8 & isort.

* Linters now run using Python 3.9.

* Fix apply_async() in Calling Tasks userguide

* Fix dead links in contributing guide (celery#6506)

* Fix inconsistency in documentation for `link_error` (celery#6505)

* Make documentation of link_error consistent

Fixes celery#4099

* Fix undefined variable in example

* Add to contributors list

* Update testing.rst (celery#6507)

Use double back ticks for some code examples, so that quotes don't get converted into smart-quotes.

celery#6497

* Don't upgrade click to 8.x since click-repl doesn't support it yet.

Fixes celery#6511.
Upstream issue: click-contrib/click-repl#72

* Update documentation on changes to custom CLI options in 5.0.

Fixes celery#6380.

* update step to install homebrew

* redis: Support Sentinel with SSL

Use the SentinelManagedSSLConnection when SSL is enabled for the
transport. The redis-py project doesn't have a connection class for
SSL+Sentinel yet. So, create a class in redis.py to add that
functionality.

* Revert "redis: Support Sentinel with SSL" (celery#6518)

This reverts commit 18a0963.

* Reintroduce support for custom preload options (celery#6516)

* Restore preload options.

Fixes celery#6307.

* Document breaking changes for preload options in 5.0.

Fixes celery#6379.

* Changelog for 5.0.3.

* Bump version: 5.0.2 → 5.0.3

* Added integration tests for calling a task (celery#6523)

* DummyClient of cache+memory:// backend now shares state between threads (celery#6524)

* isort.

* Update changelog.

* Bump version: 5.0.3 → 5.0.4

* Change deprecated from collections import Mapping/MutableMapping to from collections.abc ... (celery#6532)

* fix celery#6047

* Fix type error in S3 backend (celery#6537)

* Convert key from bytes to str

* Add unit test for S3 delete of key with type bytes

* events.py: Remove duplicate decorator in wrong place (celery#6543)

`@handle_preload_options` was specified twice as a decorator of `events`, once at the top (wrong) and once at the bottom (right).
This fixes the `celery events` commands and also `celery --help`

* Update changelog.

* Bump version: 5.0.4 → 5.0.5

* ADD: indico additions - trails

* FIX: remove dev.txt dependencies

* ADD: handle revoke failures

* ADD: trailer_request support and better drain resolution

* ADD: merge options was overriding link_error values

* PATCH: DLX and reject behaviour

* FIX: amqp dependencies

Co-authored-by: Omer Katz <omer.drow@gmail.com>
Co-authored-by: Thomas Grainger <tagrain@gmail.com>
Co-authored-by: Martin Paulus <mpaulus@lequest.com>
Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>
Co-authored-by: Ash Berlin-Taylor <ash_github@firemirror.com>
Co-authored-by: qiaocc <jasonqiao36@gmail.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Weiliang Li <to.be.impressive@gmail.com>
Co-authored-by: Akash Agrawal <akashrocksha@gmail.com>
Co-authored-by: Michal Kuffa <michal.kuffa@sentry.io>
Co-authored-by: Frazer McLean <frazer@frazermclean.co.uk>
Co-authored-by: Maarten Fonville <mfonville@users.noreply.github.com>
Co-authored-by: laixintao <laixintaoo@gmail.com>
Co-authored-by: Nicolas Dandrimont <nicolas@dandrimont.eu>
Co-authored-by: Bas ten Berge <bas+github@tenberge-ict.nl>
Co-authored-by: Zvi Baratz <z.baratz@gmail.com>
Co-authored-by: Justinas Petuchovas <justinas.petuchovas@gmail.com>
Co-authored-by: bastb <bas@tenberge-ict.nl>
Co-authored-by: Artem Bernatskyi <artem.bernatskyy@gmail.com>
Co-authored-by: ZubAnt <ya.zubarevanton@yandex.ru>
Co-authored-by: Lewis Kabui <lewisemm@users.noreply.github.com>
Co-authored-by: David Pärsson <david@parsson.se>
Co-authored-by: Anthony Lukach <anthonylukach@gmail.com>
Co-authored-by: Safwan Rahman <safwan.rahman15@gmail.com>
Co-authored-by: Stepan Henek <stepan@henek.name>
Co-authored-by: KexZh <hanbaobao2005@gmail.com>
Co-authored-by: Thomas Riccardi <thomas@deepomatic.com>
Co-authored-by: Egor Sergeevich Poderiagin <egor@crazyrussian.pro>
Co-authored-by: Asif Saif Uddin (Auvi) <auvipy@gmail.com>
Co-authored-by: Lewis M. Kabui <13940255+lewisemm@users.noreply.github.com>
Co-authored-by: Ixiodor <Ixiodor@users.noreply.github.com>
Co-authored-by: Mathieu Rollet <matletix@gmail.com>
Co-authored-by: Mike DePalatis <depalatis@gmail.com>
Co-authored-by: partizan <serg.partizan@gmail.com>
Co-authored-by: Nick Pope <nick.pope@flightdataservices.com>
Co-authored-by: Matus Valo <matusvalo@users.noreply.github.com>
Co-authored-by: Matus Valo <matusvalo@gmail.com>
Co-authored-by: henribru <6639509+henribru@users.noreply.github.com>
Co-authored-by: Stuart Axon <stuaxo2@yahoo.com>
Co-authored-by: Sonya Chhabra <sonyakc.2007@gmail.com>
Co-authored-by: AbdealiJK <abdealikothari@gmail.com>
Co-authored-by: František Zatloukal <Zatloukal.Frantisek@gmail.com>
Co-authored-by: elonzh <elonzh@qq.com>
Co-authored-by: Sven Koitka <razorx89@users.noreply.github.com>
Co-authored-by: Arnon Yaari <wiggin15@yahoo.com>
sihrc added a commit to IndicoDataSolutions/celery that referenced this pull request Feb 23, 2021
* Remove defaults for unsupported Python runtimes.

* Remove obsolete test.

* Doc pytest plugin (celery#6289)

* update to new pytest name

* doc pytest plugin

* trim heading to the length of the new pytest name

* add warning against use of sort key on dynamodb table, closes celery#6332

* Remove celery.five and bump vine dep (celery#6338)

* improv: Replace `five.values` with `dict.values`

* improv: Use `time.monotonic()` in kombu tests

Also in the docs where it is used to demonstrate `memcache` timeouts.

* rm: Delete `celery.five`

`vine.five` is no longer present in `vine >= 5`.

* triv: Remove refs to `celery.five` in docs, &c

* build: Bump `vine` dependency to 5.0+

* Wheels are no longer universal.

* Remove failing before_install step.

* Update changelog.

* Bump version: 5.0.0rc2 → 5.0.0rc3

* Fix release date.

* Remove unused import.

* Correctly skip these tests when the relevant dependency is missing.

* Expose retry_policy for Redis result backend

Rather than adding a new top-level config option, I have used a new key
in the already existing setting `result_backend_transport_options`.

Closes celery#6166

* Update changelog for 4.3.1.

* fix typo (celery#6346)

* Travis CI: Test Python 3.9 release candidate 1 (celery#6328)

* Travis CI: Test Python 3.9 release candidate 1

* fixup! Travis CI: matrix --> jobs

* fixup! Fix indentation error

* fixup! tox.ini: 3.9 --> 3.9-dev

* Fix test failure in Python 3.9RC1.

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Fix the broken celery upgrade settings command.

* Fix celery migrate settings options.

* Remove Riak result backend settings.

* Rephrase to mention that 3.5 is also EOL.

* Add a note about the removal of the Riak result backend.

* Fix examples of starting a worker in comments (celery#6331)

* Remove deprecated function from app.log.Logging.

* Migration guide.

* Document breaking changes for the CLI in the Whats New document.

* Add a "port code to Python 3" migration step.

* Update supported Python versions in the introduction document.

* Update bash completion.

* Add note about new shell completion.

* Update daemonization docs.

* Remove amqp backend. (celery#6360)

Fixes celery#6356.

* Warn when deprecated settings are used (celery#6353)

* Warn when deprecated settings are used.

* Mention deprecation in docs.

* Refer to the right place in the documentation.

* Complete What's New.

* Add wall of contributors.

* Update codename.

* Fix alt text.

* isort.

* PyPy 3.7 is currently in alpha.

No need for that sentence.

* Mention the new pytest-celery plugin.

* Mention retry policy for the redis result backend.

* Fix phrasing.

* Mention ordered group results are now the default.

* pyupgrade.

* Complete release notes.

* Bump version: 5.0.0rc3 → 5.0.0

* Happify linters.

* Specify utf-8 as the encoding for log files.

Fixes celery#5144.

* Fixed some typos in readme

* Fix custom headers propagation for protocol 1 hybrid messages

* Retry after race during schema creation in database backend (celery#6298)

* Retry after race during schema creation in database backend

Fixes celery#6296

This race condition does not commonly present, since the schema creation
only needs to happen once per database. It's more likely to appear in
e.g. a test suite that uses a new database each time.

For context of the sleep times I chose, the schema creation takes ~50 ms
on my laptop.

I did a simulated test run of 50 concurrent calls to MetaData.create_all
repeated 200 times and the number of retries was:

- 0 retries: 8717x
- 1 retry:   1279x
- 2 retries  4x

* Add test for prepare_models retry error condition

* Add name to contributors

* Update daemonizing.rst

Fix daemonizing documentation for issue celery#6363 to put `multi` before `-A`

* Revert "Update daemonizing.rst" (celery#6376)

This reverts commit 96ec6db.

* bugfix: when set config result_expires = 0, chord.get will hang. (celery#6373)

* bugfix: when set config result_expires = 0, chord.get will hang.

`EXPIRE key 0` will delete a key in redis, then chord will never get the
result.

fix: celery#5237

* test: add testcase for expire when set config with zero.

* Display a custom error message whenever an attempt to use -A or --app as a sub-command option was made.

Fixes celery#6363

* Remove test dependencies for Python 2.7.

* Restore the celery worker --without-{gossip,mingle,heartbeat} flags (celery#6365)

In the previously used argparse arguments framework, these three options were
used as flags.

Since 5.0.0, they are options which need to take an argument (whose only
sensible value would be "true"). The error message coming up is also (very)
hard to understand, when running the celery worker command with an odd number
of flags:

  Error: Unable to parse extra configuration from command line.
  Reason: not enough values to unpack (expected 2, got 1)

When the celery worker is run with an even number of flags, the last one is
considered as an argument of the previous one, which is a subtle bug.

* Provide clearer error messages when app fails to load.

* fix pytest plugin registration documentation (celery#6387)

* fix pytest plugin registration documentation

* Update docs/userguide/testing.rst

Co-authored-by: Thomas Grainger <tagrain@gmail.com>

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Contains a workaround for the capitalized configuration issue (celery#6385)

* Contains a workaround for the capitalized configuration issue

* Update celery/apps/worker.py

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Update celery/apps/worker.py

Co-authored-by: Omer Katz <omer.drow@gmail.com>

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Remove old explanation regarding `absolute_import` (celery#6390)

Resolves celery#6389.

* Update canvas.rst (celery#6392)

* Update canvas.rst

Tiny fixes.

* Update docs/userguide/canvas.rst

Co-authored-by: Omer Katz <omer.drow@gmail.com>

Co-authored-by: Omer Katz <omer.drow@gmail.com>

* Remove duplicate words from docs (celery#6398)

Remove the duplicate usage of “required” in documentation (specifically, `introduction.rst`).

* Allow lowercase log levels. (celery#6396)

Fixes celery#6395.

* Detach now correctly passes options with more than one word. (celery#6394)

When specifying options such as `-E` the detached worker should receive the `--task-events` option.
Instead it got the `--task_events` option which doesn't exist and therefore silently failed.

This fixes celery#6362.

* The celery multi command now works as expected. (celery#6388)

* Contains the missed change requested by @thedrow

* Added a some celery configuration examples.

* fixed loglevel info->INFO in docs

* return list instead set in CommaSeparatedList

_broadcast method of kombu Mailbox. does not support set
https://github.com/celery/kombu/blob/7b2578b19ba4b1989b722f6f6e7efee2a1a4d86a/kombu/pidbox.py#L319

* Rewrite detaching logic (celery#6401)

* Rewrite detaching logic.

* Ignore empty arguments.

* Ensure the SystemD services are up to date.

* fix: Pass back real result for single task chains

When chains are delayed, they are first frozen as part of preparation
which causes the sub-tasks to also be frozen. Afterward, the final (0th
since we reverse the tasks/result order when freezing) result object
from the freezing process would be passed back to the caller. This
caused problems in signaling completion of groups contained in chains
because the group relies on a promise which is fulfilled by a barrier
linked to each of its applied subtasks. By constructing two
`GroupResult` objects (one during freezing, one when the chain sub-tasks
are applied), this resulted in there being two promises; only one of
which would actually be fulfilled by the group subtasks.

This change ensures that in the special case where a chain has a single
task, we pass back the result object constructed when the task was
actually applied. When that single child is a group which does not get
unrolled (ie. contains more than one child itself), this ensures that we
pass back a `GroupResult` object which will actually be fulfilled. The
caller can then await the result confidently!

* fix: Retain `group_id` when tasks get re-frozen

When a group task which is part of a chain was to be delayed by
`trace_task()`, it would be reconstructed from the serialized request.
Normally, this sets the `group_id` of encapsulated tasks to the ID of
the group being instantiated. However, in the specific situation of a
group that is the last task in a chain which contributes to the
completion of a chord, it is essential that the group ID of the top-most
group is used instead. This top-most group ID is used by the redis
backend to track the completions of "final elements" of a chord in the
`on_chord_part_return()` implementation. By overwriting the group ID
which was already set in the `options` dictionaries of the child tasks
being deserialized, the chord accounting done by the redis backend would
be made inaccurate and chords would never complete.

This change alters how options are overridden for signatures to ensure
that if a `group_id` has already been set, it cannot be overridden.
Since group ID should be generally opaque to users, this should not be
disruptive.

* fix: Count chord "final elements" correctly

This change amends the implementation of `chord.__length_hint__()` to
ensure that all child task types are correctly counted. Specifically:

 * all sub-tasks of a group are counted recursively
 * the final task of a chain is counted recursively
 * the body of a chord is counted recursively
 * all other simple signatures count as a single "final element"

There is also a deserialisation step if a `dict` is seen while counting
the final elements in a chord, however this should become less important
with the merge of celery#6342 which ensures that tasks are recursively
deserialized by `.from_dict()`.

* test: Add more integration tests for groups

These tests are intended to show that group unrolling should be
respected in various ways by all backends. They should make it more
clear what behaviour we should be expecting from nested canvas
components and ensure that all the implementations (mostly relevant to
chords and `on_chord_part_return()` code) behave sensibly.

* test: Fix old markings for chord tests

* fix: Make KV-store backends respect chord size

This avoids an issue where the `on_chord_part_return()` implementation
would check the the length of the result of a chain ending in a nested
group. This would manifest in behaviour where a worker would be blocked
waiting for for the result object it holds to complete since it would
attempt to `.join()` the result object. In situations with plenty of
workers, this wouldn't really cause any noticable issue apart from some
latency or unpredictable failures - but in concurrency constrained
situations like the integrations tests, it causes deadlocks.

We know from previous commits in this series that chord completion is
more complex than just waiting for a direct child, so we correct the
`size` value in `BaseKeyValueStoreBackend.on_chord_part_return()` to
respect the `chord_size` value from the request, falling back to the
length of the `deps` if that value is missing for some reason (this is
necessary to keep a number of the tests happy but it's not clear to me
if that will ever be the case in real life situations).

* fix: Retain chord header result structure in Redis

This change fixes the chord result flattening issue which manifested
when using the Redis backend due to its deliberate throwing away of
information about the header result structure. Rather than assuming that
all results which contribute to the finalisation of a chord should be
siblings, this change checks if any are complex (ie. `GroupResult`s) and
falls back to behaviour similar to that implemented in the
`KeyValueStoreBackend` which restores the original `GroupResult` object
and `join()`s it.

We retain the original behaviour which is billed as an optimisation in
f09b041. We could behave better in the complex header result case by not
bothering to stash the results of contributing tasks under the `.j` zset
since we won't be using them, but without checking for the presence of
the complex group result on every `on_chord_part_return()` call, we
can't be sure that we won't need those stashed results later on. This
would be an opportunity for optimisation in future if we were to use an
`EVAL` to only do the `zadd()` if the group result key doesn't exist.
However, avoiding the result encoding work in `on_chord_part_return()`
would be more complicated. For now, it's not worth the brainpower.

This change also slightly refactors the redis backend unit tests to make
it easier to build fixtures and hit both the complex and simple result
structure cases.

* Update obsolete --loglevel argument values in docs

* Set logfile, not loglevel.

* Mention removed deprecated modules in the release notes.

Fixes celery#6406.

* Copy __annotations__ when creating tasks

This will allow getting type hints.

Fixes celery#6186.

* test: Improve chord body group index freezing test

Add more elements to the body so we can verify that the `group_index`
counts up from 0 as expected. This change adds the `pytest-subtests`
package as a test dependency so we can define partially independent
subtests within test functions.

* test: Use all() for subtask checks in canvas tests

When we expect all of the tasks in some iterable to meet a conditional,
we should make that clear by using `all(condition for ...)`.

* test: Add more tests for `from_dict()` variants

Notably, this exposed the bug tracked in celery#6341 where groups are not
deeply deserialized by `group.from_dict()`.

* fix: Ensure group tasks are deeply deserialised

Fixes celery#6341

* Fix `celery shell` command

* predefined_queues_urls -> predefined_queues

* Update changelog.

* Bump version: 5.0.0 → 5.0.1

* [Fix celery#6361] Fixing documentation for RabbitMQ task_queue_ha_policy

* Fix _autodiscover_tasks_from_fixups function

* fixup! Fix _autodiscover_tasks_from_fixups function

* Correct configuration item: CELERY_RESULT_EXPIRES

Related issue: celery#4050
celery#4050 (comment)

* Flush worker prints, notably the banner

In some cases (kubernetes, root) the banner is only printed at the
end of the process execution, instead of at the beginning.

* [Fix celery#6361] Remove RabbitMQ ha_policy from queue

* ci: Fix TOXENV for pypy3 unit tests

Fixes celery#6409

* ci: Move Python 3.9 test base from dev to release

* docs: fix celery beat settings

* move to travis-ci.com

* fix: Ensure default fairness maps to `SCHED_FAIR` (celery#6447)

Fixes celery#6386

* Preserve callbacks when replacing a task with a chain (celery#6189)

* Preserve callbacks when replacing a task with a chain.

* Preserve callbacks when replacing a task with a chain.

* Added tests.

* Update celery/app/task.py

Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>

* Mark test as flaky.

* Fix race condition in CI.

* fix: Run linked tasks in original slot for replace

This change alters the handling of linked tasks for chains which are
used as the argument to a `.replace()` call for a task which itself has
a chain of signatures to call once it completes. We ensure that the
linked callback is not only retained but also called at the appropiate
point in the newly reconstructed chain comprised of tasks from both the
replacement chain and the tail of the encapsulating chain of the task
being replaced.

We amend some tests to validate this behaviour better and ensure that
call/errbacks behave as expected if the encapsulating chain has either
set. One test is marked with an `xfail` since errbacks of encapsulating
chains are not currently called as expected due to some ambiguity in
when an errback of a replaced task should be dropped or not (celery#6441).

Co-authored-by: Asif Saif Uddin <auvipy@gmail.com>
Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>

* Fix minor documentation omission (celery#6453)

Co-authored-by: Lewis Kabui <lewisemm@users.noreply.github.com>

* Fix max_retries override on self.retry (celery#6436)

* Fix max_retries override

* Fix max_retries override

* Fix max_retries override

* Update exceptions.py

typo

* Update autoretry.py

typo

* Update task.py

Prevent exception unpacking for tasks without autoretry_for

* Update test_tasks.py

Unit test

* Update test_tasks.py

Added a new test

* Update autoretry.py

Fox for explicit raise in tasks

* Update test_tasks.py

* Update autoretry.py

* Update task.py

* Update exceptions.py

* Update task.py

* Happify linter.

* Raise proper error when replacing with an empty chain. (celery#6452)

Fixes celery#6451.

* Update changelog.

* Bump version: 5.0.1 → 5.0.2

* Update daemonizing.rst

Improved systemd documentation for auto-start of the service, and mention the possibility to depend on RabbitMQ service. Also add Restart=always for Celery Beat example

* Update celerybeat.service

* Fix old celery beat variables

Change made 5 days ago in 7c3da03 is faulty, the correct celery beat variables do start with `CELERYBEAT` and not `CELERY_BEAT`

* Fix formatting.

* Fix formatting.

* fix: Make `--workdir` eager for early handling (celery#6457)

This change makes the `--workdir` options an eager one which `click`
will process early for us, before any of the others. At the same time,
we add a callback which ensures that the `chdir()` is run during
handling of the argument so that all subsequent actions (e.g. app
loading) occur in the specified working directory.

Fixes celery#6445

* Fix example.

Fixes celery#6459.

* When using the MongoDB backend, don't cleanup if result_expires is 0 or None. (celery#6462)

Fixes celery#6450.

* Add missing space (celery#6468)

* Fix passing queues into purge command (celery#6469)

In current wersion calling `celery --app my.celery_app purge -Q queue_name` is failing with following trace:

```
    names = (queues or set(app.amqp.queues.keys())) - exclude_queues
TypeError: unsupported operand type(s) for -: 'list' and 'list'
```

Becouse code is expecting set and `queues` is actually a list.

Here is a fix.

* Change donations sidebar to direct users to OpenCollective.

* Added pytest to extras.

Missed in 9a6c292.

* Restore app.start() and app.worker_main() (celery#6481)

* Restore `app.start()` and `app.worker_main()`.

* Update celery/app/base.py

Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>

* Fix spelling error.

Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>

* fix: `node_format()` logfile before detaching

Fixes celery#6426

* Multithreaded backend (celery#6416)

* Cache backend to thread local storage instead of global variable

* Cache oid to thread local storage instead of global variable

* Improve code returning thread_local data

* Move thread local storage to Celery class, introduced thread_oid and added unittests

* Remove python2 compatibility code

* Restore ability to extend the CLI with new sub-commands.

* Adjust documentation to demonstrate how to introduce sub-command plugins in 5.x.

Fixes celery#6439.

* autopep8 & isort.

* Linters now run using Python 3.9.

* Fix apply_async() in Calling Tasks userguide

* Fix dead links in contributing guide (celery#6506)

* Fix inconsistency in documentation for `link_error` (celery#6505)

* Make documentation of link_error consistent

Fixes celery#4099

* Fix undefined variable in example

* Add to contributors list

* Update testing.rst (celery#6507)

Use double back ticks for some code examples, so that quotes don't get converted into smart-quotes.

celery#6497

* Don't upgrade click to 8.x since click-repl doesn't support it yet.

Fixes celery#6511.
Upstream issue: click-contrib/click-repl#72

* Update documentation on changes to custom CLI options in 5.0.

Fixes celery#6380.

* update step to install homebrew

* redis: Support Sentinel with SSL

Use the SentinelManagedSSLConnection when SSL is enabled for the
transport. The redis-py project doesn't have a connection class for
SSL+Sentinel yet. So, create a class in redis.py to add that
functionality.

* Revert "redis: Support Sentinel with SSL" (celery#6518)

This reverts commit 18a0963.

* Reintroduce support for custom preload options (celery#6516)

* Restore preload options.

Fixes celery#6307.

* Document breaking changes for preload options in 5.0.

Fixes celery#6379.

* Changelog for 5.0.3.

* Bump version: 5.0.2 → 5.0.3

* Added integration tests for calling a task (celery#6523)

* DummyClient of cache+memory:// backend now shares state between threads (celery#6524)

* isort.

* Update changelog.

* Bump version: 5.0.3 → 5.0.4

* Change deprecated from collections import Mapping/MutableMapping to from collections.abc ... (celery#6532)

* fix celery#6047

* Fix type error in S3 backend (celery#6537)

* Convert key from bytes to str

* Add unit test for S3 delete of key with type bytes

* events.py: Remove duplicate decorator in wrong place (celery#6543)

`@handle_preload_options` was specified twice as a decorator of `events`, once at the top (wrong) and once at the bottom (right).
This fixes the `celery events` commands and also `celery --help`

* Update changelog.

* Bump version: 5.0.4 → 5.0.5

* ADD: indico additions - trails

* FIX: remove dev.txt dependencies

* ADD: handle revoke failures

* ADD: trailer_request support and better drain resolution

* ADD: merge options was overriding link_error values

* PATCH: DLX and reject behaviour

* FIX: amqp dependencies

Co-authored-by: Omer Katz <omer.drow@gmail.com>
Co-authored-by: Thomas Grainger <tagrain@gmail.com>
Co-authored-by: Martin Paulus <mpaulus@lequest.com>
Co-authored-by: maybe-sybr <58414429+maybe-sybr@users.noreply.github.com>
Co-authored-by: Ash Berlin-Taylor <ash_github@firemirror.com>
Co-authored-by: qiaocc <jasonqiao36@gmail.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
Co-authored-by: Weiliang Li <to.be.impressive@gmail.com>
Co-authored-by: Akash Agrawal <akashrocksha@gmail.com>
Co-authored-by: Michal Kuffa <michal.kuffa@sentry.io>
Co-authored-by: Frazer McLean <frazer@frazermclean.co.uk>
Co-authored-by: Maarten Fonville <mfonville@users.noreply.github.com>
Co-authored-by: laixintao <laixintaoo@gmail.com>
Co-authored-by: Nicolas Dandrimont <nicolas@dandrimont.eu>
Co-authored-by: Bas ten Berge <bas+github@tenberge-ict.nl>
Co-authored-by: Zvi Baratz <z.baratz@gmail.com>
Co-authored-by: Justinas Petuchovas <justinas.petuchovas@gmail.com>
Co-authored-by: bastb <bas@tenberge-ict.nl>
Co-authored-by: Artem Bernatskyi <artem.bernatskyy@gmail.com>
Co-authored-by: ZubAnt <ya.zubarevanton@yandex.ru>
Co-authored-by: Lewis Kabui <lewisemm@users.noreply.github.com>
Co-authored-by: David Pärsson <david@parsson.se>
Co-authored-by: Anthony Lukach <anthonylukach@gmail.com>
Co-authored-by: Safwan Rahman <safwan.rahman15@gmail.com>
Co-authored-by: Stepan Henek <stepan@henek.name>
Co-authored-by: KexZh <hanbaobao2005@gmail.com>
Co-authored-by: Thomas Riccardi <thomas@deepomatic.com>
Co-authored-by: Egor Sergeevich Poderiagin <egor@crazyrussian.pro>
Co-authored-by: Asif Saif Uddin (Auvi) <auvipy@gmail.com>
Co-authored-by: Lewis M. Kabui <13940255+lewisemm@users.noreply.github.com>
Co-authored-by: Ixiodor <Ixiodor@users.noreply.github.com>
Co-authored-by: Mathieu Rollet <matletix@gmail.com>
Co-authored-by: Mike DePalatis <depalatis@gmail.com>
Co-authored-by: partizan <serg.partizan@gmail.com>
Co-authored-by: Nick Pope <nick.pope@flightdataservices.com>
Co-authored-by: Matus Valo <matusvalo@users.noreply.github.com>
Co-authored-by: Matus Valo <matusvalo@gmail.com>
Co-authored-by: henribru <6639509+henribru@users.noreply.github.com>
Co-authored-by: Stuart Axon <stuaxo2@yahoo.com>
Co-authored-by: Sonya Chhabra <sonyakc.2007@gmail.com>
Co-authored-by: AbdealiJK <abdealikothari@gmail.com>
Co-authored-by: František Zatloukal <Zatloukal.Frantisek@gmail.com>
Co-authored-by: elonzh <elonzh@qq.com>
Co-authored-by: Sven Koitka <razorx89@users.noreply.github.com>
Co-authored-by: Arnon Yaari <wiggin15@yahoo.com>
@vznncv
Copy link
Contributor

vznncv commented Jun 10, 2021

Note: although this merge request makes Celery.backend property thread safe, some function like celery.app.trace.build_tracer :

celery/celery/app/trace.py

Lines 292 to 296 in d9d8250

def build_tracer(name, task, loader=None, hostname=None, store_errors=True,
Info=TraceInfo, eager=False, propagate=False, app=None,
monotonic=time.monotonic, trace_ok_t=trace_ok_t,
IGNORE_STATES=IGNORE_STATES):
"""Return a function that traces task execution.

celery/celery/app/trace.py

Lines 322 to 331 in d9d8250

# If the task doesn't define a custom __call__ method
# we optimize it away by simply calling the run method directly,
# saving the extra method call and a line less in the stack trace.
fun = task if task_has_custom(task, '__call__') else task.run
loader = loader or app.loader
backend = task.backend
ignore_result = task.ignore_result
track_started = task.track_started
track_started = not eager and (task.track_started and not ignore_result)

celery/celery/app/trace.py

Lines 356 to 358 in d9d8250

store_result = backend.store_result
mark_as_done = backend.mark_as_done
backend_cleanup = backend.process_cleanup

are invoked at worker startup and capture backend and some bound methods (mark_as_done) in the one thread, but may use them in another one:

celery/celery/app/trace.py

Lines 448 to 452 in d9d8250

# -*- TRACE -*-
try:
R = retval = fun(*args, **kwargs)
state = SUCCESS
except Reject as exc:

So, probably such functions should be re-written to use app.backend rather local backend variables/bound methods usage.

@auvipy
Copy link
Member

auvipy commented Jun 10, 2021

Note: although this merge request makes Celery.backend property thread safe, some function like celery.app.trace.build_tracer :

celery/celery/app/trace.py

Lines 292 to 296 in d9d8250

def build_tracer(name, task, loader=None, hostname=None, store_errors=True,
Info=TraceInfo, eager=False, propagate=False, app=None,
monotonic=time.monotonic, trace_ok_t=trace_ok_t,
IGNORE_STATES=IGNORE_STATES):
"""Return a function that traces task execution.

celery/celery/app/trace.py

Lines 322 to 331 in d9d8250

# If the task doesn't define a custom __call__ method
# we optimize it away by simply calling the run method directly,
# saving the extra method call and a line less in the stack trace.
fun = task if task_has_custom(task, '__call__') else task.run
loader = loader or app.loader
backend = task.backend
ignore_result = task.ignore_result
track_started = task.track_started
track_started = not eager and (task.track_started and not ignore_result)

celery/celery/app/trace.py

Lines 356 to 358 in d9d8250

store_result = backend.store_result
mark_as_done = backend.mark_as_done
backend_cleanup = backend.process_cleanup

are invoked at worker startup and capture backend and some bound methods (mark_as_done) in the one thread, but may use them in another one:

celery/celery/app/trace.py

Lines 448 to 452 in d9d8250

# -*- TRACE -*-
try:
R = retval = fun(*args, **kwargs)
state = SUCCESS
except Reject as exc:

So, probably such functions should be re-written to use app.backend rather local backend variables/bound methods usage.

are you up for that?

@vznncv
Copy link
Contributor

vznncv commented Jun 11, 2021

Yes, I'll check this code more thoroughly and try to create merge request in some days.

vznncv added a commit to vznncv/celery that referenced this pull request Jul 11, 2021
Add simple test with embedded worker that checks
backend instance usage by threads. According
merge request celery#6416 backends should be thread local.
vznncv added a commit to vznncv/celery that referenced this pull request Jul 11, 2021
Add simple test with embedded worker that checks
backend instance usage by threads. According
merge request celery#6416 backends should be thread local.
vznncv added a commit to vznncv/celery that referenced this pull request Jul 11, 2021
Fix backend capturing by closure during task creation in the function `celery.app.trace.build_tracer`, as different threads may create and use celery task. It complement changes in the pull request celery#6416.
vznncv added a commit to vznncv/celery that referenced this pull request Jul 11, 2021
Fix backend capturing by closure during task creation in the function `celery.app.trace.build_tracer`, as different threads may create and use celery task. It complement changes in the pull request celery#6416.
vznncv added a commit to vznncv/celery that referenced this pull request Jul 11, 2021
Fix backend capturing by closure during task creation in the function `celery.app.trace.build_tracer`, as different threads may create and use celery task. It complement changes in the pull request celery#6416.
auvipy pushed a commit that referenced this pull request Jul 11, 2021
* Add test of backend usage by threads

Add simple test with embedded worker that checks
backend instance usage by threads. According
merge request #6416 backends should be thread local.

* Fix backend captures in the `celery.app.trace.build_tracer`

Fix backend capturing by closure during task creation in the function `celery.app.trace.build_tracer`, as different threads may create and use celery task. It complement changes in the pull request #6416.

* Fix flake8 errors

Fix flake8 errors from Celery/lint github workflow step
jeyrce pushed a commit to jeyrce/celery that referenced this pull request Aug 25, 2021
* Cache backend to thread local storage instead of global variable

* Cache oid to thread local storage instead of global variable

* Improve code returning thread_local data

* Move thread local storage to Celery class, introduced thread_oid and added unittests
jeyrce pushed a commit to jeyrce/celery that referenced this pull request Aug 25, 2021
* Add test of backend usage by threads

Add simple test with embedded worker that checks
backend instance usage by threads. According
merge request celery#6416 backends should be thread local.

* Fix backend captures in the `celery.app.trace.build_tracer`

Fix backend capturing by closure during task creation in the function `celery.app.trace.build_tracer`, as different threads may create and use celery task. It complement changes in the pull request celery#6416.

* Fix flake8 errors

Fix flake8 errors from Celery/lint github workflow step
@d0d0 d0d0 mentioned this pull request Oct 5, 2021
18 tasks
fonhorst pushed a commit to aimclub/AutoTM that referenced this pull request Jan 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Celery backends are not thread-safe

8 participants