<div dir="ltr">Sure, no problem, i'll try to keep it short;<div><br></div><div>I have a (stackless) python design gui application built with Qt/PySide. With this a designer can graphically (drag & drop, blocks & arrows) design:</div>
<div><br></div><div> - a datamodel (sqlalchemy, currently sqlite), </div><div> - process flow, with steps that can basically execute any python functon, but e.g. also generate dynamic web page elements (push & pull, execution using tasklets), </div>
<div> - end user web interfaces (implemented in bottle/html/ajax, python simple server for now) and </div><div> - role model(determines what users get access to which web interfaces).</div><div><br></div><div>And with one click (for demo purposes) deploy the whole shebang locally as a web application server. </div>
<div><br></div><div>Some process flow steps generate web interfaces for the end users. The the application server part that executes the process flow, uses tasklets to be able to run process steps asynchronously (e.g. not stopping while waiting for user input)</div>
<div><br></div><div>What i would like to do is start and be able to stop the web application, including the web server from the designer gui and have the process execution part of the server not block while waiting on http requests.</div>
<div><br></div><div>previously i deep copied the combined model (data, process, role/web gui) and started the app server server based on that model in a separate thread (oh, i created a tasklet for the bottle microframework run() method, which includes the mainn server loop()) ; I only called schedule() on each web server request to be able to do anything outside the server mainloop. However that had the effect that process steps where not executed as long as the end user sent no requests (some processes do not have any web component). </div>
<div><br></div><div>After monkeypatching, the server did what it was supposed to (run both internal processes as well as processes with a web component), however because the server thread was now a tasklet, the designer gui did not respond anymore.</div>
<div><br></div><div>After using <span style="font-size:12.727272033691406px;font-family:arial,sans-serif">thread.real_thread.start_new_</span><span style="font-size:12.727272033691406px;font-family:arial,sans-serif">thread to fix this, the server seemed to run until the first http request, after which the server app got stuck in Trigger.run (see last mail).</span></div>
<div><span style="font-size:12.727272033691406px;font-family:arial,sans-serif"><br></span></div><div><span style="font-size:12.727272033691406px;font-family:arial,sans-serif">What i have also tried is to put stackless,schedule() in the main webserver loop. That seemed to work pretty well, apart from the occasional crash :-(; any ideas what that might be?</span></div>
<div><span style="font-size:12.727272033691406px;font-family:arial,sans-serif"><br></span></div><div><span style="font-size:12.727272033691406px;font-family:arial,sans-serif">Hope this helps, it is a somewhat complicated project (but most of it runs pretty smoothly by now).</span></div>
<div><span style="font-size:12.727272033691406px;font-family:arial,sans-serif"><br></span></div><div><font face="arial, sans-serif">Cheers, Lars</font></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Wed, Dec 4, 2013 at 11:49 AM, Kristján Valur Jónsson <span dir="ltr"><<a href="mailto:kristjan@ccpgames.com" target="_blank">kristjan@ccpgames.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">






<div lang="EN-GB" link="blue" vlink="purple">
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">I’m sorry Lars,
<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">but I have (sort-of) lost track of what it is that you are trying to do
</span><span style="font-size:11.0pt;font-family:Wingdings;color:#1f497d">J</span><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Could you try to summarize what it is you are trying to achieve? What are the components of your application?<u></u><u></u></span></p>

<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">K<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"><u></u> <u></u></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt">
<div>
<div style="border:none;border-top:solid #b5c4df 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> <a href="mailto:stackless-bounces@stackless.com" target="_blank">stackless-bounces@stackless.com</a> [mailto:<a href="mailto:stackless-bounces@stackless.com" target="_blank">stackless-bounces@stackless.com</a>]
<b>On Behalf Of </b>lars van Gemerden<br>
<b>Sent:</b> 3. desember 2013 16:22</span></p><div><div class="h5"><br>
<b>To:</b> The Stackless Python Mailing List<br>
<b>Subject:</b> Re: [Stackless] monkeypatching<u></u><u></u></div></div><p></p>
</div>
</div><div><div class="h5">
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">I have tried the real_thread approach as below, but it seems to get stuck in a loop that calls stackless.schedule().  Isn't the webserver getting scheduled (anymore, it runs at the start) ? <u></u><u></u></p>

<div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">----------------------------------------------------------------<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Where the program gets stuck (if i don't use this class, all runs well, although pretty slow compared to without the real thread):<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<blockquote style="margin-left:30.0pt;margin-right:0cm">
<div>
<div>
<p class="MsoNormal">class Trigger(BaseTrigger):                      #part of flowmodel, see below<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">    def start(self):                                       #called from flowmodel.start() see MonkeyTasklets.run below<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">        super(Trigger, self).start()        <u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">        stackless.tasklet(self.run)() <u></u><u></u></p>
</div>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<div>
<p class="MsoNormal">    def condition(self):<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">        raise NotImplementedError() <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">   <u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">    def run(self):<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">        while True:                                  #gets stuck here<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">            if self.condition():                    #returns False<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">                self.trigger()<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">            else:<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">                stackless.schedule()<u></u><u></u></p>
</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">where i create the real thread:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<blockquote style="margin-left:30.0pt;margin-right:0cm">
<div>
<div>
<p class="MsoNormal">    def run_server(self, config = None, threaded = False):                 # in this case threaded = True<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">        from flow.tasklets import MonkeyTasklets<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">        clone = self.create_run_clone(config)                  #deepcopies all models in which tasklets are created (except webserver tasklet)<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">        clone.tasklets = MonkeyTasklets()                       #see below<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">        if threaded:<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">            import thread<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">            def run_function(world):<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">                clone.tasklets.run(world = world, <u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">                                             webserver = webserver,<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">                                             maxcount = world.config.RUN_LIMIT)<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">            thread.real_thread.start_new_thread(run_function, (clone,))                  #create real thread<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">        else:<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">            clone.tasklets.run(clone, webserver, maxcount = clone.config.RUN_LIMIT)<u></u><u></u></p>
</div>
</div>
<div>
<div>
<p class="MsoNormal">        return clone                                                                                                       #clone is returned to be able to stop the thread via clone.tasklets.stop = True<u></u><u></u></p>

</div>
</div>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">This is where the main loop runs:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<blockquote style="margin-left:30.0pt;margin-right:0cm">
<div>
<p class="MsoNormal">class MonkeyTasklets(object):<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"> stacklesslib.app.install_stackless()<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    def __init__(self):<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        self.stop = None                              #used to stop the loop and therefore the thread<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">            <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    def run(self, world, webserver = None, maxcount = None): <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        self.stop = False<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        world.flowmodel.start()<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        if webserver:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">            webserver.start_server(world_model = world)                        #creates a tasklet for the webserver<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        counter = 0<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        while not self.stop or counter > maxcount:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">            counter += 1<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">            try:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                stacklesslib.main.mainloop.loop()<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">            except Exception as e:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                import asyncore<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                if isinstance(e, ReferenceError):<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                    print("run:EXCEPTION", str(e), asyncore.socket_map)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                else:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                    print("run:EXCEPTION", asyncore.socket_map)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                    traceback.print_exc()<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                sys.exc_clear()<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        if webserver:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                webserver.stop()<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        world.flowmodel.stop()<u></u><u></u></p>
</div>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">monkeypatching takes place at the start of the program.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I would like to get this running (because i am into it right now), but it isn't crucial.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Cheers, Lars<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><u></u> <u></u></p>
<div>
<p class="MsoNormal">On Mon, Dec 2, 2013 at 9:52 AM, Kristján Valur Jónsson <<a href="mailto:kristjan@ccpgames.com" target="_blank">kristjan@ccpgames.com</a>> wrote:<u></u><u></u></p>
<div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Well, that’s the thing, the way we “currently” do monkeypatching, it is an all-or-nothing approach.</span><u></u><u></u></p>

<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Either you replace your entire application’s “threading” usage with fake threads from stackless,
 or you don’t.</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Although, as a convention, I have put in the old modules as _<i>real</i>_* attributes inside the
 fake ones.  This helps, if your code is aware of this trick.</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"> </span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">A few years ago, Jack Diedrich had a PyCon talk about using context managers to temporarily monkeypatch
 code.</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">This would be useful, e.g. if you wanted to start up part of your application in such a way.</span><u></u><u></u></p>

<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">Then you could do something like:</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"> </span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">with stackless.monkeypatch.patch_all():</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">  import flask</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">  import mywebserver</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"> </span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">import myGUI # using regular threads.</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"> </span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">I’m sure we could re-engineer stacklesslib.monkeypatch to make use of this pattern.</span><u></u><u></u></p>

<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"> </span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d">K</span><u></u><u></u></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1f497d"> </span><u></u><u></u></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt">
<div>
<div style="border:none;border-top:solid #b5c4df 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span lang="EN-US" style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span lang="EN-US" style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">
<a href="mailto:stackless-bounces@stackless.com" target="_blank">stackless-bounces@stackless.com</a> [mailto:<a href="mailto:stackless-bounces@stackless.com" target="_blank">stackless-bounces@stackless.com</a>]
<b>On Behalf Of </b>lars van Gemerden<br>
<b>Sent:</b> 2. desember 2013 01:26</span><u></u><u></u></p>
<div>
<div>
<p class="MsoNormal"><br>
<b>To:</b> The Stackless Python Mailing List<br>
<b>Subject:</b> Re: [Stackless] monkeypatching<u></u><u></u></p>
</div>
</div>
</div>
</div>
<div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
<div>
<p class="MsoNormal">thank you for the help, <u></u><u></u></p>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">With the fix it works now; i have one problem left, is that when i start the server from the gui, the server runs, but the (Qt/PySide) gui becomes unresponsive. Before, i started
 the web app and server in a separate thread (and had the scheduler run in that), but that probably  wont work if threads are replaced with tasklets (if i understood the monkeypatching somewhat). <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">Does anyone have any ideas how to solve that (to keep the gui responsive, also to be able to stop the server)?  Before i tried multiprocessing, but that led to a lot of servers
 running :-)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">In another experiment I have overridden the server loop serve_forever() to call stackless.schedule() (or rather tasklets.schedule() in the code above). This seems to work apart
 from an occasional crash (weird attribute error for (my subclass of) WSGIServer).<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">Also thanks a lot for putting up the 2.7.5 64 bit binaries!! It finally let me run the demo on my Windows 8 laptop (no idea why, something to do with PySide 32bit and win8 probably)<u></u><u></u></p>

