<h1 dir="auto">Checklist</h1>

<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have verified that the issue exists against the <code class="notranslate">master</code> branch of Celery.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> This has already been asked to the <a href="https://groups.google.com/forum/#!forum/celery-users" rel="nofollow">discussion group</a> first.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have read the relevant section in the<br>
<a href="http://docs.celeryproject.org/en/latest/contributing.html#other-bugs" rel="nofollow">contribution guide</a><br>
on reporting bugs.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have checked the <a href="https://github.com/celery/celery/issues?q=is%3Aissue+label%3A%22Issue+Type%3A+Bug+Report%22+-label%3A%22Category%3A+Documentation%22">issues list</a><br>
for similar or identical bug reports.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have checked the <a href="https://github.com/celery/celery/pulls?q=is%3Apr+label%3A%22PR+Type%3A+Bugfix%22+-label%3A%22Category%3A+Documentation%22">pull requests list</a><br>
for existing proposed fixes.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have checked the <a href="https://github.com/celery/celery/commits/master">commit log</a><br>
to find out if the bug was already fixed in the master branch.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have included all related issues and possible duplicate issues<br>
in this issue (If there are none, check this box anyway).</li>
</ul>
<h2 dir="auto">Mandatory Debugging Information</h2>
<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have included the output of <code class="notranslate">celery -A proj report</code> in the issue.<br>
(if you are not able to do this, then at least specify the Celery<br>
version affected).</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have verified that the issue exists against the <code class="notranslate">master</code> branch of Celery.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have included the contents of <code class="notranslate">pip freeze</code> in the issue.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have included all the versions of all the external dependencies required<br>
to reproduce this bug.</li>
</ul>
<h2 dir="auto">Optional Debugging Information</h2>

<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have tried reproducing the issue on more than one Python version<br>
and/or implementation.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have tried reproducing the issue on more than one message broker and/or<br>
result backend.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have tried reproducing the issue on more than one version of the message<br>
broker and/or result backend.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have tried reproducing the issue on more than one operating system.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have tried reproducing the issue on more than one workers pool.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have tried reproducing the issue with autoscaling, retries,<br>
ETA/Countdown &amp; rate limits disabled.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox"> I have tried reproducing the issue after downgrading<br>
and/or upgrading Celery and its dependencies.</li>
</ul>
<h2 dir="auto">Related Issues and Possible Duplicates</h2>

<h4 dir="auto">Related Issues</h4>
<ul dir="auto">
<li>None</li>
</ul>
<h4 dir="auto">Possible Duplicates</h4>
<ul dir="auto">
<li>None</li>
</ul>
<h2 dir="auto">Environment &amp; Settings</h2>

<p dir="auto"><strong>Celery version</strong>:</p>

<details>
<summary><b><code class="notranslate">celery report</code> Output:</b></summary>
<p dir="auto">
</p><div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="software -&gt; celery:4.4.5 (cliffs) kombu:4.6.10 py:3.7.5
            billiard:3.6.3.0 py-amqp:2.6.0
platform -&gt; system:Linux arch:64bit, ELF
            kernel version:5.3.0-59-generic imp:CPython
loader   -&gt; celery.loaders.app.AppLoader
settings -&gt; transport:amqp results:disabled

broker_url: 'amqp://guest:********@localhost:5672//'
task_default_queue: 'default'
task_queue_max_priority: 100
task_default_priority: 5
worker_prefetch_multiplier: 1
task_acks_late: True"><pre class="notranslate"><code class="notranslate">software -&gt; celery:4.4.5 (cliffs) kombu:4.6.10 py:3.7.5
            billiard:3.6.3.0 py-amqp:2.6.0
platform -&gt; system:Linux arch:64bit, ELF
            kernel version:5.3.0-59-generic imp:CPython
loader   -&gt; celery.loaders.app.AppLoader
settings -&gt; transport:amqp results:disabled

broker_url: 'amqp://guest:********@localhost:5672//'
task_default_queue: 'default'
task_queue_max_priority: 100
task_default_priority: 5
worker_prefetch_multiplier: 1
task_acks_late: True
</code></pre></div>
<p dir="auto"></p>
</details>
<h1 dir="auto">Steps to Reproduce</h1>
<h2 dir="auto">Required Dependencies</h2>

