<html dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style id="owaParaStyle">P {
        MARGIN-BOTTOM: 0px; MARGIN-TOP: 0px
}
</style>
</head>
<body fPStyle="1" ocsi="0">
<div style="direction: ltr;font-family: Tahoma;color: #000000;font-size: 10pt;">
<p>Apart from the bug you found (and crafted by me), your example illustrates some of the shortcomings of monkeypatching.</p>
<p>The framework you are working with is clearly using socket.select() to do timeouts when listening to connections.  This is fairly common in Python (socketserver.py does this) but IMHO bad practice.</p>
<p>First, "accept" itself can timeout and python oughty to simply better support timeout in that api.</p>
<p>Second, there is no "asynchronous" select.  We monkeypatch select by farming it off to a worker thread.</p>
<p>In a stackless application this introduces latency.</p>
<p> </p>
<p>To accept a connection, your application has to wake up from select(), then enter an accept() state and then wake up from that.</p>
<p> </p>
<p>Select() is not a nice API and the reason we do IO in stackless (using multiple tasklets) is generally in order to avoid using select().</p>
<p> </p>
<p>K</p>
<div style="FONT-SIZE: 16px; FONT-FAMILY: Times New Roman; COLOR: #000000">
<hr tabindex="-1">
<div id="divRpF530641" style="DIRECTION: ltr"><font color="#000000" size="2" face="Tahoma"><b>From:</b> stackless-bounces@stackless.com [stackless-bounces@stackless.com] on behalf of lars van Gemerden [lars@rational-it.com]<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<br>
</font><br>
</div>
<div></div>
<div>
<div dir="ltr">OK, thanks for the input, 
<div><br>
</div>
<div>i am trying to get this to work, but i might have found a bug (which i find hard to debug):
<div><br>
</div>
<div>i have reimplemented the code above as:</div>
<div>--------------------------------------------------------------</div>
<div>
<div>import asyncore, traceback, sys, logging</div>
<div><br>
</div>
<div>import stacklesslib.main</div>
<div>import stacklesslib.app</div>
<div><br>
</div>
<div># the unittests use time.time() for various time tests.</div>
<div># Therefore, we must make sure that main uses this</div>
<div>from time import time as elapsed_time</div>
<div>stacklesslib.main.elapsed_time = elapsed_time</div>
<div><br>
</div>
<div>class MonkeyTasklets(object):</div>
<div>    </div>
<div>    _stop = False</div>
<div>    </div>
<div>    stacklesslib.app.install_stackless()</div>
<div>            </div>
<div>    @classmethod</div>
<div>    def run(cls, world, webserver = None, maxcount = None): #param killer is ignored</div>
<div>        world.flowmodel.start()</div>
<div>        if webserver:</div>
<div>            cls.server = webserver.start_server(world_model = world) #starts a tasklet for running the webserver</div>
<div>        counter = 0</div>
<div>        while not cls._stop or counter > maxcount:</div>
<div>            counter += 1</div>
<div>            tick_time = elapsed_time()    </div>
<div>            try:</div>
<div>                stacklesslib.main.mainloop.loop()</div>
<div>            except Exception as e:</div>
<div>                import asyncore</div>
<div>                if isinstance(e, ReferenceError):</div>
<div>                    print("run:EXCEPTION", str(e), asyncore.socket_map)</div>
<div>                else:</div>
<div>                    print("run:EXCEPTION", asyncore.socket_map)</div>
<div>                    traceback.print_exc()</div>
<div>                sys.exc_clear()</div>
<div>        world.flowmodel.stop()</div>
<div>    </div>
<div>    @classmethod</div>
<div>    def schedule(cls):</div>
<div>        stackless.schedule() </div>
<div>        </div>
<div>    @classmethod</div>
<div>    def tasklet(cls, func):</div>
<div>        return stackless.tasklet(func)</div>
<div>    </div>
<div>    @classmethod</div>
<div>    def stop(cls):</div>
<div>        if hasattr(cls, "server"):</div>
<div>            cls.server.stop()</div>
<div>        cls._stop = True</div>
<div>        </div>
<div><br>
</div>
<div>tasklets = MonkeyTasklets</div>
<div><br>
</div>
<div>--------------------------------------------------------------<br>
</div>
<div></div>
<div> and i get the exception:</div>
</div>
<div><br>
</div>
<div>File <span style="FONT-WEIGHT: 600; COLOR: rgb(0,0,102)">"d:\Documents\Code\python\floware\server\bottle.py"</span>, line 641, in
<span style="FONT-WEIGHT: 600; COLOR: rgb(34,119,34)">run</span><br>
  <span style="FONT-STYLE: italic">run(self, **kwargs)</span><br>
