Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Appeler deux fois run_until_complete renvoie une erreur

0 votes

Je cherche à faire marcher asyncio pour faire tourner un process en arrière plan, après pas mal d'essais je suis arrivé à la conclusion que dans mon cas relativement simple, rununtilcomplete est la solution. Par contre, je tombe sur un problème: lorsque je lance le process deux fois de suite, la deuxième plante.

Mon code (simplifié en MWE):

# Import all required modules
import logging
import os
os.environ['PYTHONASYNCIODEBUG'] = '1'
import asyncio

# Define global variables
loop = asyncio.get_event_loop()
logging.basicConfig(level=logging.DEBUG)

# Wrapper around asyncBuild that manages the event loop part
def build(steps):
    global loop
    loop.run_until_complete(asyncBuild(steps))
    loop.stop()

# Inner function that actually does the job
async def asyncBuild(steps):
    for step in steps:
        print("building: " + step)

def stopBuild():
    global loop
    loop.stop()

build(['aaa'])
build(['bbb'])
loop.close()

Lorsqu'on atteint le deuxième appel à la fonction "build", python me renvoie une RuntimeError:

building: aaa
Traceback (most recent call last):
  File "test.py", line 30, in <module>
    build(['bbb'])
  File "test.py", line 17, in build
    loop.run_until_complete(asyncBuild(steps))
  File "/usr/local/Cellar/python3/3.5.0/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/base_events.py", line 340, in run_until_complete
    raise RuntimeError('Event loop stopped before Future completed.')
RuntimeError: Event loop stopped before Future completed.
DEBUG:asyncio:Close <_UnixSelectorEventLoop running=False closed=False debug=True>
/usr/local/Cellar/python3/3.5.0/Frameworks/Python.framework/Versions/3.5/lib/python3.5/asyncio/base_events.py:368: RuntimeWarning: coroutine 'asyncBuild' was never awaited

Y a-t-il un moyen de régler ça ? Pour un peu de contexte: j'appelle le script depuis un GUI en C++ via pythonQt, et je veux pouvoir arrêter la fonction "asyncBuild" en cours de route, d'où la fonction "stopBuild()".

demandé 2-Nov-2015 par LaTruelle (110 points)

1 Réponse

+1 vote
 
Meilleure réponse

Le message d'erreur dit : "Event loop stopped before Future completed."
Tu devrais essayer d'enlever les lignes "loop.stop()".

Ensuite, je ne vois pas pourquoi tu fais "global loop".

répondu 2-Nov-2015 par bubulle (2,256 points)
sélectionné 6-Nov-2015 par LaTruelle

Effectivement c'est mieux. Par contre, ça ne résout que la partie "courante". Si j'appelle la fonction stopBuild() depuis l'extérieur, tout plante.

Il y a un moyen d'arrêter la fonction en cours de route ou il faut passer par du threading ?

...