<ul dir="auto">
<li><strong>Minimal Python Version</strong>: 3.7.5</li>
<li><strong>Minimal Celery Version</strong>: 4.4.2 or master</li>
<li><strong>Minimal Kombu Version</strong>: 4.6.10</li>
<li><strong>Minimal Broker Version</strong>: rabbitmq 3.8.2</li>
<li><strong>Minimal Result Backend Version</strong>: N/A</li>
<li><strong>Minimal OS and/or Kernel Version</strong>: Linux-5.3.0-59-generic-x86_64-with-Ubuntu-19.10-eoan 2020-06-18 10:30:24</li>
<li><strong>Minimal Broker Client Version</strong>: N/A or Unknown</li>
<li><strong>Minimal Result Backend Client Version</strong>: N/A or Unknown</li>
</ul>
<h3 dir="auto">Python Packages</h3>

<details>
<summary><b><code class="notranslate">pip freeze</code> Output:</b></summary>
<p dir="auto">
</p><div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="amqp==2.6.0
billiard==3.6.3.0
celery==4.4.5
future==0.18.2
importlib-metadata==1.6.1
kombu==4.6.10
pika==1.1.0
pytz==2020.1
vine==1.3.0
zipp==3.1.0"><pre class="notranslate"><code class="notranslate">amqp==2.6.0
billiard==3.6.3.0
celery==4.4.5
future==0.18.2
importlib-metadata==1.6.1
kombu==4.6.10
pika==1.1.0
pytz==2020.1
vine==1.3.0
zipp==3.1.0
</code></pre></div>
<p dir="auto"></p>
</details>
<h3 dir="auto">Other Dependencies</h3>

<details>
<p dir="auto">
N/A
</p>
</details>
<h2 dir="auto">Minimally Reproducible Test Case</h2>

<details>
<p dir="auto">
app.py :
</p><div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import celery
import time

