mirror of
https://github.com/kennethreitz/responder.git
synced 2026-06-05 23:00:17 +00:00
178 lines
12 KiB
HTML
178 lines
12 KiB
HTML
<!DOCTYPE html>
|
|
|
|
<html lang="en" data-content_root="../../">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>responder.background — responder 3.6.1 documentation</title>
|
|
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=5ecbeea2" />
|
|
<link rel="stylesheet" type="text/css" href="../../_static/basic.css?v=b08954a9" />
|
|
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css?v=27fed22d" />
|
|
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css?v=76b2166b" />
|
|
<link rel="stylesheet" type="text/css" href="../../_static/design-elements.e5416f61bae5d36adc6d722a2b6f8cff.css?v=452a8e97" />
|
|
<script src="../../_static/documentation_options.js?v=f731707b"></script>
|
|
<script src="../../_static/doctools.js?v=9bcbadda"></script>
|
|
<script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
|
|
<script src="../../_static/clipboard.min.js?v=a7894cd8"></script>
|
|
<script src="../../_static/copybutton.js?v=fd10adb8"></script>
|
|
<script>
|
|
</script>
|
|
<script src="../../_static/design-elements.bbdccc18c4abea9397628f9fea3d48c2.js?v=03c7770e"></script>
|
|
<link rel="index" title="Index" href="../../genindex.html" />
|
|
<link rel="search" title="Search" href="../../search.html" />
|
|
|
|
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
|
|
|
|
|
|
|
|
|
|
|
</head><body>
|
|
|
|
|
|
<div class="document">
|
|
<div class="documentwrapper">
|
|
<div class="bodywrapper">
|
|
|
|
|
|
<div class="body" role="main">
|
|
|
|
<h1>Source code for responder.background</h1><div class="highlight"><pre>
|
|
<span></span><span class="kn">import</span><span class="w"> </span><span class="nn">asyncio</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">concurrent.futures</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">inspect</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">multiprocessing</span>
|
|
<span class="kn">import</span><span class="w"> </span><span class="nn">traceback</span>
|
|
|
|
<span class="kn">from</span><span class="w"> </span><span class="nn">starlette.concurrency</span><span class="w"> </span><span class="kn">import</span> <span class="n">run_in_threadpool</span>
|
|
|
|
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"BackgroundQueue"</span><span class="p">]</span>
|
|
|
|
|
|
<div class="viewcode-block" id="BackgroundQueue">
|
|
<a class="viewcode-back" href="../../api.html#responder.background.BackgroundQueue">[docs]</a>
|
|
<span class="k">class</span><span class="w"> </span><span class="nc">BackgroundQueue</span><span class="p">:</span>
|
|
<span class="w"> </span><span class="sd">"""A queue for running tasks in background threads.</span>
|
|
|
|
<span class="sd"> Uses a ``ThreadPoolExecutor`` sized to the number of CPUs. Access it</span>
|
|
<span class="sd"> via ``api.background``.</span>
|
|
|
|
<span class="sd"> Usage::</span>
|
|
|
|
<span class="sd"> # As a decorator — fire and forget</span>
|
|
<span class="sd"> @api.background.task</span>
|
|
<span class="sd"> def send_email(to, subject):</span>
|
|
<span class="sd"> ...</span>
|
|
|
|
<span class="sd"> send_email("user@example.com", "Hello")</span>
|
|
|
|
<span class="sd"> # Direct submission</span>
|
|
<span class="sd"> future = api.background.run(send_email, "user@example.com", "Hello")</span>
|
|
|
|
<span class="sd"> # As a callable (supports async functions)</span>
|
|
<span class="sd"> await api.background(send_email, "user@example.com", "Hello")</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">n</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Create a new background queue.</span>
|
|
|
|
<span class="sd"> :param n: Number of worker threads. Defaults to CPU count.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">n</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">n</span> <span class="o">=</span> <span class="n">multiprocessing</span><span class="o">.</span><span class="n">cpu_count</span><span class="p">()</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">n</span> <span class="o">=</span> <span class="n">n</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">pool</span> <span class="o">=</span> <span class="n">concurrent</span><span class="o">.</span><span class="n">futures</span><span class="o">.</span><span class="n">ThreadPoolExecutor</span><span class="p">(</span><span class="n">max_workers</span><span class="o">=</span><span class="n">n</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">results</span> <span class="o">=</span> <span class="p">[]</span>
|
|
|
|
<div class="viewcode-block" id="BackgroundQueue.run">
|
|
<a class="viewcode-back" href="../../api.html#responder.background.BackgroundQueue.run">[docs]</a>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Submit a function to run in a background thread.</span>
|
|
|
|
<span class="sd"> :param f: The function to run.</span>
|
|
<span class="sd"> :returns: A ``concurrent.futures.Future`` for the result.</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">f</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">pool</span><span class="o">.</span><span class="n">submit</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">f</span></div>
|
|
|
|
|
|
<div class="viewcode-block" id="BackgroundQueue.task">
|
|
<a class="viewcode-back" href="../../api.html#responder.background.BackgroundQueue.task">[docs]</a>
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">task</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">f</span><span class="p">):</span>
|
|
<span class="w"> </span><span class="sd">"""Decorator that wraps a function to run in the background thread pool.</span>
|
|
|
|
<span class="sd"> The decorated function returns a ``Future`` instead of blocking.</span>
|
|
<span class="sd"> Exceptions are printed to stderr via traceback.</span>
|
|
|
|
<span class="sd"> :param f: The function to wrap.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">on_future_done</span><span class="p">(</span><span class="n">fs</span><span class="p">):</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">fs</span><span class="o">.</span><span class="n">result</span><span class="p">()</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
|
|
<span class="n">traceback</span><span class="o">.</span><span class="n">print_exc</span><span class="p">()</span>
|
|
|
|
<span class="k">def</span><span class="w"> </span><span class="nf">do_task</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
<span class="n">result</span><span class="o">.</span><span class="n">add_done_callback</span><span class="p">(</span><span class="n">on_future_done</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">result</span>
|
|
|
|
<span class="k">return</span> <span class="n">do_task</span></div>
|
|
|
|
|
|
<span class="k">async</span> <span class="k">def</span><span class="w"> </span><span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">func</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">inspect</span><span class="o">.</span><span class="n">iscoroutinefunction</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">create_task</span><span class="p">(</span><span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="k">await</span> <span class="n">run_in_threadpool</span><span class="p">(</span><span class="n">func</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
|
|
|
|
</pre></div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
<div class="sphinxsidebar" role="navigation" aria-label="Main">
|
|
<div class="sphinxsidebarwrapper"><p class="logo">
|
|
<a href="../../index.html">
|
|
<img class="logo" src="../../_static/responder.png" />
|
|
</a>
|
|
</p>
|
|
<p>
|
|
<strong>Responder</strong> — a familiar HTTP service framework for Python.
|
|
<br />
|
|
<small>v3.6.1</small>
|
|
</p>
|
|
<h3>Useful Links</h3>
|
|
<ul>
|
|
<li><a href="https://github.com/kennethreitz/responder">Responder @ GitHub</a></li>
|
|
<li><a href="https://pypi.org/project/responder/">Responder @ PyPI</a></li>
|
|
<li><a href="https://github.com/kennethreitz/responder/issues">Issue Tracker</a></li>
|
|
</ul>
|
|
<search id="searchbox" style="display: none" role="search">
|
|
<h3 id="searchlabel">Quick search</h3>
|
|
<div class="searchformwrapper">
|
|
<form class="search" action="../../search.html" method="get">
|
|
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
|
<input type="submit" value="Go" />
|
|
</form>
|
|
</div>
|
|
</search>
|
|
<script>document.getElementById('searchbox').style.display = "block"</script>
|
|
</div>
|
|
</div>
|
|
<div class="clearer"></div>
|
|
</div>
|
|
<div class="footer">
|
|
©2018-2026, Kenneth Reitz.
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
</html> |