<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html; charset=ISO-8859-1"
 http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
On 3/12/10 9:44 PM, Carl, Andrew F (AS) wrote:
<blockquote
 cite="mid:CE1C9C26CC18FD4E804F232CEC1F845103B10D84@XMBTX132.northgrum.com"
 type="cite">
  <meta http-equiv="Content-Type"
 content="text/html; charset=ISO-8859-1">
  <meta name="Generator"
 content="MS Exchange Server version 6.5.7654.12">
  <title>Just Not Getting One Aspect of Tasklets and Channel Receive on
Pong Example</title>
<!-- Converted from text/rtf format -->
  <p dir="LTR"><span lang="en-us"><font face="Calibri">The pong example
on p.</font></span><span lang="en-us"> <font face="Calibri">13 of the</font></span><span
 lang="en-us"> <font face="Calibri">&#8220;</font></span><span lang="en-us"><font
 face="Calibri">Why Stackless</font></span><span lang="en-us"><font
 face="Calibri">&#8221;</font></span><span lang="en-us"><font face="Calibri">
manual is unclear</font></span><span lang="en-us"><font face="Calibri">
to me</font></span><span lang="en-us"><font face="Calibri">.&nbsp; It
appears that the tasklet statement puts the task on the</font></span><span
 lang="en-us"> <font face="Calibri">queue</font></span><span
 lang="en-us"><font face="Calibri"> once, but yet it seems that the
send to the</font></span><span lang="en-us"> <font face="Calibri">&#8220;</font></span><span
 lang="en-us"><font face="Calibri">while receive</font></span><span
 lang="en-us"><font face="Calibri">&#8221;</font></span><span lang="en-us"><font
 face="Calibri"> is effectively creating another tasklet on the</font></span><span
 lang="en-us"> <font face="Calibri">queue</font></span><span
 lang="en-us"><font face="Calibri">. It would seem that</font></span><span
 lang="en-us"><font face="Calibri"> they should bounce back and forth
only once each with</font></span><span lang="en-us"><font face="Calibri">out</font></span><span
 lang="en-us"><font face="Calibri"> the addition of a new tasklet
statement. Could someone please</font></span><span lang="en-us"> <font
 face="Calibri">clarify</font></span><span lang="en-us"><font
 face="Calibri"> this?</font></span></p>
</blockquote>
<tt>
An unambiguous link would be preferrable to readers, like this:</tt><br>
<br>
<tt><a class="moz-txt-link-freetext"
 href="http://members.verizon.net/olsongt/stackless/why_stackless.html#pingpong-stackless-py-stackless-ping-pong-example">http://members.verizon.net/olsongt/stackless/why_stackless.html#pingpong-stackless-py-stackless-ping-pong-example</a></tt><br>
<br>
<tt><font color="#33cc00">#<br>
# pingpong_stackless.py<br>
#<br>
<br>
import stackless<br>
<br>
ping_channel = stackless.channel()<br>
pong_channel = stackless.channel()<br>
<br>
def ping():<br>
&nbsp;&nbsp;&nbsp; while ping_channel.receive(): #blocks here<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "PING"<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pong_channel.send("from ping")<br>
<br>
def pong():<br>
&nbsp;&nbsp;&nbsp; while pong_channel.receive():<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "PONG"<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ping_channel.send("from pong")<br>
<br>
<br>
<br>
stackless.tasklet(ping)()<br>
stackless.tasklet(pong)()<br>
<br>
# we need to 'prime' the game by sending a start message<br>
# if not, both tasklets will block<br>
stackless.tasklet(ping_channel.send)('startup')<br>
<br>
stackless.run()<br>
</font><br>
<br>
Assuming that this is the code you are referring to, I am trying</tt><br>
<tt>to understand your question.</tt><br>
<p><i><font face="Calibri">Two tasklets are created which are
initially blocking on their channel.</font></i></p>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<pre class="literal-block">stackless.tasklet(ping)()
stackless.tasklet(pong)()
</pre>
<p><i><font face="Calibri">Going into details:</font></i><br>
</p>
<pre class="literal-block">stackless.tasklet(ping)
</pre>
<p><i><font face="Calibri">is the constructor call of a tasklet, bound
to function ping.<br>
A more explicit notation would be</font></i></p>
<pre class="literal-block">task = stackless.tasklet()  # not bound to a function
task.bind(ping)             # bound to ping
task.setup()                # set empty argument list
</pre>
<p><font face="Calibri"><i>After the setup, the ping tasklet is ready
to
run. It is sitting in<br>
the runnables queue, right after the implicit main tasklet.<br>
</i></font></p>
<font face="Calibri"><i>The same thing as above repeats for the pong
tasklet.<br>
</i></font>
<pre class="literal-block">stackless.tasklet(pong)()
</pre>
<p><i><font face="Calibri">We have a circular list of runnable tasklets:<br>
</font></i></p>
<pre><tt>main     &lt;-    still executing
ping    |  |   paused
pong     -&gt;    paused<font face="Calibri">
</font></tt></pre>
<p><i><font face="Calibri">Now we
enter the last line before the run():</font></i></p>
<pre><tt># we need to 'prime' the game by sending a start message
# if not, both tasklets will block
stackless.tasklet(ping_channel.send)('startup')
</tt></pre>
<i><font face="Calibri">This tasklet</font> does the equivalent of</i><br>
<pre>    ping_channel.send('startup')
</pre>
<font face="Calibri"><i>but it is written in this deferred form, so
that all tasklet activities are done<br>
in the run() context. This is not needed for the example to work, but
seems<br>
to be the author's intent, for more clarity.<br>
<br>
We have now the following circular queue picture:</i><br>
</font>
<pre><tt><tt>main     &lt;-    still executing
ping    |  |   paused
pong    |  |   paused
&lt;???&gt;    -&gt;    paused
</tt></tt>
</pre>
<p><i><font face="Calibri">Now we enter the final statement, which does
it all:</font></i><br>
</p>
<pre>stackless.run()
</pre>
<i><font face="Calibri">Main gets removed from the runnables queue, to
let the other tasklets<br>
do their thing. ping is the next available tasklet and it runs:<br>
</font></i>
<pre><tt><tt>ping     &lt;-    current
pong    |  |   paused
&lt;???&gt;    -&gt;    paused
</tt></tt>
</pre>
<i><font face="Calibri">ping starts to run, but immediately blocks on
the empty ping_channel:</font><br>
</i><br>
<tt>def ping():<br>
&nbsp;&nbsp;&nbsp; while ping_channel.receive(): #blocks here<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "PING"<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pong_channel.send("from ping")<br>
<br>
</tt><font face="Calibri"><i>ping gets removed from the runnables queue
and stored in the<br>
ping_channel. So the next available tasklet is pong.</i></font><tt><br>
</tt>
<pre><tt><tt>pong     &lt;-    current
&lt;???&gt;    -&gt;    paused

