<br><br><div class="gmail_quote">On Mon, Feb 20, 2012 at 8:09 PM, Eric Larson <span dir="ltr"><<a href="mailto:eric@ionrock.org">eric@ionrock.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
CherryPy provides a bus that allows you to add events to the web server process. It is specified pretty clearly and CherryPy recently made it available as a standalone package, Magicbus (<a href="https://bitbucket.org/cherrypy/magicbus/overview" target="_blank">https://bitbucket.org/cherrypy/magicbus/overview</a>). Specifically it allows you to send events on different signals the main server process might get. You can also use it for a general bus within the app server, but at its most basic level, the goal was to make the stop/start/restart events easy to hook into.<br>
<br>
I've found it to be really helpful for managing processes and wrote a simple supervisor-ish app called Dad using it (<a href="http://bitbucket.org/elarson/dad" target="_blank">http://bitbucket.org/elarson/dad</a>).<br>
</blockquote><div><br>Thanks for the pointer -- that looks pretty neat<br><br>I would be more interested though, in defining an extension to the WSGI standard<br><br>A rough example of what I am talking about:<br><br>If I take the wsgiref doc, here's an example of a minimal wsgi application (myapp.py):<br>
<br>
<div style class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">wsgiref.simple_server</span> <span class="kn">import</span> <span class="n">make_server</span><br><br><span class="k">def</span> <span class="nf">hello_world_app</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
<span class="n">status</span> <span class="o">=</span> <span class="s">'200 OK'</span> <span class="c"># HTTP Status</span>
<span class="n">headers</span> <span class="o">=</span> <span class="p">[(</span><span class="s">'Content-type'</span><span class="p">,</span> <span class="s">'text/plain'</span><span class="p">)]</span>
<span class="n">start_response</span><span class="p">(</span><span class="n">status</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
<span class="k">return</span> <span class="p">[</span><span class="s">"Hello World"</span><span class="p">]</span>
<span class="n">def main():<br></span><span class="o"></span> <span class="n">return make_server</span><span class="p">(</span><span class="s">''</span><span class="p">,</span> <span class="mi">8000</span><span class="p">,</span> <span class="n">hello_world_app</span><span class="p">)</span><br>
<span class="k"></span> <br><br></pre></div>
</div>That module can be run by any web server out there that understands WSGI. For instance, with gunicorn I can do:<br><br>$ gunicorn myapp:main<br><br>What I am talking about is a second entry point for the shutdown - example:<br>
<br>
<div style class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">wsgiref.simple_server</span> <span class="kn">import</span> <span class="n">make_server</span><br><br><span class="k">def</span> <span class="nf">hello_world_app</span><span class="p">(</span><span class="n">environ</span><span class="p">,</span> <span class="n">start_response</span><span class="p">):</span>
<span class="n">status</span> <span class="o">=</span> <span class="s">'200 OK'</span> <span class="c"># HTTP Status</span>
<span class="n">headers</span> <span class="o">=</span> <span class="p">[(</span><span class="s">'Content-type'</span><span class="p">,</span> <span class="s">'text/plain'</span><span class="p">)]</span>
<span class="n">start_response</span><span class="p">(</span><span class="n">status</span><span class="p">,</span> <span class="n">headers</span><span class="p">)</span>
<span class="k">return</span> <span class="p">[</span><span class="s">"Hello World"</span><span class="p">]</span>
<span class="n">def main():<br></span><span class="o"></span> <span class="n"> return make_server</span><span class="p">(</span><span class="s">''</span><span class="p">,</span> <span class="mi">8000</span><span class="p">,</span> <span class="n">hello_world_app</span><span class="p">)</span><br>
<br>def shutdown(): # or maybe something else as an argument I don't know<br> do_some_cleanup()<br><span class="k"></span> <br><br></pre></div>
</div>
And point the shutdown callable to a web server:<br><br>$ gunicorn myapp:main myapp:shutdown<br><br>If this is defined in the WSGI standard it means any wsgi web server could call shutdown() , not only gunicorn<br><br>Cheers<br>
Tarek<br><br><br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
HTH<br>
<br>
Eric<br>
<br>
--<br>
Eric Larson<br>
<div><div class="h5"><br>
<br>
On Monday, February 20, 2012 at 10:03 AM, Tarek Ziadé wrote:<br>
<br>
> Hello<br>
><br>
> I need to be able to call a function when the web application shuts down (SIGTERM/SIGINT) -- the use case is to stop a background thread.<br>
><br>
> I am currently using signals because it seems to be the most clean way to do this. atexit is much trickier since you don't know when it's going to get called and you might try to call objects that were garbage collected unless you hack something to keep references alive.<br>
><br>
> But signals are also tricky beasts since you may compete with other code that are listening to them. For instance mod_wsgi don't like apps that have signal handlers.<br>
><br>
> Anyways, the bottom line is that the cleanest way to do this -- as per Chris McDonough idea, would be to introduce in the WSGI protocol a "shutdown" function the servers would be obligated to call before exiting.<br>
><br>
> I am not sure yet about its arguments, maybe a signum + frame or simply an exit code...<br>
><br>
> But how do you like the idea ? That would solve for me the problem of having to deal differently here depending on if I am called with mod_wsgi or gunicorn or xxx<br>
><br>
><br>
> Cheers<br>
> Tarek<br>
><br>
> --<br>
> Tarek Ziadé | <a href="http://ziade.org" target="_blank">http://ziade.org</a><br>
</div></div>> _______________________________________________<br>
> Web-SIG mailing list<br>
> <a href="mailto:Web-SIG@python.org">Web-SIG@python.org</a> (mailto:<a href="mailto:Web-SIG@python.org">Web-SIG@python.org</a>)<br>
> Web SIG: <a href="http://www.python.org/sigs/web-sig" target="_blank">http://www.python.org/sigs/web-sig</a><br>
> Unsubscribe: <a href="http://mail.python.org/mailman/options/web-sig/eric%40ionrock.org" target="_blank">http://mail.python.org/mailman/options/web-sig/eric%40ionrock.org</a><br>
<br>
<br>
<br>
</blockquote></div><br><br clear="all"><br>-- <br>Tarek Ziadé | <a href="http://ziade.org">http://ziade.org</a><br>