python - Asyncio print status of coroutines progress -


i have bunch of coroutines doing work

@asyncio.coroutine def do_work():     global counter     result = ...     if result.status == 'ok':         counter += 1 

and 1

counter = 0 @asyncio.coroutine def display_status():     while true:         print(counter)         yield asyncio.sleep(1) 

which have display how many coroutines have finished work. how implement task? following solution doesn't work

@asyncio.coroutine def spawn_jobs():     coros = []     in range(10):         coros.append(asyncio.task(do_work()))     yield asyncio.gather(*coros)  if __name__ == '__main__':     loop = asyncio.get_event_loop()     loop.create_task(display_status())     loop.run_until_complete(spawn_jobs())     loop.close() 

i expect counter printed console every second no matter do_work() coroutines do. have 2 outputs: 0 , after few seconds repeating 10.

but have 2 outputs: 0 , after few seconds repeating 10.

i can't reproduce it. if use:

import asyncio import random  @asyncio.coroutine def do_work():     global counter     yield asyncio.sleep(random.randint(1, 5))     counter += 1 

i output this:

0 0 4 6 8 task destroyed pending! task: <task pending coro=<display_status() running @ most_wanted.py:16> wait_for=<future pending cb=[task._wakeup()] created @ ../lib/asyncio/tasks.py:490> created @ most_wanted.py:27> 

the infinite loop in display_status() causes warning @ end. avoid warning; exit loop when tasks in batch done:

#!/usr/bin/env python3 import asyncio import random contextlib import closing itertools import cycle  class batch:     def __init__(self, n):         self.total = n         self.done = 0      async def run(self):         await asyncio.wait([batch.do_work() _ in range(batch.total)])      def running(self):         return self.done < self.total      async def do_work(self):         await asyncio.sleep(random.randint(1, 5)) # work here         self.done += 1      async def display_status(self):         while self.running():             await asyncio.sleep(1)             print('\rdone:', self.done)      async def display_spinner(self, char=cycle('/|\-')):         while self.running():             print('\r' + next(char), flush=true, end='')             await asyncio.sleep(.3)  closing(asyncio.get_event_loop()) loop:     batch = batch(10)     loop.run_until_complete(asyncio.wait([         batch.run(), batch.display_status(), batch.display_spinner()])) 

output

done: 0 done: 2 done: 3 done: 4 done: 10 

Comments