summaryrefslogtreecommitdiff
path: root/doc/hubs.html
blob: 144fd47c753a297820f47f78e91e288661fedc01 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221

<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />

    <title>Understanding Eventlet Hubs &#8212; Eventlet 0.32.0 documentation</title>
    <link rel="stylesheet" type="text/css" href="_static/pygments.css" />
    <link rel="stylesheet" type="text/css" href="_static/classic.css" />
    
    <script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
    <script src="_static/jquery.js"></script>
    <script src="_static/underscore.js"></script>
    <script src="_static/doctools.js"></script>
    
    <link rel="index" title="Index" href="genindex.html" />
    <link rel="search" title="Search" href="search.html" />
    <link rel="next" title="Testing Eventlet" href="testing.html" />
    <link rel="prev" title="Zeromq" href="zeromq.html" /> 
  </head><body>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="testing.html" title="Testing Eventlet"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="zeromq.html" title="Zeromq"
             accesskey="P">previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="index.html">Eventlet 0.32.0 documentation</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">Understanding Eventlet Hubs</a></li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <section id="understanding-eventlet-hubs">
<span id="understanding-hubs"></span><h1>Understanding Eventlet Hubs<a class="headerlink" href="#understanding-eventlet-hubs" title="Permalink to this headline">¶</a></h1>
<p>A hub forms the basis of Eventlet’s event loop, which dispatches I/O events and schedules greenthreads.  It is the existence of the hub that promotes coroutines (which can be tricky to program with) into greenthreads (which are easy).</p>
<p>Eventlet has multiple hub implementations, and when you start using it, it tries to select the best hub implementation for your system.  The hubs that it supports are (in order of preference):</p>
<dl class="simple">
<dt><strong>epolls</strong></dt><dd><p>Linux.</p>
</dd>
<dt><strong>poll</strong></dt><dd><p>On platforms that support it</p>
</dd>
<dt><strong>selects</strong></dt><dd><p>Lowest-common-denominator, available everywhere.</p>
</dd>
<dt><strong>pyevent</strong></dt><dd><p>This is a libevent-based backend and is thus the fastest.  It’s disabled by default, because it does not support native threads, but you can enable it yourself if your use case doesn’t require them.  (You have to install pyevent, too.)</p>
</dd>
</dl>
<p>If the selected hub is not ideal for the application, another can be selected.  You can make the selection either with the environment variable <a class="reference internal" href="environment.html#env-vars"><span class="std std-ref">EVENTLET_HUB</span></a>, or with use_hub.</p>
<dl class="py function">
<dt class="sig sig-object py" id="eventlet.hubs.use_hub">
<span class="sig-prename descclassname"><span class="pre">eventlet.hubs.</span></span><span class="sig-name descname"><span class="pre">use_hub</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">hub</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#eventlet.hubs.use_hub" title="Permalink to this definition">¶</a></dt>
<dd><p>Use this to control which hub Eventlet selects.  Call it with the name of the desired hub module.  Make sure to do this before the application starts doing any I/O!  Calling use_hub completely eliminates the old hub, and any file descriptors or timers that it had been managing will be forgotten.  Put the call as one of the first lines in the main module.:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="sd">&quot;&quot;&quot; This is the main module &quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">eventlet</span> <span class="kn">import</span> <span class="n">hubs</span>
<span class="n">hubs</span><span class="o">.</span><span class="n">use_hub</span><span class="p">(</span><span class="s2">&quot;pyevent&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>Hubs are implemented as thread-local class instances.  <a class="reference internal" href="#eventlet.hubs.use_hub" title="eventlet.hubs.use_hub"><code class="xref py py-func docutils literal notranslate"><span class="pre">eventlet.hubs.use_hub()</span></code></a> only operates on the current thread.  When using multiple threads that each need their own hub, call <a class="reference internal" href="#eventlet.hubs.use_hub" title="eventlet.hubs.use_hub"><code class="xref py py-func docutils literal notranslate"><span class="pre">eventlet.hubs.use_hub()</span></code></a> at the beginning of each thread function that needs a specific hub.  In practice, it may not be necessary to specify a hub in each thread; it works to use one special hub for the main thread, and let other threads use the default hub; this hybrid hub configuration will work fine.</p>
<p>It is also possible to use a third-party hub module in place of one of the built-in ones.  Simply pass the module itself to <a class="reference internal" href="#eventlet.hubs.use_hub" title="eventlet.hubs.use_hub"><code class="xref py py-func docutils literal notranslate"><span class="pre">eventlet.hubs.use_hub()</span></code></a>.  The task of writing such a hub is a little beyond the scope of this document, it’s probably a good idea to simply inspect the code of the existing hubs to see how they work.:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">eventlet</span> <span class="kn">import</span> <span class="n">hubs</span>
<span class="kn">from</span> <span class="nn">mypackage</span> <span class="kn">import</span> <span class="n">myhub</span>
<span class="n">hubs</span><span class="o">.</span><span class="n">use_hub</span><span class="p">(</span><span class="n">myhub</span><span class="p">)</span>
</pre></div>
</div>
<p>Supplying None as the argument to <a class="reference internal" href="#eventlet.hubs.use_hub" title="eventlet.hubs.use_hub"><code class="xref py py-func docutils literal notranslate"><span class="pre">eventlet.hubs.use_hub()</span></code></a> causes it to select the default hub.</p>
</dd></dl>

<section id="how-the-hubs-work">
<h2>How the Hubs Work<a class="headerlink" href="#how-the-hubs-work" title="Permalink to this headline">¶</a></h2>
<p>The hub has a main greenlet, MAINLOOP.  When one of the running coroutines needs
to do some I/O, it registers a listener with the hub (so that the hub knows when to wake it up again), and then switches to MAINLOOP (via <code class="docutils literal notranslate"><span class="pre">get_hub().switch()</span></code>).  If there are other coroutines that are ready to run, MAINLOOP switches to them, and when they complete or need to do more I/O, they switch back to the MAINLOOP.  In this manner, MAINLOOP ensures that every coroutine gets scheduled when it has some work to do.</p>
<p>MAINLOOP is launched only when the first I/O operation happens, and it is not the same greenlet that __main__ is running in.  This lazy launching is why it’s not necessary to explicitly call a dispatch() method like other frameworks, which in turn means that code can start using Eventlet without needing to be substantially restructured.</p>
</section>
<section id="more-hub-related-functions">
<h2>More Hub-Related Functions<a class="headerlink" href="#more-hub-related-functions" title="Permalink to this headline">¶</a></h2>
<dl class="py function">
<dt class="sig sig-object py" id="eventlet.hubs.get_hub">
<span class="sig-prename descclassname"><span class="pre">eventlet.hubs.</span></span><span class="sig-name descname"><span class="pre">get_hub</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#eventlet.hubs.get_hub" title="Permalink to this definition">¶</a></dt>
<dd><p>Get the current event hub singleton object.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>This is considered an internal API, and it might change
unexpectedly without being deprecated first.</p>
</div>
</dd></dl>

<dl class="py function">
<dt class="sig sig-object py" id="eventlet.hubs.get_default_hub">
<span class="sig-prename descclassname"><span class="pre">eventlet.hubs.</span></span><span class="sig-name descname"><span class="pre">get_default_hub</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#eventlet.hubs.get_default_hub" title="Permalink to this definition">¶</a></dt>
<dd><p>Select the default hub implementation based on what multiplexing
libraries are installed.  The order that the hubs are tried is:</p>
<ul class="simple">
<li><p>epoll</p></li>
<li><p>kqueue</p></li>
<li><p>poll</p></li>
<li><p>select</p></li>
</ul>
<p>It won’t automatically select the pyevent hub, because it’s not
python-thread-safe.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>This is considered an internal API, and it might change
unexpectedly without being deprecated first.</p>
</div>
</dd></dl>

<dl class="py function">
<dt class="sig sig-object py" id="eventlet.hubs.trampoline">
<span class="sig-prename descclassname"><span class="pre">eventlet.hubs.</span></span><span class="sig-name descname"><span class="pre">trampoline</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="pre">fd</span></em>, <em class="sig-param"><span class="pre">read=None</span></em>, <em class="sig-param"><span class="pre">write=None</span></em>, <em class="sig-param"><span class="pre">timeout=None</span></em>, <em class="sig-param"><span class="pre">timeout_exc=&lt;class</span> <span class="pre">'eventlet.timeout.Timeout'&gt;</span></em>, <em class="sig-param"><span class="pre">mark_as_closed=None</span></em><span class="sig-paren">)</span><a class="headerlink" href="#eventlet.hubs.trampoline" title="Permalink to this definition">¶</a></dt>
<dd><p>Suspend the current coroutine until the given socket object or file
descriptor is ready to <em>read</em>, ready to <em>write</em>, or the specified
<em>timeout</em> elapses, depending on arguments specified.</p>
<p>To wait for <em>fd</em> to be ready to read, pass <em>read</em> <code class="docutils literal notranslate"><span class="pre">=True</span></code>; ready to
write, pass <em>write</em> <code class="docutils literal notranslate"><span class="pre">=True</span></code>. To specify a timeout, pass the <em>timeout</em>
argument in seconds.</p>
<p>If the specified <em>timeout</em> elapses before the socket is ready to read or
write, <em>timeout_exc</em> will be raised instead of <code class="docutils literal notranslate"><span class="pre">trampoline()</span></code>
returning normally.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>This is considered an internal API, and it might change
unexpectedly without being deprecated first.</p>
</div>
</dd></dl>

