Sleep
import logging
import time
import random
import typing
import awaitable
@awaitable.awaitable
def do_process(name: str,
t: typing.Union[int, float]) -> None:
"""
Await some time before returning
:param name: task name
:param t: time to sleep in seconds
:return: None
"""
logging.info(f'From {name}: awaiting {t} seconds...')
starting_time = time.time()
time.sleep(t)
logging.info(f'From {name}: task complete '
f'in {time.time() - starting_time:.2f} seconds')
La funzione do_process
è contrassegnata come awaitable e semplicemente
registrerà un testo descrittivo e attenderà un numero di secondi passato
dall’argomento t
.
async def process(count: int) -> None:
"""
Run some processes asynchronously
Each process will await a random number of seconds
:param count: number of tasks to process
:return: None
"""
logging.info(f'Running {count} processes')
tasks = awaitable.AsyncioGather()
for i in range(count):
tasks.add(do_process(name=f'task_{tasks.count() + 1}',
t=random.randint(0, count)))
logging.info(f'Starting to process {len(tasks)} tasks')
await tasks.run()
La funzione process
è una funzione asincrona che raccoglierà un numero di
processi prima di elaborarli tutti insieme in maniera asincrona.
Come risultato, tutte le chiamate a sleep (vedi la funzione do_process
)
saranno eseguite più o meno allo stesso momento e l’intero processo sarà
completato quando l’attesa più lunga verrà completata.
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO,
format='%(levelname)-8s '
'%(filename)-15s '
'line: %(lineno)-5d '
'%(funcName)-20s '
'%(message)s')
starting_time = time.time()
awaitable.run_awaitable(func=process,
count=10)
ending_time = time.time()
logging.info(f'Operation completed in {ending_time - starting_time:.2f} '
'seconds')
La chiamata alla funzione run_awaitable
richiamerà la funzione asincrona
process
passando il numero 10 di lavori paralleli da processare.
Al termine sarà mostrato il numero di secondi passati per completare l’operazione.
INFO 01_sleep.py line: 53 process Running 10 processes
INFO 01_sleep.py line: 58 process Starting to process 10 tasks
INFO 01_sleep.py line: 38 do_process From task_1: awaiting 10 seconds...
INFO 01_sleep.py line: 38 do_process From task_2: awaiting 0 seconds...
INFO 01_sleep.py line: 41 do_process From task_2: task complete in 0.00 seconds
INFO 01_sleep.py line: 38 do_process From task_3: awaiting 2 seconds...
INFO 01_sleep.py line: 38 do_process From task_4: awaiting 9 seconds...
INFO 01_sleep.py line: 38 do_process From task_5: awaiting 7 seconds...
INFO 01_sleep.py line: 38 do_process From task_6: awaiting 10 seconds...
INFO 01_sleep.py line: 38 do_process From task_7: awaiting 5 seconds...
INFO 01_sleep.py line: 38 do_process From task_8: awaiting 5 seconds...
INFO 01_sleep.py line: 38 do_process From task_9: awaiting 8 seconds...
INFO 01_sleep.py line: 38 do_process From task_10: awaiting 0 seconds...
INFO 01_sleep.py line: 41 do_process From task_10: task complete in 0.00 seconds
INFO 01_sleep.py line: 41 do_process From task_3: task complete in 2.00 seconds
INFO 01_sleep.py line: 41 do_process From task_8: task complete in 5.00 seconds
INFO 01_sleep.py line: 41 do_process From task_7: task complete in 5.00 seconds
INFO 01_sleep.py line: 41 do_process From task_5: task complete in 7.01 seconds
INFO 01_sleep.py line: 41 do_process From task_9: task complete in 8.01 seconds
INFO 01_sleep.py line: 41 do_process From task_4: task complete in 9.01 seconds
INFO 01_sleep.py line: 41 do_process From task_1: task complete in 10.01 seconds
INFO 01_sleep.py line: 41 do_process From task_6: task complete in 10.01 seconds
INFO 01_sleep.py line: 74 <module> Operation completed in 10.02 seconds
Verranno eseguiti 10 lavori con un’attesa casuale tra 0 e 10 secondi e l’intera operazione verrà completata in circa 10.02 secondi. Senza usare async o awaitable l’operazione in maniera sincrona avrebbe impiegato circa 56 secondi.