Hi Folks:

I have started to prototype a Stackless select() function. For now
I want something similar to Go. I have success with the function using 
stackless.py over CPython. Carl Boltz and Stephan Diehl have been 
really helpful. I am still running tests and playing with 
algorithms but the initial code is pretty straightforward. I am also
writing documentation that I will post later with a new version of
stackless.py. I am not sure how new features are handled in the PyPy
or for that matter Stackless world.

the signature is:

(channel, value) = stackless.select([cases])

case, a tuple of (channel, operation, value) where operation is 
{RECEIVE, SEND} 

RECEIVE = -1, SEND = 1

I have attached an initial version. 

An early observation....

I am thinking to simplify implementing the code for C based Stackless
(as a subclass as per Richard Tew's suggestions), maybe two function 
could be added to channel.

channel._queueTasklet(current tasklet, operation)
channel._removeTasklet(tasklet, operation) 

Any feedback?

Cheers,
Andrew


      
# Select.py
# Andrew Francis
# December 18th, 2009
#
# This is an initial version of the Select function for Stackless.py
# The object of this version is to get Select to work and learn
# I am new to stackless.py

def select(list):
    result = None
    ready = []
    source = getcurrent()

    # is there a channel that will not block? If so, put it on the
    # ready list
    for channel, operation, value in list:
        if (channel.balance > 0 and operation == RECEIVE) or \
           (channel.balance < 0 and operation == SEND): \
              ready.append((channel,operation, value))

    """
     if there are ready channels, randomly select one
     and return from select(). In the Pike paper this is done to 
     guard against 'chatty' processes. Is this really necessary
     in the Stackless world given the difference in schedulers?
    """
    
    l = len(ready)
    if l != 0:
       unblockedChannel, operation, value = ready[random.randint(0, l - 1)]
       result = unblockedChannel._channel_action(value, operation)
    else:
      
       # for some reason, channel action does this instead of using a boolean?
       source.blocked = operation

       for channel, operation, value in list:
           channel.queue.append(source)
           channel.balance += operation
           source.selectedChannels[channel] = (operation, value)
               
       _scheduler_remove(source)

       schedule()

       #lets be safe for now
       result = source.tempval

       unblockedChannel = source.selected
       source.selected = None
       source.blocked = False
       del(source.selectedChannels[unblockedChannel])

       # now remove self from all the other channels, ouch
       for channel, (operation, value) in source.selectedChannels.items():
           channel.balance -= operation
           channel.queue.remove(source)

    return unblockedChannel, result
import stackless
import sys 

"""
test5.py

the purpose of this test is to check whether select will properly
block, unblock and return the correct value
"""
RECEIVE = -1
SEND = 1

def sender(ch):
    stackless.schedule()      #ensure that selector goes first
    ch.send("hello world")
    print "Sender done"


def selector(list):
    try:
       channel, result = stackless.select(list)
       print "THE RESULT FROM SELECT ->", channel, result
    except:
       print sys.exc_info()

if __name__ == "__main__":
   list = []

   list.append((stackless.channel(),RECEIVE, None))
   list.append((stackless.channel(),RECEIVE, None))
   list.append((stackless.channel(),RECEIVE, None))
   list.append((stackless.channel(),RECEIVE, None))
   list.append((stackless.channel(),RECEIVE, None))

   stackless.tasklet(selector)(list)
   stackless.tasklet(sender)(list[0][0])
   stackless.run()
   print "THE PROGRAMMING IS ENDING"
   

_______________________________________________
Stackless mailing list
[email protected]
http://www.stackless.com/mailman/listinfo/stackless

Reply via email to