<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">

<head>
<meta http-equiv=Content-Type content="text/html; charset=us-ascii">
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
<title>Just Not Getting One Aspect of Tasklets and Channel Receive on Pong
Example</title>
<style>
<!--
 /* Font Definitions */
 @font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";
        color:black;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p
        {mso-style-priority:99;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";
        color:black;}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML Preformatted Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";
        color:black;}
tt
        {mso-style-priority:99;
        font-family:"Courier New";}
span.HTMLPreformattedChar
        {mso-style-name:"HTML Preformatted Char";
        mso-style-priority:99;
        mso-style-link:"HTML Preformatted";
        font-family:Consolas;
        color:black;}
span.EmailStyle21
        {mso-style-type:personal;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
span.EmailStyle22
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page Section1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.Section1
        {page:Section1;}
-->
</style>
<!--[if gte mso 9]><xml>
 <o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
 <o:shapelayout v:ext="edit">
  <o:idmap v:ext="edit" data="1" />
 </o:shapelayout></xml><![endif]-->
</head>

<body bgcolor=white lang=EN-US link=blue vlink=purple>

<div class=Section1>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>Chris,<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; First,
I&#8217;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 follows:<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";
color:#33CC00'><br>
<tt>def ping():<o:p></o:p></tt></span></p>

<p class=MsoNormal><tt><span style='font-size:10.0pt;color:#33CC00'>&nbsp;&nbsp;&nbsp;
accum_ping = accum_ping + 1</span></tt><span style='font-size:10.0pt;
font-family:"Courier New";color:#33CC00'><br>
<tt>&nbsp;&nbsp;&nbsp; while ping_channel.receive(): #blocks here</tt><br>
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print &quot;PING&quot;<o:p></o:p></tt></span></p>

<p class=MsoNormal style='text-indent:.5in'><span style='font-size:10.0pt;
font-family:"Courier New";color:#33CC00'>&nbsp; if accum_ping &gt; 1:</span><o:p></o:p></p>

<p class=MsoNormal style='text-indent:.5in'><span style='font-size:10.0pt;
font-family:"Courier New";color:#33CC00'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
stackless.tasklet(pong)()&nbsp;&nbsp; #so there would be a pong task available
to channel receive after all calls subsequent to the 1<sup>st</sup> time pong
is called<br>
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pong_channel.send(&quot;from ping&quot;)</tt><br>
<br>
<tt>def pong():</tt><br>
<tt>&nbsp;&nbsp;&nbsp; accum_pong = accum_pong + 1</tt><br>
<tt>&nbsp;&nbsp;&nbsp; while pong_channel.receive():</tt><br>
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print &quot;PONG&quot;</tt><br>
&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if accum_pong &gt; 1:<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Courier New";
color:#33CC00'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
stackless.tasklet(ping)()&nbsp;&nbsp; #so there would be a ping task available
to channel receive after all calls subsequent to the 1<sup>st</sup> time ping
is called<br>
<tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ping_channel.send(&quot;from
pong&quot;)</tt><br>
<br>
</span><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>Thanks,<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>Andy<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'><o:p>&nbsp;</o:p></span></p>

<div>

<div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in'>

<p class=MsoNormal><b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif";
color:windowtext'>From:</span></b><span style='font-size:10.0pt;font-family:
"Tahoma","sans-serif";color:windowtext'> Christian Tismer [mailto:tismer@stackless.com]
<br>
<b>Sent:</b> Monday, March 15, 2010 2:44 PM<br>
<b>To:</b> Carl, Andrew F (AS)<br>
<b>Cc:</b> The Stackless Python Mailing List; afcarl1@earthlink.net<br>
<b>Subject:</b> Re: [Stackless] Just Not Getting One Aspect of Tasklets and
Channel Receive on Pong Example<o:p></o:p></span></p>

</div>

</div>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

<p class=MsoNormal>On 3/15/10 7:03 PM, Carl, Andrew F (AS) wrote: <o:p></o:p></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>Christian,</span><o:p></o:p></p>

<p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";
color:#1F497D'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
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
&#8220;stackless.tasklet(&#8230;)()&#8221; places an instance of a
&#8220;callable&#8221; 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.</span><o:p></o:p></p>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

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

</body>

</html>