[Stackless] Solution with Select/JoinPattern Re: Simple Example of implementing a Join

Andrew Francis andrewfr_ice at yahoo.com
Mon Nov 19 00:03:01 CET 2012

Hi Folks:

I believe this was my first post to Stackless Python. I cannot believe this was over seven years ago. I recently gave a talk at Pycon Canada 2012 called "How to Solve a Problem Like Santa Claus: Prototyping Join Patterns with stackless.py for Stackless Python." I am surprised that this talk was accepted. Anyhow I worked on join patterns during the two day sprint. 

Here is the video. http://pyvideo.org/video/1577/how-to-solve-a-problem-like-santa-claus. I am correcting the slides and since I realise there are gaps in the talk, I will come out with a third edition. And a paper describing the algorithm in detail. I am also working on creating an egg for stackless.py with join. 

Anyhow here is a solution to the 2005 problem using a simplified join pattern interface. By the way, this problem is hard to solve with straight Stackless Python. And somewhat verbose with Go. The purpose of this exercise was to implement WS-BPEL's activity link feature. The channels should impose a logical ordering over the tasklets with a trace of  a(B|C)d . That is A executes before B or C. B and C should finish before D starts. B and C can run in parallel. 

in A, the select() blocks until either ab or ac is ready to receive. When one of the channels have completed, it is taken out of the activities list. At no time does A hold one channel and wait for another.

In D, the joinPattern waits until bd and bc are ready to send. Again at no time does D hold a channel while waiting for another. 

It took me a while to learn that blocking is tantamount to waiting and holding is having a reference. 


Andrew Francis
November 17th, 2012

testing logical Order
example inspired from a September 2005 post

Note - I should check select() for a list and throw a type error

import stackless

def aTasklet(aName, ab, ac):
    print "in ", aName
    activities = [ab.sendCase("a-to-b"), ac.sendCase("a-to-c")]
    while len(activities):
        activity = stackless.select(activities)

def bTasklet(aName, ab, bd):
    print "in ", aName
    print ab.receive()

def cTasklet(aName, ac, cd):
    print "in ", aName
    print ac.receive()

def dTasklet(aName, bd, cd):
    print "in", aName
    print stackless.select([stackless.joinPattern([bd,cd])])
    print "done", aName

if __name__ == "__main__":
   ab = stackless.channel()
   ac = stackless.channel()
   bd = stackless.channel()
   cd = stackless.channel()

   stackless.tasklet(aTasklet)("A", ab, ac)
   stackless.tasklet(bTasklet)("B", ab, bd)
   stackless.tasklet(cTasklet)("C", ac, cd)
   stackless.tasklet(dTasklet)("D", bd, cd)


 From: Andrew Francis <andrewfr_ice at yahoo.com>
To: stackless at stackless.com 
Sent: Thursday, September 1, 2005 7:55 PM
Subject: Simple Example of implementing a Join 
Hello Colleagues:

Please bear with me for a while....

I am trying to figure out how to implement
the equivalent of a Join. For instance, I
wish to have tasklet D run after tasklet A,
B and C complete. Assume A,B,C can execute
in parallel. Do I use three channels? Can 
someone please post a simple example? Once
I am comfortable, I would be more than 
happy to summarize in the Wiki.


Start your day with Yahoo! - make it your home page 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.stackless.com/pipermail/stackless/attachments/20121118/97043f75/attachment.html>

More information about the Stackless mailing list