File <span style="FONT-WEIGHT: 600; COLOR: rgb(0,0,102)">"d:\Documents\Code\python\floware\server\bottle.py"</span>, line 2720, in
<span style="FONT-WEIGHT: 600; COLOR: rgb(34,119,34)">run</span><br>
  <span style="FONT-STYLE: italic">server.run(app)</span><br>
File <span style="FONT-WEIGHT: 600; COLOR: rgb(0,0,102)">"d:\Documents\Code\python\floware\server\webserver.py"</span>, line 329, in
<span style="FONT-WEIGHT: 600; COLOR: rgb(34,119,34)">run</span><br>
  <span style="FONT-STYLE: italic">self.server.serve_forever()</span><br>
File <span style="FONT-WEIGHT: 600; COLOR: rgb(0,0,102)">"C:\Python27\lib\SocketServer.py"</span>, line 236, in
<span style="FONT-WEIGHT: 600; COLOR: rgb(34,119,34)">serve_forever</span><br>
  <span style="FONT-STYLE: italic">poll_interval)</span><br>
File <span style="FONT-WEIGHT: 600; COLOR: rgb(0,0,102)">"C:\Python27\lib\SocketServer.py"</span>, line 155, in
<span style="FONT-WEIGHT: 600; COLOR: rgb(34,119,34)">_eintr_retry</span><br>
  <span style="FONT-STYLE: italic">return func(*args)</span><br>
File <span style="FONT-WEIGHT: 600; COLOR: rgb(0,0,102)">"d:\Documents\Code\python\floware\stacklesslib\replacements\select.py"</span>, line 27, in
<span style="FONT-WEIGHT: 600; COLOR: rgb(34,119,34)">select</span><br>
  <span style="FONT-STYLE: italic">return stacklesslib.threadpool.call_on_thread(real_select.select, args, kwargs)</span><br>
File <span style="FONT-WEIGHT: 600; COLOR: rgb(0,0,102)">"d:\Documents\Code\python\floware\stacklesslib\threadpool.py"</span>, line 123, in
<span style="FONT-WEIGHT: 600; COLOR: rgb(34,119,34)">call_on_thread</span><br>
  <span style="FONT-STYLE: italic">return tasklet_call(wrapped, dispatcher, timeout=timeout, onOrphaned=onOrphaned)</span><br>
File <span style="FONT-WEIGHT: 600; COLOR: rgb(0,0,102)">"d:\Documents\Code\python\floware\stacklesslib\util.py"</span>, line 209, in
<span style="FONT-WEIGHT: 600; COLOR: rgb(34,119,34)">tasklet_call</span><br>
  <span style="FONT-STYLE: italic">return channel_wait(chan, timeout)</span><br>
File <span style="FONT-WEIGHT: 600; COLOR: rgb(0,0,102)">"d:\Documents\Code\python\floware\stacklesslib\util.py"</span>, line 53, in
<span style="FONT-WEIGHT: 600; COLOR: rgb(34,119,34)">channel_wait</span><br>
  <span style="FONT-STYLE: italic">return chan.receive()</span><br>
File <span style="FONT-WEIGHT: 600; COLOR: rgb(0,0,102)">"d:\Documents\Code\python\floware\stacklesslib\util.py"</span>, line 192, in
<span style="FONT-WEIGHT: 600; COLOR: rgb(34,119,34)">helper</span><br>
  <span style="FONT-STYLE: italic">result = function(*args, **kwargs)</span><br>
