[Stackless] Stackless API

Arman Bostani arman at twinsun.com
Thu Jan 29 20:20:03 CET 2004

arman>> * If the tasklet has a single frame and it performs a python "return",
arman>>   the caller of tasklet.run gets the return value.

tismer> What is the caller. What is the caller?
tismer> You might think that run() defines the caller. But run() is
tismer> an artificial thing at the moment, just there to make sure
tismer> that the spelled tasklet is run right now.
tismer> We might have to re-consider run(), if it should carry semantics
tismer> like being a real caller.
tismer> Again, I need this discussion on the mailing list!

Yes, I consider the caller of run() to be the "caller".

arman>> * There's a scheduler object with which tasklets can be registered.
arman>>   scheduler.schedule(tasklet) will add tasklet to the list of tasklets
arman>>   run by the scheduler.  scheduler.run() will call tasklet.run() to
arman>>   execute the registered tasklets.

tismer> So you think that all the scheduling stuff should be local to
tismer> a scheduler object? Furthermore, do you want to have several
tismer> scheduler objects, maybe with different opinions/strategies
tismer> at the same time?
tismer> This would change things a lot, and it might make much sense,
tismer> at least it would make much noise. I need to know whether this
tismer> would be of general interest, then I might go for it.
tismer> If not, I'd like to keep Stackless as simple as possible.
tismer> (This is what I claimed for years, with little success :-)

Exactly, I think there could be multiple schedulers, implementing a
variety of policies.  Their common interface to tasklets is the
tasklet run() method.

arman>> * We don't need to have stackless.schedule or stackless.run functions
arman>>   anymore.  The user simply calls the run method on the scheduler.

tismer> Then I'd really need a definition of what run() should do.
tismer> Does it mean that that tasklet should run now? (Current truth)
tismer> Or, should it mean that that tasklet should run and return it's
tismer> value to the current caller, which is the tasklet that issued
tismer> the run() command? Guaranteed?
tismer> Other question: Would such behavior, provided it makes sense,
tismer> contradict the CSP paradigms?

OK, the tasklet run() method executes the tasklet until it yields
control.  This can happen through a return from the last frame or
yield_control.  The semantics of what I'm describing is almost exactly
what stackless does today.  Except that now the tasklets don't perform
a schedule.  They simply yield control back to the caller of

tom> The idea of a return value from a tasklet seems like a nonsense to me,
tom> as there is no caller waiting for said value. If you want this kind of
tom> behavior, pass the tasklet a channel, and have the last statement the
tom> tasklet executes be:
tom>   resultChan.send(result)
tom> Then the part of the program that needs this value can just receive on
tom> this channel.
tom> I think maybe there is some confusion about what the various methods do,
tom> that could (maybe??) be cleared up quite easily with some renaming

Assuming we go with the model I'm suggesting, the caller of
tasklet.run() is "waiting" for a return value.  If its a scheduler
calling tasklet.run, then it may have a policy to collect the return
values from the tasklets it runs.

Using return values fits in well with the existing Python programming
model.  So, you can create tasklets of unmodified python code, run
them and get back the return value.  No channel communication is
needed in simple cases.

tismer> The notation of tasklet.run() is arbitrary.
tismer> Currently, it only says that the spelled tasklet is put
tismer> into a position which lets it be run immediately, and
tismer> after it is done, *my* current tasklet is the next one in the
tismer> chain. But there is no guarantee that this will happen in this
tismer> order. That's the reason why I was asking.
tismer> Aaron Watters also asked me to make run() more restricted, like
tismer> guaranteeing that it will get back to "me".
tismer> This is possible, but it would enforce some structure like a "caller"
tismer> of tasklets. I need more input like this, to go that way.

tom> Again I think this is a very bad idea.
tom> It's important to make a clear distinction between the 'advertised'
tom> semantics of run() - i.e. its contract, and the details of what
tom> currently happens in the implementation.
tom> I feel we need something more like Thread.start() in Java. A method that
tom> simply means 'make this tasklet runnable', and if we're doing
tom> cooperative scheduling, perhaps it should explicitly be a scheduling
tom> point.
tom> Note that this says *nothing* about, "it's going to run right now, and
tom> then the tasklet that called run() will get the next turn..." etc. If
tom> your code needs such guarantees, you are in big trouble.
tom> I think tasklet.start() is the way to go, and drop tasklet.run()

What you're looking for can be implemented using a scheduler in the
mechanism I'm suggesting.  Instead of using tasklet.start(), you use
scheduler_instance.schedule(tasklet).  You don't need to use the run()
method at all.  Its a lower-level than what you need.

tom> A module property stackless.scheduler, to which one can assign an
tom> object.
tom> This object should provide a certain interface. Here, to describe the
tom> interface, is a simple round-robin implementation:

tom> class RoundRobin(object): ...

The problem with this model is that you have a single global
scheduler.  In the model I'm proposing, the scheduler itself calls the
tasklet run methods.  You can have as many simultaneously running
schedulers as you need.


Stackless mailing list
Stackless at stackless.com

More information about the Stackless mailing list