[Stackless] NonblockingChannel start help appreciated

Kristján Valur Jónsson kristjan at ccpgames.com
Tue Feb 9 22:38:42 CET 2010


Hi.
First of all:
you are using time.sleep(), which will put the entire process to sleep.
If you want to pause a tasklet, only, you have to have some scheduler to take care of that for you. something in the general direction of:
class Scheduler():
...
def Sleep(self, delay):
	c = stackless.channel()
	when = time.clock()+delay
	self.eventqueue.append((delay, c))
	self.ComputeNextEvent()
	c.receive()

def Pump(self):
	if time.clock()<self.nextEvent: return
	for t,c in self.eventqueue:
		if t <= time.clock():
			c.send() #but be careful with bookkeeping and removing stuff from queue.
You can then pump this each time round the main tasklet.

Second, you can see if there is an event pending, by looking at the channel's balance:
if self.ch.balance > 0:
	self.ch.receive()

if the balance is <= 0 (meaning no one is sending), the caller of receive() will block.

K

> -----Original Message-----
> From: stackless-bounces at stackless.com [mailto:stackless-
> bounces at stackless.com] On Behalf Of Peter Buchmann
> Sent: 9. febrúar 2010 15:10
> To: stackless at stackless.com
> Subject: [Stackless] NonblockingChannel start help appreciated
> 
> 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/e
> xamples/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
> 
> _______________________________________________
> Stackless mailing list
> Stackless at stackless.com
> http://www.stackless.com/mailman/listinfo/stackless





More information about the Stackless mailing list