</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">Cheers, Lars<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"> <u></u><u></u></p>
<div>
<p class="MsoNormal">On Mon, Dec 2, 2013 at 12:36 AM, Kristján Valur Jónsson <<a href="mailto:kristjan@ccpgames.com" target="_blank">kristjan@ccpgames.com</a>> wrote:<u></u><u></u></p>
<div>
<div>
<p><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">A bug!</span><u></u><u></u></p>
<p><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">in threadpool.py, replace the final line with:</span><u></u><u></u></p>
<p><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> </span><u></u><u></u></p>
<p><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">return tasklet_call(wrapped, dispatcher=dispatcher, timeout=timeout, onOrphaned=onOrphaned)</span><u></u><u></u></p>
<p><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">Needs more unittests :)</span><u></u><u></u></p>
<p><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> </span><u></u><u></u></p>
<p><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">K</span><u></u><u></u></p>
<div>
<div>
<div class="MsoNormal" align="center" style="text-align:center">
<hr size="2" width="100%" align="center">
</div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-family:"Tahoma","sans-serif"">
<a href="mailto:stackless-bounces@stackless.com" target="_blank">stackless-bounces@stackless.com</a> [<a href="mailto:stackless-bounces@stackless.com" target="_blank">stackless-bounces@stackless.com</a>] on behalf of lars van Gemerden [<a href="mailto:lars@rational-it.com" target="_blank">lars@rational-it.com</a>]<br>