</section>
</section>


            <div class="clearer"></div>
          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="index.html">Table of Contents</a></h3>
  <ul>
<li><a class="reference internal" href="#">Understanding Eventlet Hubs</a><ul>
<li><a class="reference internal" href="#how-the-hubs-work">How the Hubs Work</a></li>
<li><a class="reference internal" href="#more-hub-related-functions">More Hub-Related Functions</a></li>
</ul>
</li>
</ul>

  <h4>Previous topic</h4>
  <p class="topless"><a href="zeromq.html"
                        title="previous chapter">Zeromq</a></p>
  <h4>Next topic</h4>
  <p class="topless"><a href="testing.html"
                        title="next chapter">Testing Eventlet</a></p>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="_sources/hubs.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
<div 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>
</div>
<script>$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="right" >
          <a href="testing.html" title="Testing Eventlet"
             >next</a> |</li>
        <li class="right" >
          <a href="zeromq.html" title="Zeromq"
             >previous</a> |</li>
        <li class="nav-item nav-item-0"><a href="index.html">Eventlet 0.32.0 documentation</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">Understanding Eventlet Hubs</a></li> 
      </ul>
    </div>

    <div class="footer" role="contentinfo">
        &#169; Copyright 2005-2010, Eventlet Contributors.
      Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 4.1.2.
    </div>
<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-42952223-1', 'eventlet.net');
  ga('send', 'pageview');
</script>

  </body>
</html>