async def run_task(self, task_name, task_fun):
self.logger.info(f'{task_name}')
begin_time = int(time.time())
self.task_state = False
# t = threading.Thread(target=self.check_task, args=(begin_time, task_name))
# t.start()
# t.join()
try:
await getattr(self, task_fun)()
await asyncio.sleep(1)
self.logger.warning(f'{task_name} -> DONE.')
self.task_state = True
except Exception as e:
self.logger.error(e)
self.task_state = True
finally:
await self.close_page()
await asyncio.sleep(1)
def check_task(self, begin_time, task_name):
while True:
if self.task_state:
return True
now_time = int(time.time())
n = now_time - begin_time
if n > 120:
self.logger.warning(f'{task_name} runtime {n}s.')
return False
time.sleep(1)
1
ysc3839 2021-01-20 17:29:55 +08:00 via Android
我不了解 Python 的 async,如果是 js 的话可以用 Promise.race,然后取消 task 运行。
|
2
Vegetable 2021-01-20 17:31:32 +08:00 1
想得倒是挺多,不过你没感觉这是一个很常见的需求吗?
https://docs.python.org/zh-cn/3/library/asyncio-task.html#timeouts async def main(): # Wait for at most 1 second try: await asyncio.wait_for(eternity(), timeout=1.0) except asyncio.TimeoutError: print('timeout!') asyncio.run(main()) |
3
linw1995 2021-01-21 14:47:44 +08:00
如果不是同步堵塞住的话,用 `asyncio.wait_for` 就好了。同步堵塞的话,建议修改这个函数,通过 `loop.run_in_executor` 用副线程去跑,这样就不会堵塞住了。同时在外部用 `asyncio.wait_for`,且通过在 coro 内部去 try-except 这个超时而抛出的 `asyncio.CancelError` ,再通过 theading.Event 等方式,把取消事件传递给副线程的函数
|