[Stackless] Monkeypatching

Andrew Francis andrewfr_ice at yahoo.com
Thu Dec 12 17:27:45 CET 2013


Hi Lars:

What I am suggesting is:

>def serve_forever(self, poll_interval=0.5):
>        self._BaseServer__is_shut_down.clear()
>        try:
>            while not self._BaseServer__shutdown_request:
>                r, w, e = SocketServer._eintr_retry(select.select, [self], [], [], >poll_interval)

write a function that does:

if stackless.getruncount() > 1:
    # we want to give tasklets that are ready to run a chance in case
    # of  low I/O  activity
    poll_interval = .5
else:
    poll_interval = some_other_large_value
r, w, e = SocketServer._eintr_retry(select.select, [self], [], [], poll_interval)


My thinking is you want to cut down on needless returns and expensive system calls. 

I am also assuming you don't have some timer function that depends on the polling...

Cheers,
Andrew



On Thursday, December 12, 2013 5:15 AM, lars van Gemerden <lars at rational-it.com> wrote:
 
what i have now (in relation to the default simpleserver use of bottle.py) is:

#-------------------------------------------------------------------------------------
from bottle import Bottle, ServerAdapter

from wsgiref.simple_server import WSGIServer, make_server, WSGIRequestHandler
import select, SocketServer

class StacklessWSGIServer(WSGIServer): 
    def serve_forever(self, poll_interval=0.5):
        self._BaseServer__is_shut_down.clear()
        try:
            while not self._BaseServer__shutdown_request:
                r, w, e = SocketServer._eintr_retry(select.select, [self], [], [], poll_interval)
                if self in r:
                    self._handle_request_noblock()
                tasklets.schedule()
        finally:
            self._BaseServer__shutdown_request = False
            self._BaseServer__is_shut_down.set()
        
class MyWSGIRefServer(ServerAdapter):
    server = None

    def run(self, handler):
        self.server = make_server(self.host, self.port, handler, 
                                  server_class=StacklessWSGIServer, **self.options)
        self.server.serve_forever()

    def stop(self):
        self.server.shutdown()

app = Bottle()


           
def start_server(world_model):
    config = world_model.config
    manager = WebManager(world = world_model, secret = "jhbv235gfuhbvq2345hy3bo0")
    setattr(sys.modules[__name__], "manager", manager)
    server = MyWSGIRefServer(host=config.WS_HOST, port=config.WS_PORT)
    tasklets.tasklet(app.run)(server = server, debug = config.WS_DEBUG)
    return server

#-------------------------------------------------------------------------------------

I did this mainly by some reverse engineering, not by  really understanding the server code.

Cheers, Lars



On Thu, Dec 12, 2013 at 2:07 AM, Andrew Francis <andrewfr_ice at yahoo.com> wrote:

Hi Folks:
>
>
>This is what I am suggesting. The reactor tasklet before calling the underlying select/poll system call should look at the scheduler queue. If there are runnable tasklets, then call select/poll with a timeout. Otherwise block indefinitely. The idea is if your application is consists of mostly I/O bound tasklets, they will be blocked on channels and will eventually be scheduled and run when there is I/O for them.
>
>
>I'll write a simple example to illustrate.....
>
>
>Cheers,
>Andrew
>
>
>
>On Wednesday, December 11, 2013 7:00 AM, lars van Gemerden <lars at rational-it.com> wrote:
> 
>Hi Andrew,
>
>
>It wasn't blocked on IO, the server got stuck in it's mainloop (or similar name). I don't know much about webservers, WSGIservers etc, but what i also tried was putting a schedule() in this mainloop (which i think polls the socket). Is this what you suggest? It seems to work well, apart from the occasional weird AttributeError, which i'll have to look into. However others discouraged this approach, but i never quite understood why. 
>
>
>Cheers, Lars
>
>
>
>On Fri, Dec 6, 2013 at 7:40 PM, Andrew Francis <andrewfr_ice at yahoo.com> wrote:
>
>Hi Lars:
>>
>>
>>Message: 1
>>Date: Thu, 5 Dec 2013 22:07:20
 +0100
>>From: lars van Gemerden <lars at rational-it.com>
>>To: The Stackless Python Mailing List <stackless at stackless.com>
>>Subject: Re: [Stackless] monkeypatching
>>Message-ID:
>>    <CAP8kt8yLp1P46DeZfdBwkeTvWmbWFXbAra+MSxViXhuWXj0Fsw at mail.gmail.com>
>>Content-Type: text/plain; charset="windows-1252"
>>
>>>(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).
>>
>>
>>
>>I haven't had a chance to carefully look at your code. However from this description, it sounds like a thread/tasklet is blocked on I/O.  This will have the effect of blocking all tasklets in that thread. What you need to do is occasionally call a timeout from the underlying system call (for example, select()) and do a schedule() so other tasklets can run.
>> 
>>
>>Cheers,
>>Andrew
>>
>>
>>P.S - Yahoo's new and improved mail interface is killing me!
>>_______________________________________________
>>Stackless mailing list
>>Stackless at stackless.com
>>http://www.stackless.com/mailman/listinfo/stackless
>>
>
>
>
>-- 
>====================================
>Lars van Gemerden
>lars at rational-it.com
>+31 6 26 88 55 39
>==================================== 
>
>


-- 
====================================
Lars van Gemerden
lars at rational-it.com
+31 6 26 88 55 39
==================================== 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.stackless.com/pipermail/stackless/attachments/20131212/dffc9f3f/attachment-0001.html>


More information about the Stackless mailing list