<b>Sent:</b> Sunday, December 01, 2013 1:58 PM<br>
<b>To:</b> The Stackless Python Mailing List<br>
<b>Subject:</b> Re: [Stackless] monkeypatching</span><u></u><u></u></p>
</div>
</div>
<div>
<div>
<div>
<div>
<p class="MsoNormal">OK, thanks for the input, 
<u></u><u></u></p>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">i am trying to get this to work, but i might have found a bug (which i find hard to debug):
<u></u><u></u></p>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">i have reimplemented the code above as:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">--------------------------------------------------------------<u></u><u></u></p>
</div>
<div>
<div>
<p class="MsoNormal">import asyncore, traceback, sys, logging<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">import stacklesslib.main<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">import stacklesslib.app<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"># the unittests use time.time() for various time tests.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"># Therefore, we must make sure that main uses this<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">from time import time as elapsed_time<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">stacklesslib.main.elapsed_time = elapsed_time<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">class MonkeyTasklets(object):<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    _stop = False<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    stacklesslib.app.install_stackless()<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">            <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    @classmethod<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    def run(cls, world, webserver = None, maxcount = None): #param killer is ignored<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        world.flowmodel.start()<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        if webserver:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">            cls.server = webserver.start_server(world_model = world) #starts a tasklet for running the webserver<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        counter = 0<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        while not cls._stop or counter > maxcount:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">            counter += 1<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">            tick_time = elapsed_time()    <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">            try:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                stacklesslib.main.mainloop.loop()<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">            except Exception as e:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                import asyncore<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                if isinstance(e, ReferenceError):<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                    print("run:EXCEPTION", str(e), asyncore.socket_map)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                else:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                    print("run:EXCEPTION", asyncore.socket_map)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                    traceback.print_exc()<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">                sys.exc_clear()<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        world.flowmodel.stop()<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    @classmethod<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    def schedule(cls):<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        stackless.schedule() <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    @classmethod<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    def tasklet(cls, func):<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        return stackless.tasklet(func)<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    @classmethod<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">    def stop(cls):<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        if hasattr(cls, "server"):<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">            cls.server.stop()<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        cls._stop = True<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">        <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">tasklets = MonkeyTasklets<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">--------------------------------------------------------------<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> and i get the exception:<u></u><u></u></p>
</div>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">File <b><span style="color:#000066">"d:\Documents\Code\python\floware\server\bottle.py"</span></b>, line 641, in
<b><span style="color:#227722">run</span></b><br>
  <i>run(self, **kwargs)</i><br>
