[Stackless] added tasklet.throw
Kristján Valur Jónsson
kristjan at ccpgames.com
Fri Apr 5 18:13:46 CEST 2013
Ok, I have committed a change to the 2.7 branch (didn’t want to do the full merging yet, until we stabilize):
Here’s the comment:
modifying edge case semantics of tasklet.throw()
1) sending to a new tasklet works like a running tasklet. It is scheduled,
gets an unhandled exception, and things proceed as per usual in that case.
2) Sending to a dead tasklet causes a RuntimeError, unless one is sending
a TaskletExit, in which case it is just ignored.
This is now pretty much the same as tasklet.raise_exception().
The thing is though, that tasklet.raise_exception() and kill() behave in a strange way when the target is already dead. The dead tasklet is actually scheduled and the scheduling mechanism is put in motion, even though its “frame” is null. It is by pure chance that things don’t break. So, the case is handled like a regular uncaught exception. But this is strange, since a tasklet can by definition have only one such.
Another reason I couldn’t emulate that behaviour with tasklet.throw(), is because it is not possible, or nice, to do so with non-immediate effect. we shouldn’t have a dead tasklet in the runnable queue.
Hence the change. If the tasklet is dead, then senditng it an exception is clearly an error, much as trying to rebind a dead tasklet is. Except for the kill, which I think ought to be a harmless special case to allow.
What do you think?
This does not preclude thinking more about how to deal with unhandled exceptions. The current built-in behaviour is to invoke them on the mani tasklet. But here is an idea: How about defining a class method on the tasklet class, default_handler(exc, val, tb), which does this? Then, frameworks and others can redefine this in a subclass.
The benefit of doing this, rather than having people wrap their main functions in try:except, is that this will work even when the tasklet hasn’t started yet, when the tasklet is fresh in the runnable queue.
From: stackless-bounces at stackless.com [mailto:stackless-bounces at stackless.com] On Behalf Of Christian Tismer
Sent: 5. apríl 2013 13:10
To: The Stackless Python Mailing List
Cc: Richard Tew
Subject: Re: [Stackless] added tasklet.throw
On 04.04.13 20:47, Richard Tew wrote:
On Fri, Apr 5, 2013 at 4:09 AM, Kristján Valur Jónsson <kristjan at ccpgames.com<mailto:kristjan at ccpgames.com>> wrote:
I’ve been thinking some more about this.
It should be ok to kill a tasklet that hasn’t run yet. And killing a dead one should be a no-op.
Rather than making “kill” have special semantics, how about just applying that rule? An exception sent to a tasklet that hasn´t run yet just disappears and the tasklet dies.
An exception sent to a dead tasklet just disappears.
I think these are sensible semantics. In my opinion, it was a mistake to design stackless such that uncought tasklet exceptions were sent to the main tasklet.
I disagree. I think there's an argument to be made that when a new tasklet gets inserted into the scheduler, it is effectively running. The user does not know, or care, when it actually starts running as long as it duly gets run in a fair manner. My expectation would be that an exception raised on a not yet run by (but inserted in) the scheduler tasklet, would be raised on the main tasklet - as it has not been caught. Also, I would expect that raising an exception on a dead tasklet would error.
For the most part, I just start tasklets. I expect them to run. But when I start micromanaging them and holding references to them to do more advanced usage, I already do things like checking to see if they are alive before performing operations on them. Or checking to see if they are blocked on a channel. Or whatever. I think that based on my usage of tasklets, if someone is throwing exceptions on tasklets, they should be explicit in terms of the expected situation. This means that it is not unreasonable to expect them to check the tasklets state before raising exceptions on them.
I'm in the same boat.
Letting things just pass trough as a no-op is error-prone, because
it hides programming errors where an alive tasklet is expected,
but it was dead.
I believe it is better to support explicitly the expected situation instead
of making things too "handy", meaning sloppy style.
Fiddling around with tasklets is anyway not a feature that should
normally be used by users, so it is probably used in a framework.
But there things should be clean and unambiguous, to avoid hard to
cheers - chris
Christian Tismer :^) <mailto:tismer at stackless.com><mailto:tismer at stackless.com>
Software Consulting : Have a break! Take a ride on Python's
Karl-Liebknecht-Str. 121 : *Starship* http://starship.python.net/
14482 Potsdam : PGP key -> http://pgp.uni-mainz.de
phone +49 173 24 18 776 fax +49 (30) 700143-0023
PGP 0x57F3BF04 9064 F4E1 D754 C2FF 1619 305B C09C 5A3B 57F3 BF04
whom do you want to sponsor today? http://www.stackless.com/
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Stackless