【问题标题】:Asyncio with Django与 Django 的异步
【发布时间】:2017-01-11 15:07:31
【问题描述】:

我正在尝试在我的 Django 后期处理中使用 asyncio,例如:

query : # a query to my model
tasks =  []        
for record in query:
    tasks.append(do_something_with_google_calendar(record))

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

但我只是在执行时遇到错误:

loop = asyncio.get_event_loop()

RuntimeError: There is no current event loop in thread 'Thread-17'.

有什么想法吗?

提前谢谢你

【问题讨论】:

  • do_something_with_google_calendar(record)方法是如何定义的
  • @asyncio.coroutine def do_something_with_google_calendar(args):
  • 为什么不使用Celery 之类的东西进行后期处理? AsyncIO 不是用于后处理,而是用于非阻塞 IO。
  • 我开始意识到这一点。
  • 我认为我可以设法以异步方式访问 Google Calendar。我使用 pythonanywhere 服务器。我不能在那里使用 Celery。我可能不得不换一个新的服务器。

标签: python django multithreading loops python-asyncio


【解决方案1】:

您的原始代码将不起作用,因为 get_event_loop() 方法只是 get_event_loop_policy().get_event_loop() 的快捷方式,该方法仅为主线程自动创建和返回事件循环。 要使其正常工作,您需要为每个当前线程上下文显式创建和设置新的事件循环:

query : # a query to my model
tasks =  []        
for record in query:
    tasks.append(do_something_with_google_calendar(record))

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

你可以阅读更多关于这些东西here

【讨论】:

    【解决方案2】:

    看起来如果我这样做,它会起作用:

    query : # a query to my model
    tasks =  []        
    for record in query:
        tasks.append(do_something_with_google_calendar(record))
    
    loop = asyncio.SelectorEventLoop()
    asyncio.set_event_loop(loop)
    
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()
    

    我希望它是稳定的,它在 UNIX 中也能像在 Windows 中一样正常工作

    【讨论】:

    • 每个单独的线程都需要自己的异步事件循环,因为每个循环都会接管线程的执行并为其安排异步函数/协程;因此,您可以使用asyncio.new_event_loop() 在每个线程中获取一次新的事件循环,然后get_event_loop() 将返回为该线程定义的循环。 (您的解决方案应该也能正常工作,因为 SelectorEventLoop 也会返回一个新循环)
    猜你喜欢
    • 2022-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 2014-06-17
    相关资源
    最近更新 更多