File <b><span style="color:#000066">"d:\Documents\Code\python\floware\server\bottle.py"</span></b>, line 2720, in
<b><span style="color:#227722">run</span></b><br>
  <i>server.run(app)</i><br>
File <b><span style="color:#000066">"d:\Documents\Code\python\floware\server\webserver.py"</span></b>, line 329, in
<b><span style="color:#227722">run</span></b><br>
  <i>self.server.serve_forever()</i><br>
File <b><span style="color:#000066">"C:\Python27\lib\SocketServer.py"</span></b>, line 236, in
<b><span style="color:#227722">serve_forever</span></b><br>
  <i>poll_interval)</i><br>
File <b><span style="color:#000066">"C:\Python27\lib\SocketServer.py"</span></b>, line 155, in
<b><span style="color:#227722">_eintr_retry</span></b><br>
  <i>return func(*args)</i><br>
File <b><span style="color:#000066">"d:\Documents\Code\python\floware\stacklesslib\replacements\select.py"</span></b>, line 27, in
<b><span style="color:#227722">select</span></b><br>
  <i>return stacklesslib.threadpool.call_on_thread(real_select.select, args, kwargs)</i><br>
File <b><span style="color:#000066">"d:\Documents\Code\python\floware\stacklesslib\threadpool.py"</span></b>, line 123, in
<b><span style="color:#227722">call_on_thread</span></b><br>
  <i>return tasklet_call(wrapped, dispatcher, timeout=timeout, onOrphaned=onOrphaned)</i><br>
