Using coroutines your code could be rewritten as:
import asyncio
@asyncio.coroutine
def task(depth):
print('started depth %d' % (depth, ))
if depth > 10:
return depth
else:
# create new task
t = asyncio.async(task(depth + 1))
# wait for task to complete
yield from t
# get the result of the task
return t.result()
loop = asyncio.get_event_loop()
result = loop.run_until_complete(task(1))
print(result)
loop.close()
However, I'm struggling to see why you need all this extra code. In your example code you always wait directly for the result of the task, thus your code would run no different without the executor. For example, the following would produce the same result
def task(depth):
print 'started depth %d' % (depth, )
if depth > 10:
return depth
else:
task(depth + 1)
I think this example from the documentation better shows how async coroutines are able to parallelise tasks. This example creates 3 tasks, each of which computes a different factorial. Notice how when each task yields to another coroutine (in this case async.sleep
), another task is allowed to continue its execution.
import asyncio
@asyncio.coroutine
def factorial(name, number):
f = 1
for i in range(2, number+1):
print("Task %s: Compute factorial(%s)..." % (name, i))
yield from asyncio.sleep(1)
f *= i
print("Task %s: factorial(%s) = %s" % (name, number, f))
loop = asyncio.get_event_loop()
tasks = [
asyncio.ensure_future(factorial("A", 2)),
asyncio.ensure_future(factorial("B", 3)),
asyncio.ensure_future(factorial("C", 4))]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
Output:
Task A: Compute factorial(2)...
Task B: Compute factorial(2)...
Task C: Compute factorial(2)...
Task A: factorial(2) = 2
Task B: Compute factorial(3)...
Task C: Compute factorial(3)...
Task B: factorial(3) = 6
Task C: Compute factorial(4)...
Task C: factorial(4) = 24