<br>
<span style="FONT-WEIGHT: 600; COLOR: rgb(0,0,102)">TypeError: wrapped() argument after * must be a sequence, not function</span></div>
<div>--------------------------------------------------------------<span style="FONT-SIZE: large; FONT-WEIGHT: 600; COLOR: rgb(0,0,102)"><br>
</span></div>
<div><span style="COLOR: rgb(0,0,102)">is this something i am doing wrong or indeed a buggy in stacklesslib and if so, how can it be fixed?</span></div>
<div><span style="COLOR: rgb(0,0,102)"><br>
</span></div>
<div><span style="COLOR: rgb(0,0,102)">Cheers, Lars</span></div>
</div>
</div>
<div class="gmail_extra"><br>
<br>
<div class="gmail_quote">On Sun, Dec 1, 2013 at 4:05 AM, Richard Tew <span dir="ltr">
<<a href="mailto:richard.m.tew@gmail.com" target="_blank">richard.m.tew@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">
latest stacklesslib, i mean.<br>
<div class="HOEnZb">
<div class="h5"><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" value="+31626885539">
+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" value="+31626885539">
+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><br>
</div>
</div>
</blockquote>
</div>
<br>
<br clear="all">
<div><br>
</div>
-- <br>
====================================<br>
Lars van Gemerden<br>
<a href="mailto:lars@rational-it.com" target="_blank">lars@rational-it.com</a><br>
<span class="baec5a81-e4d6-4674-97f3-e9220f0136c1" style="WHITE-SPACE: nowrap">+31 6 26 88 55 39<a title="Call: +31 6 26 88 55 39" style="OVERFLOW: hidden; CURSOR: hand; BORDER-TOP: medium none; HEIGHT: 16px; BORDER-RIGHT: medium none; WIDTH: 16px; VERTICAL-ALIGN: middle; WHITE-SPACE: nowrap; RIGHT: 0px; BORDER-BOTTOM: medium none; POSITION: static !important; FLOAT: none; LEFT: 0px; MARGIN: 0px; BORDER-LEFT: medium none; DISPLAY: inline; TOP: 0px; BOTTOM: 0px" href="#"><img title="Call: +31 6 26 88 55 39" style="OVERFLOW: hidden; CURSOR: hand; BORDER-TOP: medium none; HEIGHT: 16px; BORDER-RIGHT: medium none; WIDTH: 16px; VERTICAL-ALIGN: middle; WHITE-SPACE: nowrap; RIGHT: 0px; BORDER-BOTTOM: medium none; POSITION: static !important; FLOAT: none; LEFT: 0px; MARGIN: 0px; BORDER-LEFT: medium none; DISPLAY: inline; TOP: 0px; BOTTOM: 0px" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAKLSURBVHjadJPfS5NhFMe/21xvuhXRyJAZroiSrJnbRdT7vrAf5HBaK5RABmEEwQIvkpZ/QRcWXdSFw5soKaF0F7qZeLO13mGBDpQsf5CoxVKHOt0Pctp2uvEdrzG/V+c553w/54HnPDIiQiGpPMETABoB2AAYd9MRAMMAvGmX+RcAyAoBVJ7gZQDtABworH4AHWmX+bOMZdkjCoXiUzabvcAwzPSsob5p/VTNY9GcdpnxdmYZ9wJThSCtCr1e/4XjuNPd3d1KjUZzaGbI27ysqzGQoggAsLa1A7ehArrDxfDNr0oBlQB+wmKxbJFEL968SxoamsjkHaPU9l9piUo6A0RE1DG2QCWdASrpDAzJM5kMI8XecdjVxfEl+K9dxFgsgUvvR6HyBKHyBAEATyKLeGSsENuNcqk5kUjEGm7fzcYqr0ClVODl99+YXEvl6+c1amjVe+ahiGGYaUEQKnmeh91uL43rqheixjpdmzCL11er0PcjhrTLvMfUJsyKYUSeyWQ6enp6tgCgrKxsfbP8bB8AdE1G89cOReMAgOv+Cag8QXRNRkXAsDwcDr+am5tLCYKA3t7eo2dG+1vVK/MfpRPtA+MIReMYaKj+/xm9MiICx3EmpVL5wefzFavValis1u1vvHMkdfykCQC0kSGUTo+Ajmnx1dSC7IGD+UUCEYGIwLKsyWazrSeTSSIiMpnNf7Ttz5+ec96fr7/VnE0mk+QfHMzV3WjcKH/4rEr05QGFIA6HY4llWRLPRER+v3/HYrFMFQSIkNra2tVQKJSlfcSyLO0LECFWq3XF6XRGA4HAptTsdrsXeZ6fEHtl+31nAOA4rkUulz/I5XL63dQGgHEAN8Ph8AYA/BsAt4ube4GblQIAAAAASUVORK5CYII="></a></span><br>
==================================== </div>
</div>
</div>
</div>
</body>
</html>