[Stackless] NonblockingChannel start help appreciated

Peter Buchmann peter.buchmann1 at googlemail.com
Tue Feb 9 16:09:38 CET 2010


hi,

maybe someone could give me a first starting help as I'm new to stackless.

I'm stacked with a worker tasklet - which should interact with an
other tasklet running a while loop.

I thought something like the NonblockingChannel
(http://zope.stackless.com/wiki/ChannelExamples) might be needed but
could not get it to work


The whole code is at the end !

#### PROBLEM: the while loop should run till we receive something not
sure how that is best done. At the moment it blocks always for 30 sec.

class testloop

def action(self):
    datacount=0
    while 1:
        print "testloop: ", time.time()

        #### PROBLEM: the while loop should run till we receive
something not sure how that is best done.
        # A small example would be much appreciated.
        # At the moment it blocks always for 30 sec.
        (worker_ch, message) = self.ch.receive()
        print "testloop: message from: ", message
        worker_ch.send(datacount)

        time.sleep(0.1)
        datacount = datacount + 1







#### CODE START

import time
import stackless

class Sleep(object):
    def __init__(self):
        self.sleepingTasklets = []
        stackless.tasklet(self.ManageSleepingTasklets)()

    def Sleep(self, secondsToWait):
        channel = stackless.channel()
        endTime = time.time() + secondsToWait
        self.sleepingTasklets.append((endTime, channel))
        self.sleepingTasklets.sort()
        # Block until we get sent an awakening notification.
        channel.receive()

    def ManageSleepingTasklets(self):
        while True:
            if len(self.sleepingTasklets):
                endTime = self.sleepingTasklets[0][0]
                if endTime <= time.time():
                    channel = self.sleepingTasklets[0][1]
                    del self.sleepingTasklets[0]
                    # We have to send something, but it doesn't matter
what as it is not used.
                    channel.send(None)
                elif stackless.getruncount() == 1:
                    # We are the only tasklet running, the rest are
blocked on channels sleeping.
                    # We can call time.sleep until the first awakens
to avoid a busy wait.
                    delay = endTime - time.time()
                    #print "wait delay", delay
                    time.sleep(max(delay,0))
            stackless.schedule()

sleep = Sleep().Sleep


# based on http://code.google.com/p/stacklessexamples/source/browse/trunk/#trunk/examples/santaAgentsOO.py
class testloop(object):
    """
    testloop should run most of the time

    only to be shortly interrupted by a worker to exchange some data
    """
    def __init__(self):
        self.ch = stackless.channel()
        self.running = True
        stackless.tasklet(self.runAction)()

    def runAction(self):
        while self.running:
            self.action()

    def action(self):
        datacount=0
        while 1:
            print "testloop: ", time.time()

            #### PROBLEM: the while loop should run till we receive
something not sure how that is best done.
            # A small example would be much appreciated.
            # At the moment it blocks always for 30 sec.
            (worker_ch, message) = self.ch.receive()
            print "testloop: message from: ", message
            worker_ch.send(datacount)


            time.sleep(0.1)
            datacount = datacount + 1



class worker(object):
    def __init__(self, testloop, message, sleeptime):
        self.testloop = testloop
        self.message = message
        self.sleeptime=sleeptime

        self.ch = stackless.channel()
        self.running = True
        stackless.tasklet(self.runAction)()

    def runAction(self):
        while self.running:
            self.action()


    def action(self):
        sleep(self.sleeptime)
        self.testloop.ch.send((self.ch, self.message))
        testloop_response = self.ch.receive()
        stackless.schedule()


if __name__ == '__main__':

    testloop = testloop()
    worker(testloop, "worker30", 30)
    worker(testloop, "worker60", 60)

    stackless.run()


#### CODE END



Cheers

Peter




More information about the Stackless mailing list