<p dir="auto">I have a very time-sensitive application that I'm building.</p>
<p dir="auto">I noticed that the first time a worker sends a new task, it has a non-trivial delay due to the declaring of the queues.</p>
<p dir="auto">I would like to know if it's possible to remove this delay, or to move it at some init function in my worker.</p>
<h2 dir="auto">Related Issues and Possible Duplicates</h2>
<p dir="auto">None found</p>
<h4 dir="auto">Related Issues</h4>
<p dir="auto">None found</p>
<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>: 4.2.1 (windowlicker)</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.2.1 (windowlicker) kombu:4.4.0 py:3.6.6
            billiard:3.5.0.5 redis:3.2.0
platform -&gt; system:Darwin arch:64bit imp:CPython
loader   -&gt; celery.loaders.app.AppLoader
settings -&gt; transport:redis results:disabled

broker_url: 'redis://localhost:6379//'"><pre class="notranslate"><code class="notranslate">software -&gt; celery:4.2.1 (windowlicker) kombu:4.4.0 py:3.6.6
            billiard:3.5.0.5 redis:3.2.0
platform -&gt; system:Darwin arch:64bit imp:CPython
loader   -&gt; celery.loaders.app.AppLoader
settings -&gt; transport:redis results:disabled

broker_url: 'redis://localhost:6379//'
</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>: N/A or Unknown</li>
<li><strong>Minimal Broker Version</strong>: N/A or Unknown</li>
<li><strong>Minimal Result Backend Version</strong>: N/A or Unknown</li>
<li><strong>Minimal OS and/or Kernel Version</strong>: N/A or Unknown</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.4.2
billiard==3.5.0.5
celery==4.2.1
kombu==4.4.0
pytz==2018.9
redis==3.2.0
vine==1.2.0"><pre class="notranslate"><code class="notranslate">amqp==2.4.2
billiard==3.5.0.5
celery==4.2.1
kombu==4.4.0
pytz==2018.9
redis==3.2.0
vine==1.2.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">
</p><div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import time

from celery import Celery

app = Celery('test', broker='redis://localhost:6379')


@app.task()
def dummy_task_secondary():
    print(&quot;Dummy task completed&quot;)


@app.task()
def dummy_task_primary():
    t = time.time()
    dummy_task_secondary.delay()
    print(f&quot;First time it took {time.time() - t}&quot;)

    t = time.time()
    dummy_task_secondary.delay()
    print(f&quot;Second time it took {time.time() - t}&quot;)
"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">time</span>

<span class="pl-k">from</span> <span class="pl-s1">celery</span> <span class="pl-k">import</span> <span class="pl-v">Celery</span>

<span class="pl-s1">app</span> <span class="pl-c1">=</span> <span class="pl-v">Celery</span>(<span class="pl-s">'test'</span>, <span class="pl-s1">broker</span><span class="pl-c1">=</span><span class="pl-s">'redis://localhost:6379'</span>)


<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">task</span>()</span>
<span class="pl-k">def</span> <span class="pl-en">dummy_task_secondary</span>():
    <span class="pl-en">print</span>(<span class="pl-s">"Dummy task completed"</span>)


<span class="pl-en">@<span class="pl-s1">app</span>.<span class="pl-en">task</span>()</span>
<span class="pl-k">def</span> <span class="pl-en">dummy_task_primary</span>():
    <span class="pl-s1">t</span> <span class="pl-c1">=</span> <span class="pl-s1">time</span>.<span class="pl-en">time</span>()
    <span class="pl-s1">dummy_task_secondary</span>.<span class="pl-en">delay</span>()
    <span class="pl-en">print</span>(<span class="pl-s">f"First time it took <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">time</span>.<span class="pl-en">time</span>() <span class="pl-c1">-</span> <span class="pl-s1">t</span><span class="pl-kos">}</span></span>"</span>)

    <span class="pl-s1">t</span> <span class="pl-c1">=</span> <span class="pl-s1">time</span>.<span class="pl-en">time</span>()
    <span class="pl-s1">dummy_task_secondary</span>.<span class="pl-en">delay</span>()
    <span class="pl-en">print</span>(<span class="pl-s">f"Second time it took <span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">time</span>.<span class="pl-en">time</span>() <span class="pl-c1">-</span> <span class="pl-s1">t</span><span class="pl-kos">}</span></span>"</span>)</pre></div>
<p dir="auto"></p>
</details>
<h1 dir="auto">Expected Behavior</h1>
<p dir="auto">There is no difference between the time it takes to send the first task and the second.</p>
<h1 dir="auto">Actual Behavior</h1>
<p dir="auto">The first time is dramatically slower:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="[2019-03-11 15:27:42,610: WARNING/ForkPoolWorker-8] First time it took 0.029098987579345703
[2019-03-11 15:27:42,612: WARNING/ForkPoolWorker-8] Second time it took 0.0007290840148925781"><pre class="notranslate"><code class="notranslate">[2019-03-11 15:27:42,610: WARNING/ForkPoolWorker-8] First time it took 0.029098987579345703
[2019-03-11 15:27:42,612: WARNING/ForkPoolWorker-8] Second time it took 0.0007290840148925781
</code></pre></div>
<p dir="auto">I am not sure if this issue is a feature request or a request for guidance.  I do not see how this could be accomplished, so I guess it is a feature request -- but perhaps it is already possible?</p>
<p dir="auto">I am trying to swap from using class based tasks to decorator tasks.  Simple tasks are easy to swap over.  However, some of my tasks are based around this class based task: <a href="https://github.com/PolicyStat/jobtastic/blob/v2.1.1/jobtastic/task.py#L313">https://github.com/PolicyStat/jobtastic/blob/v2.1.1/jobtastic/task.py#L313</a></p>
<p dir="auto">The Jobtastic Task Class provides a run method that prevents duplicate tasks from running simultaneously and abstracts some cruft that is pretty handy.  Then its run method calls <code class="notranslate">calculate_result()</code> to perform the actual work of the task you create.</p>
<p dir="auto">What has been holding this back is since the <a href="https://docs.celeryproject.org/en/stable/userguide/tasks.html#custom-task-classes" rel="nofollow">decorator makes your function the run method</a>, how can I implement this functionality without rewriting it in every task?  If the run() method of the Jobtastic Task is overridden, the utility of the task is lost.</p>
<p dir="auto">Is there a way to incorporate the advanced runtime logic of the Jobtastic Task?  Is it possible to tell the decorator what method the wrapped function should become?  Or would an additional <code class="notranslate">run()</code> wrapper be required to handle this with a decorated approach?</p>