app = celery.Celery(&quot;app&quot;, broker=&quot;amqp://guest:guest@localhost//&quot;)
app.conf.task_default_queue = &quot;default&quot;
app.conf.task_queue_max_priority = 100
app.conf.task_default_priority = 5
app.conf.worker_prefetch_multiplier = 1
app.conf.task_acks_late = True


@app.task
def dummy_low():
    time.sleep(5)
    print(&quot;dummy_low.&quot;)


@app.task
def dummy_high():
    time.sleep(5)
    print(&quot;dummy_high.&quot;)


def main():
    print(&quot;Creating low prio tasks...&quot;)
    for i in range(2000):
        dummy_low.apply_async(priority=5)

    print(&quot;Adding high prio task chain...&quot;)
    tasks = dummy_high.si()
    for i in range(100):
        tasks = tasks | dummy_high.si()

    tasks.apply_async(priority=8)


if __name__ == &quot;__main__&quot;:
    main()
"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">celery</span>
<span class="pl-k">import</span> <span class="pl-s1">time</span>

<span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-s1">celery</span>.<span class="pl-v">Celery</span>(<span class="pl-s">"app"</span>, <span class="pl-s1">broker</span><span class="pl-c1">=</span><span class="pl-s">"amqp://guest:guest@localhost//"</span>)
<span class="pl-s1">app</span>.<span class="pl-s1">conf</span>.<span class="pl-s1">task_default_queue</span> <span class="pl-c1">=</span> <span class="pl-s">"default"</span>
<span class="pl-s1">app</span>.<span class="pl-s1">conf</span>.<span class="pl-s1">task_queue_max_priority</span> <span class="pl-c1">=</span> <span class="pl-c1">100</span>
<span class="pl-s1">app</span>.<span class="pl-s1">conf</span>.<span class="pl-s1">task_default_priority</span> <span class="pl-c1">=</span> <span class="pl-c1">5</span>
<span class="pl-s1">app</span>.<span class="pl-s1">conf</span>.<span class="pl-s1">worker_prefetch_multiplier</span> <span class="pl-c1">=</span> <span class="pl-c1">1</span>
<span class="pl-s1">app</span>.<span class="pl-s1">conf</span>.<span class="pl-s1">task_acks_late</span> <span class="pl-c1">=</span> <span class="pl-c1">True</span>


<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-s1">task</span></span>
<span class="pl-k">def</span> <span class="pl-en">dummy_low</span>():
    <span class="pl-s1">time</span>.<span class="pl-en">sleep</span>(<span class="pl-c1">5</span>)
    <span class="pl-en">print</span>(<span class="pl-s">"dummy_low."</span>)


<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-s1">task</span></span>
<span class="pl-k">def</span> <span class="pl-en">dummy_high</span>():
    <span class="pl-s1">time</span>.<span class="pl-en">sleep</span>(<span class="pl-c1">5</span>)
    <span class="pl-en">print</span>(<span class="pl-s">"dummy_high."</span>)


<span class="pl-k">def</span> <span class="pl-en">main</span>():
    <span class="pl-en">print</span>(<span class="pl-s">"Creating low prio tasks..."</span>)
    <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-c1">2000</span>):
        <span class="pl-s1">dummy_low</span>.<span class="pl-en">apply_async</span>(<span class="pl-s1">priority</span><span class="pl-c1">=</span><span class="pl-c1">5</span>)

    <span class="pl-en">print</span>(<span class="pl-s">"Adding high prio task chain..."</span>)
    <span class="pl-s1">tasks</span> <span class="pl-c1">=</span> <span class="pl-s1">dummy_high</span>.<span class="pl-en">si</span>()
    <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-c1">100</span>):
        <span class="pl-s1">tasks</span> <span class="pl-c1">=</span> <span class="pl-s1">tasks</span> <span class="pl-c1">|</span> <span class="pl-s1">dummy_high</span>.<span class="pl-en">si</span>()

    <span class="pl-s1">tasks</span>.<span class="pl-en">apply_async</span>(<span class="pl-s1">priority</span><span class="pl-c1">=</span><span class="pl-c1">8</span>)


<span class="pl-k">if</span> <span class="pl-s1">__name__</span> <span class="pl-c1">==</span> <span class="pl-s">"__main__"</span>:
    <span class="pl-en">main</span>()</pre></div>
<p dir="auto"></p>
</details>
<h1 dir="auto">Expected Behavior</h1>

<p dir="auto">High priority tasks are executed before the low priority tasks.</p>
<h1 dir="auto">Actual Behavior</h1>

<p dir="auto">Only one (the first of the chain) high priority task is executed right away. The others are not priorized and thus not executed before the end of the low-priority tasks.</p>
<p dir="auto">Please note that this <strong>doesn't happen with non-chained tasks or with grouped tasks.</strong> (with non-chained tasks or grouped tasks, priorities are respected.)</p>
<h1 dir="auto">Checklist</h1>

<ul class="contains-task-list">
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have checked the <a href="https://github.com/celery/celery/issues?utf8=%E2%9C%93&amp;q=is%3Aissue+label%3A%22Issue+Type%3A+Feature+Request%22+">issues list</a><br>
for similar or identical feature requests.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have checked the <a href="https://github.com/celery/celery/pulls?utf8=%E2%9C%93&amp;q=is%3Apr+label%3A%22PR+Type%3A+Feature%22+">pull requests list</a><br>
for existing proposed implementations of this feature.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have checked the <a href="https://github.com/celery/celery/commits/master">commit log</a><br>
to find out if the if the same feature was already implemented in the<br>
master branch.</li>
<li class="task-list-item"><input type="checkbox" id="" disabled="" class="task-list-item-checkbox" checked=""> I have included all related issues and possible duplicate issues<br>
in this issue (If there are none, check this box anyway).</li>
</ul>
<h2 dir="auto">Related Issues and Possible Duplicates</h2>

<h4 dir="auto">Related Issues</h4>
<ul dir="auto">
<li>None</li>
</ul>
<h4 dir="auto">Possible Duplicates</h4>
<ul dir="auto">
<li>None</li>
</ul>
<h1 dir="auto">Brief Summary</h1>
<p dir="auto">I would like to be able to access arbitrary AMQP message properties (e.g. <code class="notranslate">user-id</code>) within my tasks.</p>
<h1 dir="auto">Design</h1>
<h2 dir="auto">Architectural Considerations</h2>

<p dir="auto">None</p>
<h2 dir="auto">Proposed Behavior</h2>
<p dir="auto">If the message received from the transport has a <code class="notranslate">properties</code> attribute, a reference to the value should be available in the <code class="notranslate">app.task.Context</code> instance available as <code class="notranslate">self.request</code> in a bound task. If there is no <code class="notranslate">properties</code> attribute, the new <code class="notranslate">Context</code> attribute may be set to <code class="notranslate">None</code>.</p>
<h2 dir="auto">Proposed UI/UX</h2>
<p dir="auto">The new attribute in <code class="notranslate">app.task.Context</code> might be named <code class="notranslate">properties</code>.</p>
<h2 dir="auto">Diagrams</h2>

<p dir="auto">N/A</p>
<h2 dir="auto">Alternatives</h2>

<p dir="auto">Application-defined headers are already available to the task, but some functionality may be provided through broker interactions which cannot be replicated using application-defined headers (e.g. RabbitMQ's validated User-ID).<br>
Another option would be to expose each of the remaining AMQP 0-9-1 message properties on the <code class="notranslate">app.task.Context</code> object similar to <code class="notranslate">reply_to</code>. This would have the disadvantage of introducing broker-specific logic.</p>