#!/usr/bin/python3
import heapq
import time
import types
import logging
class EventLoop:
def __init__ ( self ) :
self .timers = [ ]
self .seq = 0
def runAfter( self , delay, callback) :
self .seq += 1
heapq .heappush ( self .timers , ( time .time ( ) + delay, self .seq , callback) )
def poll( self ) :
# here we can poll for sockets etc
now = time .time ( )
while self .timers and now >= self .timers [ 0 ] [ 0 ] :
heapq .heappop ( self .timers ) [ 2 ] ( )
loop = EventLoop( )
class Future:
def __init__ ( self ) :
self .__hasResult = False
self .__result = None
self .__callback = None
def done( self , result) :
if self .__callback:
self .__callback( result)
else :
self .__result = result
self .__hasResult = True
def then( self , callback) :
if self .__hasResult:
callback( self .__result)
else :
self .__callback = callback
def hasResult( self ) :
return self .__hasResult
class Spawn( Future) :
def __init__ ( self , gen) :
super ( ) .__init__ ( )
self .gen = gen
self .step ( None )
def step( self , arg) :
try :
res = self .gen .send ( arg)
if isinstance ( res, types .GeneratorType ) :
res = Spawn( res)
res.then ( self .step )
except StopIteration as e:
self .done ( e.value )
class Sleep( Future) :
def __init__ ( self , delay) :
super ( ) .__init__ ( )
loop.runAfter ( delay, lambda : self .done ( None ) )
def foo( tid, delay, n) :
logging .debug ( "%d entered foo" , tid)
for i in range ( 0 , n) :
logging .debug ( "%d before sleep" , tid)
yield Sleep( delay)
logging .debug ( "%d after sleep" , tid)
logging .debug ( "%d exiting foo" , tid)
return n
def bar( ) :
logging .debug ( "entered bar" )
f1 = Spawn( foo( 1 , 0.1 , 10 ) )
f2 = Spawn( foo( 2 , 0.15 , 5 ) )
logging .debug ( "waiting for f1" )
r1 = yield f1
logging .debug ( "f1 result is %d" , r1)
logging .debug ( "waiting for f2" )
r2 = yield f2
logging .debug ( "f1 result is %d" , r2)
logging .debug ( "exiting bar" )
logging .basicConfig ( format= "%(asctime)-15s %(message)s" , level= logging .DEBUG )
s = Spawn( bar( ) )
while not s.hasResult ( ) :
loop.poll ( )
IyEvdXNyL2Jpbi9weXRob24zCgppbXBvcnQgaGVhcHEKaW1wb3J0IHRpbWUKaW1wb3J0IHR5cGVzCmltcG9ydCBsb2dnaW5nCgpjbGFzcyBFdmVudExvb3A6CiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgc2VsZi50aW1lcnMgPSBbXQogICAgICAgIHNlbGYuc2VxID0gMAogICAgZGVmIHJ1bkFmdGVyKHNlbGYsIGRlbGF5LCBjYWxsYmFjayk6CiAgICAgICAgc2VsZi5zZXEgKz0gMQogICAgICAgIGhlYXBxLmhlYXBwdXNoKHNlbGYudGltZXJzLCAodGltZS50aW1lKCkgKyBkZWxheSwgc2VsZi5zZXEsIGNhbGxiYWNrKSkKICAgIGRlZiBwb2xsKHNlbGYpOgogICAgICAgICMgaGVyZSB3ZSBjYW4gcG9sbCBmb3Igc29ja2V0cyBldGMKICAgICAgICBub3cgPSB0aW1lLnRpbWUoKQogICAgICAgIHdoaWxlIHNlbGYudGltZXJzIGFuZCBub3cgPj0gc2VsZi50aW1lcnNbMF1bMF06CiAgICAgICAgICAgIGhlYXBxLmhlYXBwb3Aoc2VsZi50aW1lcnMpWzJdKCkKCmxvb3AgPSBFdmVudExvb3AoKQoKY2xhc3MgRnV0dXJlOgogICAgZGVmIF9faW5pdF9fKHNlbGYpOgogICAgICAgIHNlbGYuX19oYXNSZXN1bHQgPSBGYWxzZQogICAgICAgIHNlbGYuX19yZXN1bHQgPSBOb25lCiAgICAgICAgc2VsZi5fX2NhbGxiYWNrID0gTm9uZQogICAgZGVmIGRvbmUoc2VsZiwgcmVzdWx0KToKICAgICAgICBpZiBzZWxmLl9fY2FsbGJhY2s6CiAgICAgICAgICAgIHNlbGYuX19jYWxsYmFjayhyZXN1bHQpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5fX3Jlc3VsdCA9IHJlc3VsdAogICAgICAgICAgICBzZWxmLl9faGFzUmVzdWx0ID0gVHJ1ZQogICAgZGVmIHRoZW4oc2VsZiwgY2FsbGJhY2spOgogICAgICAgIGlmIHNlbGYuX19oYXNSZXN1bHQ6CiAgICAgICAgICAgIGNhbGxiYWNrKHNlbGYuX19yZXN1bHQpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5fX2NhbGxiYWNrID0gY2FsbGJhY2sKICAgIGRlZiBoYXNSZXN1bHQoc2VsZik6CiAgICAgICAgcmV0dXJuIHNlbGYuX19oYXNSZXN1bHQKCmNsYXNzIFNwYXduKEZ1dHVyZSk6CiAgICBkZWYgX19pbml0X18oc2VsZiwgZ2VuKToKICAgICAgICBzdXBlcigpLl9faW5pdF9fKCkKICAgICAgICBzZWxmLmdlbiA9IGdlbgogICAgICAgIHNlbGYuc3RlcChOb25lKQogICAgZGVmIHN0ZXAoc2VsZiwgYXJnKToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHJlcyA9IHNlbGYuZ2VuLnNlbmQoYXJnKQogICAgICAgICAgICBpZiBpc2luc3RhbmNlKHJlcywgdHlwZXMuR2VuZXJhdG9yVHlwZSk6CiAgICAgICAgICAgICAgICByZXMgPSBTcGF3bihyZXMpCiAgICAgICAgICAgIHJlcy50aGVuKHNlbGYuc3RlcCkKICAgICAgICBleGNlcHQgU3RvcEl0ZXJhdGlvbiBhcyBlOgogICAgICAgICAgICBzZWxmLmRvbmUoZS52YWx1ZSkKCmNsYXNzIFNsZWVwKEZ1dHVyZSk6CiAgICBkZWYgX19pbml0X18oc2VsZiwgZGVsYXkpOgogICAgICAgIHN1cGVyKCkuX19pbml0X18oKQogICAgICAgIGxvb3AucnVuQWZ0ZXIoZGVsYXksIGxhbWJkYTogc2VsZi5kb25lKE5vbmUpKQoKZGVmIGZvbyh0aWQsIGRlbGF5LCBuKToKICAgIGxvZ2dpbmcuZGVidWcoIiVkIGVudGVyZWQgZm9vIiwgdGlkKQogICAgZm9yIGkgaW4gcmFuZ2UoMCwgbik6CiAgICAgICAgbG9nZ2luZy5kZWJ1ZygiJWQgYmVmb3JlIHNsZWVwIiwgdGlkKQogICAgICAgIHlpZWxkIFNsZWVwKGRlbGF5KQogICAgICAgIGxvZ2dpbmcuZGVidWcoIiVkIGFmdGVyIHNsZWVwIiwgdGlkKQogICAgbG9nZ2luZy5kZWJ1ZygiJWQgZXhpdGluZyBmb28iLCB0aWQpCiAgICByZXR1cm4gbgoKZGVmIGJhcigpOgogICAgbG9nZ2luZy5kZWJ1ZygiZW50ZXJlZCBiYXIiKQogICAgZjEgPSBTcGF3bihmb28oMSwgMC4xLCAxMCkpCiAgICBmMiA9IFNwYXduKGZvbygyLCAwLjE1LCA1KSkKICAgIGxvZ2dpbmcuZGVidWcoIndhaXRpbmcgZm9yIGYxIikKICAgIHIxID0geWllbGQgZjEKICAgIGxvZ2dpbmcuZGVidWcoImYxIHJlc3VsdCBpcyAlZCIsIHIxKQogICAgbG9nZ2luZy5kZWJ1Zygid2FpdGluZyBmb3IgZjIiKQogICAgcjIgPSB5aWVsZCBmMgogICAgbG9nZ2luZy5kZWJ1ZygiZjEgcmVzdWx0IGlzICVkIiwgcjIpCiAgICBsb2dnaW5nLmRlYnVnKCJleGl0aW5nIGJhciIpCgpsb2dnaW5nLmJhc2ljQ29uZmlnKGZvcm1hdD0iJShhc2N0aW1lKS0xNXMgJShtZXNzYWdlKXMiLCBsZXZlbD1sb2dnaW5nLkRFQlVHKQoKcyA9IFNwYXduKGJhcigpKQp3aGlsZSBub3Qgcy5oYXNSZXN1bHQoKToKICAgIGxvb3AucG9sbCgp
stdout
stderr
2016-03-24 21:19:20,142 entered bar
2016-03-24 21:19:20,142 1 entered foo
2016-03-24 21:19:20,142 1 before sleep
2016-03-24 21:19:20,142 2 entered foo
2016-03-24 21:19:20,143 2 before sleep
2016-03-24 21:19:20,143 waiting for f1
2016-03-24 21:19:20,242 1 after sleep
2016-03-24 21:19:20,243 1 before sleep
2016-03-24 21:19:20,293 2 after sleep
2016-03-24 21:19:20,293 2 before sleep
2016-03-24 21:19:20,343 1 after sleep
2016-03-24 21:19:20,343 1 before sleep
2016-03-24 21:19:20,443 1 after sleep
2016-03-24 21:19:20,443 1 before sleep
2016-03-24 21:19:20,443 2 after sleep
2016-03-24 21:19:20,443 2 before sleep
2016-03-24 21:19:20,543 1 after sleep
2016-03-24 21:19:20,543 1 before sleep
2016-03-24 21:19:20,593 2 after sleep
2016-03-24 21:19:20,593 2 before sleep
2016-03-24 21:19:20,643 1 after sleep
2016-03-24 21:19:20,643 1 before sleep
2016-03-24 21:19:20,743 1 after sleep
2016-03-24 21:19:20,744 1 before sleep
2016-03-24 21:19:20,744 2 after sleep
2016-03-24 21:19:20,744 2 before sleep
2016-03-24 21:19:20,844 1 after sleep
2016-03-24 21:19:20,844 1 before sleep
2016-03-24 21:19:20,894 2 after sleep
2016-03-24 21:19:20,894 2 exiting foo
2016-03-24 21:19:20,944 1 after sleep
2016-03-24 21:19:20,944 1 before sleep
2016-03-24 21:19:21,044 1 after sleep
2016-03-24 21:19:21,044 1 before sleep
2016-03-24 21:19:21,144 1 after sleep
2016-03-24 21:19:21,144 1 exiting foo
2016-03-24 21:19:21,144 f1 result is 10
2016-03-24 21:19:21,145 waiting for f2
2016-03-24 21:19:21,145 f1 result is 5
2016-03-24 21:19:21,145 exiting bar