[Stackless] Just Not Getting One Aspect of Tasklets and Channel Receive on Pong Example

Carl, Andrew F (AS) a.carl at ngc.com
Mon Mar 15 22:53:46 CET 2010


                First, I'm impressed w/ stackless and see the potential.
I understand the transfer of control via channels and the scheduling
queue. I just seems that a channel send, once resumed on the queue,
would just continue w/ the next line of the function. It appears that
the code is effectively re-entrant at the channel receive, which appears
as the only way the ping/pong example would run as-is. There appears to
be no additional explicit calls, otherwise I would expect something as


def ping():

    accum_ping = accum_ping + 1
    while ping_channel.receive(): #blocks here
        print "PING"

  if accum_ping > 1:

      stackless.tasklet(pong)()   #so there would be a pong task
available to channel receive after all calls subsequent to the 1st time
pong is called
        pong_channel.send("from ping")

def pong():
    accum_pong = accum_pong + 1
    while pong_channel.receive():
        print "PONG"
        if accum_pong > 1:

      stackless.tasklet(ping)()   #so there would be a ping task
available to channel receive after all calls subsequent to the 1st time
ping is called
        ping_channel.send("from pong")




From: Christian Tismer [mailto:tismer at stackless.com] 
Sent: Monday, March 15, 2010 2:44 PM
To: Carl, Andrew F (AS)
Cc: The Stackless Python Mailing List; afcarl1 at earthlink.net
Subject: Re: [Stackless] Just Not Getting One Aspect of Tasklets and
Channel Receive on Pong Example


On 3/15/10 7:03 PM, Carl, Andrew F (AS) wrote: 


                Thanks for the reply and link to the stackless
documentation. Seemed like there should be more than just the PDF.
Regarding your reply, the part which is unclear is the implication of a
tasklet which contains a channel receive. I understand the functionality
and blocking, but it would seem that "stackless.tasklet(...)()" places
an instance of a "callable" on the stackless queue. But once the tasklet
channel send is accomplished, that tasklet would be complete and exit
out of the queue, no longer available to channel receive. It is for this
reason that it appears that a new tasklet is being placed in the queue
as a result of a channel send.


Why are you thinking that? The channel send is inside a function, and
when the send is done, the function continues. There is nothing
special here, and if it were, then it would surely be documented.
A tasklet is just a little housekeeping, wrapped around a piece
of code, and that is Python code that obeys the rules of Python.
And that piece of code can only be left by an explicit or
implicit return statement, or by an exception.
Tasklets are mostly like functions. When a tasklet goes asleep
on a channel, its current state is saved, so that it can
resume later on at exactly the same place where it left.
And a channel is just a little structure that holds a queue
of waiting tasklets, blocked either for sending or receiving.
The only unusual thing here is that the function resumes some
time later, when it gets unblocked from the channel. So the
only magic lies in the transfer of control during a channel
action. The time of 'what runs when' is what changes. The
rest is ordinary Python.
Ah, maybe I get the misunderstanding now. Yes, stackless.tasklet()
needs a callable, which gets called with another (), which creates
the instance of a callable, also called Python frame, and it is this
frame that the tasklet holds*). The frame itself is not callable,
this is only for the beginning of the tasklet's lifetime. After
that, it is just a resumable frame.
IOW. what Stackless essentially does is changing the order
of execution of these frames in a deterministic way.
I hope this paragraph did not add to confusion.
You can take my little walk-through literally for true,
this is exactly how it works, not more, not less.
Trust me, I initially wrote it, 10 years ago :-)
ciao -- chris
Please don't read this footnote before the above is sunken in!
*) well, in the case of tasklet( channel.send ) it is slightly
different, since channel.send is a builtin c function, and that
creates a different, but similar behaving, c-frame.
And that c-frame, bottom of our example, really ends after
being called, because there is nothing left after that call.
Forget about that detail, I just wanted to be correct.
Christian Tismer             :^)   <mailto:tismer at stackless.com>
<mailto:tismer at stackless.com> 
tismerysoft GmbH             :     Have a break! Take a ride on Python's
Johannes-Niemeyer-Weg 9A     :    *Starship* http://starship.python.net/
14109 Berlin                 :     PGP key -> http://wwwkeys.pgp.net/
work +49 30 802 86 56  mobile +49 173 24 18 776  fax +49 30 80 90 57 05
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...
URL: <http://www.stackless.com/pipermail/stackless/attachments/20100315/c3a749fd/attachment-0001.htm>

More information about the Stackless mailing list