File <b><span style="color:#000066">"d:\Documents\Code\python\floware\stacklesslib\util.py"</span></b>, line 209, in
<b><span style="color:#227722">tasklet_call</span></b><br>
  <i>return channel_wait(chan, timeout)</i><br>
File <b><span style="color:#000066">"d:\Documents\Code\python\floware\stacklesslib\util.py"</span></b>, line 53, in
<b><span style="color:#227722">channel_wait</span></b><br>
  <i>return chan.receive()</i><br>
File <b><span style="color:#000066">"d:\Documents\Code\python\floware\stacklesslib\util.py"</span></b>, line 192, in
<b><span style="color:#227722">helper</span></b><br>
  <i>result = function(*args, **kwargs)</i><br>
<br>
<b><span style="color:#000066">TypeError: wrapped() argument after * must be a sequence, not function</span></b><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">--------------------------------------------------------------<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="color:#000066">is this something i am doing wrong or indeed a buggy in stacklesslib and if so, how can it be fixed?</span><u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="color:#000066">Cheers, Lars</span><u></u><u></u></p>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"> <u></u><u></u></p>
<div>
<p class="MsoNormal">On Sun, Dec 1, 2013 at 4:05 AM, Richard Tew <<a href="mailto:richard.m.tew@gmail.com" target="_blank">richard.m.tew@gmail.com</a>> wrote:<u></u><u></u></p>
<p class="MsoNormal">latest stacklesslib, i mean.<u></u><u></u></p>
<div>
<div>
<p class="MsoNormal"><br>
On 12/1/13, Richard Tew <<a href="mailto:richard.m.tew@gmail.com" target="_blank">richard.m.tew@gmail.com</a>> wrote:<br>
> Hi Lars,<br>
><br>
> stacklessio is internal ccp stuff.<br>
><br>
> main.py in stacklesslib is pretty much all you need to understand,<br>
> beyond calling patch_all().  It is a scheduler, and makes your Open<br>
> scheduler redundant.<br>
><br>
> I suggest you get the latest stacklessio from:<br>
><br>
> <a href="https://bitbucket.org/krisvale/stacklesslib" target="_blank">https://bitbucket.org/krisvale/stacklesslib</a><br>
><br>
> And then you check out test / teststdlibunittests.py, which is a short<br>
> example of monkey patching and running the stacklesslib scheduler.<br>
><br>
> Cheers,<br>
> Richard.<br>
><br>
> On 12/1/13, lars van Gemerden <<a href="mailto:lars@rational-it.com" target="_blank">lars@rational-it.com</a>> wrote:<br>
>> sorry,<br>
>><br>
>> patch_all seemed to simple, question was a bit rethoric ;-) tried it 2<br>
>> mins<br>
>> after pressing send just in case and indeed no cigar.<br>
>><br>
>> I am trying to get this demo running and all kinds of last minute #### is<br>
>> popping up.<br>
>><br>
>> I tried reading the source but it doesn't click; i am not familiar with<br>
>> using sockets etc. at all.<br>
>><br>
>> e.g.<br>
>><br>
>> - do i need 'stacklessio'?<br>
>> - can i (essentially) just put a stackless.schedule() (or<br>
>> OpenTasklets.schedule() in the code below) in the serve_forever loop?<br>
>> - will this work at all with an adapted scheduler like this:<br>
>><br>
>> class OpenTasklets(object):<br>
>><br>
>>     _stop = False<br>
>><br>
>>     @classmethod<br>
>>     def run(cls, maxcount = None):<br>
>>         cls.schedule_channel = stackless.channel()<br>
>>         cls.schedule_channel.preference = 1<br>
>>         counter = 0<br>
>>         OpenTasklets._stop = False<br>
>>         while stackless.getruncount() != 1:<br>
>>             stackless.run()<br>
>>             cls.reschedule(cls._stop or (maxcount and counter ><br>
>> maxcount))<br>
>>             counter += 1<br>
>><br>
>>     @classmethod<br>
>>     def schedule(cls):<br>
>>         if cls.schedule_channel.receive():<br>
>>             raise TaskletExit<br>
>><br>
>>     @classmethod<br>
>>     def reschedule(cls, stop = False):<br>
>>         while cls.schedule_channel.balance < 0:<br>
>>             cls.schedule_channel.send(stop)<br>
>><br>
>> Any help is appreciated ..<br>
>><br>
>> Lars<br>
>><br>
>><br>
>><br>
>><br>
>> On Sat, Nov 30, 2013 at 8:53 PM, Richard Tew<br>
>> <<a href="mailto:richard.m.tew@gmail.com" target="_blank">richard.m.tew@gmail.com</a>>wrote:<br>
>><br>
>>> Lars :-)<br>
>>><br>
>>> Yes, there is no documentation for stacklesslib yet.  To use it, you<br>
>>> really need to be willing to read the source code.<br>
>>><br>
>>> You should already know whether calling patch_all would be enough.  It<br>
>>> would have been something you could have tried immediately, rather<br>
>>> than asking the list and waiting.<br>
>>><br>
>>> Cheers,<br>
>>> Richard.<br>
>>><br>
>>> On 11/30/13, lars van Gemerden <<a href="mailto:lars@rational-it.com" target="_blank">lars@rational-it.com</a>> wrote:<br>
>>> > Hi all,<br>
>>> ><br>
>>> > I though i could avoid it to run my demo but it seems i need to let<br>
>>> > the<br>
>>> > webserver (simple server?, single thread, 'bottle' micro framework)<br>
>>> > yield<br>
>>> > to the scheduler i am using. I have downloaded stacklesslib 1.0.3, but<br>
>>> > can't find any documentation to help with monkeypatching.<br>
>>> ><br>
>>> > - Do i just run patch_all at the start of the program?<br>
>>> ><br>
>>> > Any help is very welcome ..<br>
>>> ><br>
>>> > Cheers, Lars<br>
>>> ><br>
>>> > --<br>
>>> > ====================================<br>
>>> > Lars van Gemerden<br>
>>> > <a href="mailto:lars@rational-it.com" target="_blank">lars@rational-it.com</a><br>
>>> > <a href="tel:%2B31%206%2026%2088%2055%2039" target="_blank">+31 6 26 88 55 39</a><br>
>>> > ====================================<br>
>>> ><br>
>>><br>
>>> _______________________________________________<br>
>>> Stackless mailing list<br>
>>> <a href="mailto:Stackless@stackless.com" target="_blank">Stackless@stackless.com</a><br>
>>> <a href="http://www.stackless.com/mailman/listinfo/stackless" target="_blank">
http://www.stackless.com/mailman/listinfo/stackless</a><br>
>>><br>
>><br>
>><br>
>><br>
>> --<br>
>> ====================================<br>
>> Lars van Gemerden<br>
>> <a href="mailto:lars@rational-it.com" target="_blank">lars@rational-it.com</a><br>
>> <a href="tel:%2B31%206%2026%2088%2055%2039" target="_blank">+31 6 26 88 55 39</a><br>
>> ====================================<br>
>><br>
><br>
<br>
_______________________________________________<br>
Stackless mailing list<br>
<a href="mailto:Stackless@stackless.com" target="_blank">Stackless@stackless.com</a><br>
<a href="http://www.stackless.com/mailman/listinfo/stackless" target="_blank">http://www.stackless.com/mailman/listinfo/stackless</a><u></u><u></u></p>
</div>
</div>
</div>
<p class="MsoNormal"><br>
<br clear="all">
<u></u><u></u></p>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<p class="MsoNormal">--
<br>
====================================<br>
Lars van Gemerden<br>
<a href="mailto:lars@rational-it.com" target="_blank">lars@rational-it.com</a><u></u><u></u></p>
</div>
</div>
<p class="MsoNormal"><a href="tel:%2B31%206%2026%2088%2055%2039" target="_blank">+31 6 26 88 55 39</a><a href="#142bd3b0dfe237d2_142b282cef7bdad7_142b0afb3d212348_" title="Call: +31 6 26 88 55 39"><span style="color:windowtext;text-decoration:none"><br>

