trying to grok greenlets – more experiments in concurrent programming

I poked around in Eventlet this morning – between shopping runs and helping Karen move things around in the basement. I’d hoped to knock out a quick hackysack experiment with that stuff – since it sounded about the same – and see how it did. I over-estimated by ability to quickly grok Eventlet, and it’s underpinnings of greenlet as well.

Bob Ippolito hacked this stuff together after the same conversations that revolved around how stackless does its magic. That dude is always doing something wild and forward.

What I’ve finally concluded is that the Eventlet stuff is a nice socket-based processing engine (read web server thingy) using the greenlets – but way more than I’d need for the basics to pull together the hackysack example. Seems like heading straight down to the greenlets themselves is what I’d want to do to make it – only I’m not fully understanding all the pieces and parts to make the hackysack example. I was thinking that Eventlet would have the higher level API’s that made it similiar to a Stackless Tasklet or a Kamaelia Component. Alas, it doesn’t appear so… or I’m just too dense to clue it in anyway.

Anyway, I’ve poked around this morning, realized I’m a bit lost – and so I’m going to give it a break to see if my rear-brain can catch up with some of the core concepts here.

Oh – here’s the code that doesn’t work as yet:

import greenlet
import Queue
import sys
import random

class hackeysacker:
    counter = 0
    def __init__(self,name,circle):
        self.name = name
        self.circle = circle
        circle.append(self)
        self.messageQueue = Queue.Queue()
        self.g = greenlet(self.goLoop())
        
    def incrementCounter(self):
        hackeysacker.counter+=1
        
    def goLoop(self):
        while 1:
            msg = self.messageQueue.get()
            if msg == 'exit':
                return
            print "%s got hackeysack from %s" % (self.name,msg.name)
            kickTo = self.circle[random.randint(0,len(self.circle)-1)]
            while kickTo is self:
                kickTo = self.circle[random.randint(0,len(self.circle)-1)]
            print "%s kicking hackeysack to %s" % (self.name, kickTo.name)
            kickTo.switch(self)

hackeysackers = 5
turns = 1

def runit(hs=5,ts=5):
    global hacksackers,turns
    hackeysackers = hs
    turns = ts
    hackeysacker.counter = 0
    circle=[]
    one = hackeysacker('1',circle)
    for i in range(hackeysackers):
        hackeysacker(`i`,circle)
    one.g.switch(one)

if __name__ == '__main__':
    runit()

One thought on “trying to grok greenlets – more experiments in concurrent programming

  1. why it does not work is because Queue and greenlets aren’t designed to work together.
    All your greenlets, in fact, run in the same thread, so when messageQueue.get() blocks
    because the queue is empty it blocks every other greenlet you have, giving your program
    no chance to put something in the queue.

    in eventlet, there’s coros.queue that works as expected. however, with eventlet, you don’t create greenlets
    directly and switch() between them, instead you spawn() them (which is quite easy) and use
    communication primitives provided by eventlet, classes like coros.queue, coros.event.

    and btw, use this eventlet
    http://devel.ag-projects.com/~denis/cgi-bin/hgweb.cgi
    it’s the most stable eventlet available at this point.

    Like

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s