def pong():
    while pong_channel.receive():
        print "PONG"
        ping_channel.send("from pong")

</tt></tt></pre>
<i><font face="Calibri">The same happens to pong, since pong_channel is
empty.<br>
It gets blocked into pong_channel. Our only available<br>
tasklet is now the nameless &lt;???&gt;.</font></i><tt><tt><br>
</tt></tt>
<pre><tt><tt><tt><tt>&lt;???&gt;    &lt;-&gt;   current. sends 'startup' on ping_channel
              &nbsp;and exits.
</tt></tt></tt></tt></pre>
<i><font face="Calibri">Now we are back in ping, right after the
receive call. ping is<br>
our only active tasklet:</font></i><br>
<pre><tt><tt><tt><tt><tt><tt><tt><tt>ping     &lt;-&gt;   current. prints 'PING', then sends
              &nbsp;'from ping' on pong_channel.</tt></tt></tt></tt></tt></tt></tt></tt>

<tt>def ping():
    while ping_channel.receive(): #blocks here
        print "PING"
        pong_channel.send("from ping")
</tt>
PING

</pre>
<i><font face="Calibri">ping gets blocked after sending on
pong_channel, and pong</font><br>
<font face="Calibri">is now our only active tasklet:</font></i><br>
<br>
<pre><tt><tt><tt><tt><tt><tt><tt><tt>pong     &lt;-&gt;   current. prints 'PONG', then sends
             &nbsp; 'from pong' on ping_channel.

PONG
</tt></tt></tt></tt></tt></tt></tt></tt></pre>
<font face="Calibri"><i>Now that game continues until you hit CTL-C.
The main tasklet will th</i><i>en<br>
wake up and report the exception.</i></font><br>
<pre><tt>hope this helps -- chris


p.s.:
If people have questions like this, I'd like to refer them to
<a class="moz-txt-link-freetext"
 href="http://www.disinterest.org/resource/stackless/2.6.4-docs-html/stackless-python.html">http://www.disinterest.org/resource/stackless/2.6.4-docs-html/stackless-python.html</a>
This is the one and only reference documentation that covers it all!
</tt></pre>
<tt>-- </tt>
<pre class="moz-signature" cols="72"><pre><tt>Christian Tismer             :^)   <a
 class="moz-txt-link-rfc2396E" href="mailto:tismer@stackless.com">&lt;mailto:tismer@stackless.com&gt;</a>
tismerysoft GmbH             :     Have a break! Take a ride on Python's
</tt>Johannes-Niemeyer-Weg 9A     :    *Starship* <a
 class="moz-txt-link-freetext" href="http://starship.python.net/">http://starship.python.net/</a>
14109 Berlin                 :     PGP key -&gt; <a
 class="moz-txt-link-freetext" href="http://wwwkeys.pgp.net/">http://wwwkeys.pgp.net/</a>
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
&nbsp;     whom do you want to sponsor today?   <a
 class="moz-txt-link-freetext" href="http://www.stackless.com/">http://www.stackless.com/</a></pre></pre>
</body>
</html>