2017-10-16 6 views
3

run_in_executorで呼び出されたrun_long_thing()関数で例外を発生させるにはどうすればよいですか? 飲み込まれているようです。私は、ブロッキングコードの関数の結果は必要ありません。それは基本的に火災で、機能を忘れて、それでも私はいずれかが存在する場合、例外をキャッチする必要があります...すべてのPythonのrun_in_executorメソッド呼び出しで例外をキャッチする方法

import asyncio 
import time 


def fire_and_forget(task, *args, **kwargs): 
    loop = asyncio.get_event_loop() 
    if callable(task): 
     #if threadpoolworker is set to None, 
     #the max_workers will default to the number of processors on the machine, multiplied by 5 
     return loop.run_in_executor(None, task, *args, **kwargs) 
    else:  
     raise TypeError('Task must be a callable.') 


async def run_long_thing(sleep): 
    print("Doing long thing... {:}".format(sleep)) 
    time.sleep(sleep) 
    print("Done doing long thing. {:}".format(sleep)) 
    raise Exception("sh*t happens") 


def do_it(): 
    print("Starting my main thing...") 
    print("Calling my long thing...") 
    for i in range(0,10,1): 
     try: 
      fire_and_forget(run_long_thing, i) 
      print(i) 
      print("Pom pi dom...") 
      time.sleep(0.1) 
      print("POOOOM Pom pi dom...") 
     except: 
      print("can i see the sh*t?") 

do_it() 

答えて

2

まず、あなたがtime.sleepを呼び出す場合は、asyncioイベントループを実行してしまうことは決してないだろう結果は検出されません。代わりにdo_ittime.sleepを呼び出すあなたは今

asyncio.get_event_loop().run_until_complete(asyncio.sleep(0.1)) 

ような何かをやったほうが良いです、run_in_executorからの復帰が未来です。あなたは非同期DEFを書いて、あなたの現在のコードに沿った

async def run_long_thing(thing, *args): 
    try: await asyncio.get_event_loop().run_in_executor(None, thing, *args) 
    except: 
     #do stuff 

しかし、より多くのような何かを行うことができ、あなたのasyncioループ上create_taskを使用して気にしない場合は、例外コールバックを添付することができ

def callback(future): 
if future.exception(): #your long thing had an exception 
     # do something with future.exception() 

その後、あなたはrun_in_executor呼び出す:

future = asyncio.get_event_loop().run_in_executor(None, fun, *args) 
future.add_done_callback(callback) 

が続いcallbackが呼び出されるたびにエグゼキュータのタスクCOMPL etes。 future.result()には例外がなければ結果が含まれ、future.exception()には発生した例外が戻されます

関連する問題