Well, that's the thing, the way we "currently" do monkeypatching, it is an all-or-nothing approach. Either you replace your entire application's "threading" usage with fake threads from stackless, or you don't. Although, as a convention, I have put in the old modules as _real_* attributes inside the fake ones. This helps, if your code is aware of this trick.
A few years ago, Jack Diedrich had a PyCon talk about using context managers to temporarily monkeypatch code. This would be useful, e.g. if you wanted to start up part of your application in such a way. Then you could do something like: with stackless.monkeypatch.patch_all(): import flask import mywebserver import myGUI # using regular threads. I'm sure we could re-engineer stacklesslib.monkeypatch to make use of this pattern. K From: [email protected] [mailto:[email protected]] On Behalf Of lars van Gemerden Sent: 2. desember 2013 01:26 To: The Stackless Python Mailing List Subject: Re: [Stackless] monkeypatching thank you for the help, 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). 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 :-) 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). 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) Cheers, Lars On Mon, Dec 2, 2013 at 12:36 AM, Kristján Valur Jónsson <[email protected]<mailto:[email protected]>> wrote: A bug! in threadpool.py, replace the final line with: return tasklet_call(wrapped, dispatcher=dispatcher, timeout=timeout, onOrphaned=onOrphaned) Needs more unittests :) K ________________________________ From: [email protected]<mailto:[email protected]> [[email protected]<mailto:[email protected]>] on behalf of lars van Gemerden [[email protected]<mailto:[email protected]>] Sent: Sunday, December 01, 2013 1:58 PM To: The Stackless Python Mailing List Subject: Re: [Stackless] monkeypatching OK, thanks for the input, i am trying to get this to work, but i might have found a bug (which i find hard to debug): i have reimplemented the code above as: -------------------------------------------------------------- import asyncore, traceback, sys, logging import stacklesslib.main import stacklesslib.app # the unittests use time.time() for various time tests. # Therefore, we must make sure that main uses this from time import time as elapsed_time stacklesslib.main.elapsed_time = elapsed_time class MonkeyTasklets(object): _stop = False stacklesslib.app.install_stackless() @classmethod def run(cls, world, webserver = None, maxcount = None): #param killer is ignored world.flowmodel.start() if webserver: cls.server = webserver.start_server(world_model = world) #starts a tasklet for running the webserver counter = 0 while not cls._stop or counter > maxcount: counter += 1 tick_time = elapsed_time() try: stacklesslib.main.mainloop.loop() except Exception as e: import asyncore if isinstance(e, ReferenceError): print("run:EXCEPTION", str(e), asyncore.socket_map) else: print("run:EXCEPTION", asyncore.socket_map) traceback.print_exc() sys.exc_clear() world.flowmodel.stop() @classmethod def schedule(cls): stackless.schedule() @classmethod def tasklet(cls, func): return stackless.tasklet(func) @classmethod def stop(cls): if hasattr(cls, "server"): cls.server.stop() cls._stop = True tasklets = MonkeyTasklets -------------------------------------------------------------- and i get the exception: File "d:\Documents\Code\python\floware\server\bottle.py", line 641, in run run(self, **kwargs) File "d:\Documents\Code\python\floware\server\bottle.py", line 2720, in run server.run(app) File "d:\Documents\Code\python\floware\server\webserver.py", line 329, in run self.server.serve_forever() File "C:\Python27\lib\SocketServer.py", line 236, in serve_forever poll_interval) File "C:\Python27\lib\SocketServer.py", line 155, in _eintr_retry return func(*args) File "d:\Documents\Code\python\floware\stacklesslib\replacements\select.py", line 27, in select return stacklesslib.threadpool.call_on_thread(real_select.select, args, kwargs) File "d:\Documents\Code\python\floware\stacklesslib\threadpool.py", line 123, in call_on_thread return tasklet_call(wrapped, dispatcher, timeout=timeout, onOrphaned=onOrphaned) File "d:\Documents\Code\python\floware\stacklesslib\util.py", line 209, in tasklet_call return channel_wait(chan, timeout) File "d:\Documents\Code\python\floware\stacklesslib\util.py", line 53, in channel_wait return chan.receive() File "d:\Documents\Code\python\floware\stacklesslib\util.py", line 192, in helper result = function(*args, **kwargs) TypeError: wrapped() argument after * must be a sequence, not function -------------------------------------------------------------- is this something i am doing wrong or indeed a buggy in stacklesslib and if so, how can it be fixed? Cheers, Lars On Sun, Dec 1, 2013 at 4:05 AM, Richard Tew <[email protected]<mailto:[email protected]>> wrote: latest stacklesslib, i mean. On 12/1/13, Richard Tew <[email protected]<mailto:[email protected]>> wrote: > Hi Lars, > > stacklessio is internal ccp stuff. > > main.py in stacklesslib is pretty much all you need to understand, > beyond calling patch_all(). It is a scheduler, and makes your Open > scheduler redundant. > > I suggest you get the latest stacklessio from: > > https://bitbucket.org/krisvale/stacklesslib > > And then you check out test / teststdlibunittests.py, which is a short > example of monkey patching and running the stacklesslib scheduler. > > Cheers, > Richard. > > On 12/1/13, lars van Gemerden > <[email protected]<mailto:[email protected]>> wrote: >> sorry, >> >> patch_all seemed to simple, question was a bit rethoric ;-) tried it 2 >> mins >> after pressing send just in case and indeed no cigar. >> >> I am trying to get this demo running and all kinds of last minute #### is >> popping up. >> >> I tried reading the source but it doesn't click; i am not familiar with >> using sockets etc. at all. >> >> e.g. >> >> - do i need 'stacklessio'? >> - can i (essentially) just put a stackless.schedule() (or >> OpenTasklets.schedule() in the code below) in the serve_forever loop? >> - will this work at all with an adapted scheduler like this: >> >> class OpenTasklets(object): >> >> _stop = False >> >> @classmethod >> def run(cls, maxcount = None): >> cls.schedule_channel = stackless.channel() >> cls.schedule_channel.preference = 1 >> counter = 0 >> OpenTasklets._stop = False >> while stackless.getruncount() != 1: >> stackless.run() >> cls.reschedule(cls._stop or (maxcount and counter > >> maxcount)) >> counter += 1 >> >> @classmethod >> def schedule(cls): >> if cls.schedule_channel.receive(): >> raise TaskletExit >> >> @classmethod >> def reschedule(cls, stop = False): >> while cls.schedule_channel.balance < 0: >> cls.schedule_channel.send(stop) >> >> Any help is appreciated .. >> >> Lars >> >> >> >> >> On Sat, Nov 30, 2013 at 8:53 PM, Richard Tew >> <[email protected]<mailto:[email protected]>>wrote: >> >>> Lars :-) >>> >>> Yes, there is no documentation for stacklesslib yet. To use it, you >>> really need to be willing to read the source code. >>> >>> You should already know whether calling patch_all would be enough. It >>> would have been something you could have tried immediately, rather >>> than asking the list and waiting. >>> >>> Cheers, >>> Richard. >>> >>> On 11/30/13, lars van Gemerden >>> <[email protected]<mailto:[email protected]>> wrote: >>> > Hi all, >>> > >>> > I though i could avoid it to run my demo but it seems i need to let >>> > the >>> > webserver (simple server?, single thread, 'bottle' micro framework) >>> > yield >>> > to the scheduler i am using. I have downloaded stacklesslib 1.0.3, but >>> > can't find any documentation to help with monkeypatching. >>> > >>> > - Do i just run patch_all at the start of the program? >>> > >>> > Any help is very welcome .. >>> > >>> > Cheers, Lars >>> > >>> > -- >>> > ==================================== >>> > Lars van Gemerden >>> > [email protected]<mailto:[email protected]> >>> > +31 6 26 88 55 39<tel:%2B31%206%2026%2088%2055%2039> >>> > ==================================== >>> > >>> >>> _______________________________________________ >>> Stackless mailing list >>> [email protected]<mailto:[email protected]> >>> http://www.stackless.com/mailman/listinfo/stackless >>> >> >> >> >> -- >> ==================================== >> Lars van Gemerden >> [email protected]<mailto:[email protected]> >> +31 6 26 88 55 39<tel:%2B31%206%2026%2088%2055%2039> >> ==================================== >> > _______________________________________________ Stackless mailing list [email protected]<mailto:[email protected]> http://www.stackless.com/mailman/listinfo/stackless -- ==================================== Lars van Gemerden [email protected]<mailto:[email protected]> +31 6 26 88 55 39<tel:%2B31%206%2026%2088%2055%2039> ==================================== _______________________________________________ Stackless mailing list [email protected] http://www.stackless.com/mailman/listinfo/stackless -- ==================================== Lars van Gemerden [email protected] +31 6 26 88 55 39 ====================================
_______________________________________________ Stackless mailing list [email protected] http://www.stackless.com/mailman/listinfo/stackless
