Here is a complete code for an implementation of the Santa Claus Problem with join patterns. Or at least, my initial stab at something approximating a join pattern. This code accompanies the previous post How Do You Solve a Problem Like Santa?.
One may ask “What is with the Twisted?” In this case, I use Twisted to ensure that tasklets sleep for the correct unit of time. Simply using sleep() will put the entire thread (and all the tasklets running in that thread), to sleep). It would not take much effort to make the elves and reindeer represent network connections.
Yes Virginia, one can make Stackless and Twisted interact….
One of these days I will write a stacklessreactor 🙂
Now to find a WordPress theme that has a wider margin…..
#!/usr/bin/env python """ joinSanta.py Andrew Francis November 17th, 2011 The purpose of joinSanta is as follows: Show a solution to the Santa Claus problem using a join object """ import random import time import sys from twisted.internet import reactor from twisted.internet import task from twisted.python.failure import Failure import stackless # we can use ETIME and RTIME to control how long reindeer # and elves wait before returning and/or asking questions RTIME = (10,12) ETIME = (1,12) def tick(seconds): tickCh = stackless.channel() reactor.callLater(seconds, tickCh.send, None) tickCh.receive() def startTwisted(): reactor.run() def stopTwisted(): reactor.callLater(1, reactor.stop) print "that's all folks" """ a way of telling the tasklets that Santa tasklet is done """ def acceptChannels(pattern, status): print "[ACCEPTING]" for chanop in pattern: chanop.channel.send(status) def worker(ch, name, theRange): while True: waitTime = random.randint(theRange[0], theRange[1]) print name, "waiting ", waitTime, " seconds" tick(waitTime) ch.send(name) answer = ch.receive() def deliveryToys(reindeer): print "All the reindeer have arrived - delivering toys" def consultWithSanta(elves): print "Santa consulting with elves" acceptChannels(elves, True) def harness(reindeer): for deer in reindeer: print "harnessing ", deer.value def unharness(reindeer): print "unharnessing" acceptChannels(reindeer, True) def santa(reindeer, elves): print "in santa" joinObject = stackless.join().addPattern([ch for _, ch, _ in reindeer]).\ addPattern([ch for _, ch, _ in elves],3) reindeerPattern, elfPattern = joinObject.patterns while True: pattern = joinObject.join() print "-->", pattern ,"<---" if reindeerPattern.ready(): print "*** REINDEER GET PRIORITY ***" reindeerPattern.join() pattern = reindeerPattern if pattern is reindeerPattern: harness(reindeerPattern) deliveryToys(reindeerPattern) unharness(reindeerPattern) elif pattern is elfPattern: consultWithSanta(elfPattern) stopTwisted() print "Twisted is dead" def makeWorkers(workers): for name, ch, waitTime in workers: stackless.tasklet(worker, name)(ch, name, waitTime) return if __name__ == "__main__": random.seed() reindeers = [(reindeer, stackless.channel(reindeer), RTIME) for reindeer in \ ["DANCER", "PRANCER", "VIXEN", "COMET", "CUPID", "DONER", \ "DASHER", "BLITZEN", "RUDOLPH"]] elves = [(elf, stackless.channel(elf), ETIME) for elf in \ ['A','B','C','D','E','F','G','H','I','J']] makeWorkers(reindeers) makeWorkers(elves) l = task.LoopingCall(stackless.schedule) l.start(.001) stackless.tasklet(startTwisted, "TWISTED")() stackless.tasklet(santa,"SANTA")(reindeers, elves) stackless.run()
Leave a comment