【问题标题】:ERROR:root:Error in xyz There is no current event loop in thread 'Thread-7'错误:root:xyz 中的错误线程“Thread-7”中没有当前事件循环
【发布时间】:2020-07-17 13:40:05
【问题描述】:

我正在尝试实现 fire_and_forget 功能,这里是详细信息。

我正在尝试使用的异步装饰器:

import asyncio
import time


def fire_and_forget(f):
    def wrapped(*args, **kwargs):
        return asyncio.get_event_loop().run_in_executor(None, f, *args, *kwargs)

    return wrapped

我使用上述装饰器的异步调用:

@fire_and_forget
def call_async(self, req, body, headers_params):
    logger.info("Calling ASYNC")
    try:
        f = urllib.request.urlopen(req)
        response = f.read()
        f.close()
    except Exception as e:
        logger.exception("api exception %s" % e)
        return None

    # Parse and return the response
    try:
        res = self._parse_response(response)
    except Exception as e:
        logger.exception("Exception in parsing response of %s" % e)
        res = None
    logger.debug("clevertap response: {}".format(res))
    

我的 Flask 应用程序调用 test_xyz 反过来触发上述火灾并忘记 call_async:

from flask import Flask, jsonify, request
from call_xyz import test_xyz

app = Flask(__name__)

@app.route('/events_dm')
def events_dm():
    session_id = request.args.get('sessionId', "11111111")
    test_obj = test_xyz(session_id)
    test_obj.track_test()
    return jsonify({"success": True})


app.run(
            host='0.0.0.0',
            port=8091,
            debug=True,
            threaded=True
        )

我无法理解在哪里正确设置我的事件循环,因此我不会收到错误消息:“xyz 中的错误线程 'Thread-7' 中没有当前事件循环”并且我的事件被正确触发.

【问题讨论】:

    标签: python-3.x flask async-await python-asyncio fire-and-forget


    【解决方案1】:

    Flask 不兼容 asyncio,因此您不应尝试在其中使用 asyncio。

    此外,您实际上并没有使用 asyncio 的功能,而是调用了 concurrent.futuresrun_in_executor,即在后台使用线程。如果这是您需要的,您可以直接创建一个执行器,然后将您的函数提交给它。例如:

    import concurrent.futures
    _pool = concurrent.futures.ThreadPoolExecutor()
    
    def fire_and_forget(f):
        def wrapped(*args, **kwargs):
            return _pool.submit(lambda: f(*args, **kwargs))
        return wrapped
    

    【讨论】:

      【解决方案2】:

      你大概必须经历一次asyncio的用法和它的主要心event loop的理解。

      Similar issue这可能有助于你理解。

      这里是tutorial,有一些很好的解释

      请给出一些关于如何将coroutine 与普通Flask 应用程序一起使用的流程,这是示例之一。

      import asyncio
      import datetime
      
      from flask import Flask, jsonify, request
      
      
      app = Flask(__name__)
      
      def print_now():
          print(datetime.datetime.now())
      
      
      async def keep_printing(name: str="") -> None:
          print(name, end=" ")
          print_now()
          await asyncio.sleep(1.50)
      
      
      async def main(num_times):
          result = await asyncio.gather(
              keep_printing("first"),
              keep_printing("second"),
              keep_printing("third"),
          )
          return result
      
      
      def execute_statement():
          loop = asyncio.new_event_loop()
          asyncio.set_event_loop(loop)
          loop.run_until_complete(main(2))
          loop.close()
      
      
      @app.route('/events_dm')
      def events_dm():
          execute_statement()
          return jsonify({"success": True})
      
      app.run(
                  host='0.0.0.0',
                  port=8091,
                  debug=True,
                  threaded=True
              )
      
      

      点击/events_dm时的输出

      first 2020-07-18 00:46:26.452921
      second 2020-07-18 00:46:26.452921
      third 2020-07-18 00:46:26.452921
      127.0.0.1 - - [18/Jul/2020 00:46:27] "GET /events_dm HTTP/1.1" 200 -
      

      【讨论】:

        猜你喜欢
        • 2018-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-20
        • 1970-01-01
        相关资源
        最近更新 更多