==================================== </span></a><u></u><u></u></p>
</div>
</div>
</div>
</div>
</div>
<p class="MsoNormal"><a href="#142bd3b0dfe237d2_142b282cef7bdad7_142b0afb3d212348_" title="Call: +31 6 26 88 55 39"><span style="color:windowtext;text-decoration:none"><br>
_______________________________________________<br>
Stackless mailing list<br>
</span>Stackless@stackless.com<span style="color:windowtext;text-decoration:none"><br>
</span>http://www.stackless.com/mailman/listinfo/stackless</a><u></u><u></u></p>
</div>
<p class="MsoNormal"><a href="#142bd3b0dfe237d2_142b282cef7bdad7_142b0afb3d212348_" title="Call: +31 6 26 88 55 39"><span style="color:windowtext;text-decoration:none"><br>
<br clear="all">
</span></a><u></u><u></u></p>
<div>
<p class="MsoNormal"><a href="#142bd3b0dfe237d2_142b282cef7bdad7_142b0afb3d212348_" title="Call: +31 6 26 88 55 39"><span style="color:windowtext;text-decoration:none"> </span></a><u></u><u></u></p>
</div>
<p class="MsoNormal"><a href="#142bd3b0dfe237d2_142b282cef7bdad7_142b0afb3d212348_" title="Call: +31 6 26 88 55 39"><span style="color:windowtext;text-decoration:none">--
<br>
====================================<br>
Lars van Gemerden<br>
</span>lars@rational-it.com<span style="color:windowtext;text-decoration:none"><br>
+31 6 26 88 55 39<br>
==================================== </span></a><u></u><u></u></p>
</div>
</div>
</div>
</div>
</div>
</div>
<p class="MsoNormal"><br>
_______________________________________________<br>
Stackless mailing list<br>
<a href="mailto:Stackless@stackless.com" target="_blank">Stackless@stackless.com</a><br>
<a href="http://www.stackless.com/mailman/listinfo/stackless" target="_blank">http://www.stackless.com/mailman/listinfo/stackless</a><u></u><u></u></p>
</div>
<p class="MsoNormal"><br>
<br clear="all">
<u></u><u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<p class="MsoNormal">-- <br>
====================================<br>
Lars van Gemerden<br>
<a href="mailto:lars@rational-it.com" target="_blank">lars@rational-it.com</a><br>
<a href="tel:%2B31%206%2026%2088%2055%2039" value="+31626885539" target="_blank">+31 6 26 88 55 39</a><br>
==================================== <u></u><u></u></p>
</div>
</div></div></div>
</div>
</div>

<br>_______________________________________________<br>
Stackless mailing list<br>
<a href="mailto:Stackless@stackless.com">Stackless@stackless.com</a><br>
<a href="http://www.stackless.com/mailman/listinfo/stackless" target="_blank">http://www.stackless.com/mailman/listinfo/stackless</a><br></blockquote></div><br><br clear="all"><div><br></div>-- <br>====================================<br>
Lars van Gemerden<br><a href="mailto:lars@rational-it.com">lars@rational-it.com</a><br>+31 6 26 88 55 39<br>====================================
</div>