RuntimeError:任务中应使用超时上下文管理器

编程入门 行业动态 更新时间:2024-10-24 01:48:37
本文介绍了RuntimeError:任务中应使用超时上下文管理器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

背景:我将在一个不和谐的客户端旁边托管一个Flask服务器

flask服务器只需要将消息从客户端传递给Discord,并将消息从Discord传递给

我在调用 loop.run_until_complete(sendMsg(request)) $ b时遇到错误$ b我在 sendMsg 和 wait_for 中尝试了 wait_for loop.run_until_complete()

我到处都没有发现任何东西,所以对您有所帮助。 / p>

代码:

import discord import json import os 从烧瓶导入asyncio 从烧瓶导入,请求,render_template 从async_timeout导入超时从线程导入线程从时间import sleep 客户端= discord.Client()消息= [] 应用= Flask(__ name__) def startClient():循环=异步。 new_event_loop() asyncio.set_e vent_loop(loop) client.run('token') ##不和谐事件# @ client.event 异步定义on_ready(): print('Discord Client Ready') @ client.event 异步定义on_message(message):全局消息 message.append(message) ##Flask Stuff # async def sendMsg(request):等待client.send_message(discord.Object('channel id'),request.form ['message']) @ app.route( / chat /,方法= [ 'GET','POST']) def chatPage():全局消息 如果request.method =='GET': return render_template(' main.html') elif request.method =='POST': loop = asyncio.new_event_loop() loop.run_until_complete(sendMsg(request)) return'' @ app.route( / chat / get,Methods = ['GET']) def chatGet():返回json.dumps( messages [int(request.args ['lastMessageId']):]) #启动所有内容 os.environ [ WERKZEUG_RUN_MAIN] ='true' print('Starting discord.py client') Thread(target = startClient).start() print('Starting flask') app.run(host ='0.0.0.0',debug = True)

跟踪:

跟踪(最近一次通话最近): File / home / SuperKooks /.local/lib/python3.5/site-packages/flask/app.py,第2309行,位于__call__ return self.wsgi_app(environ,start_response)文件 / home / SuperKooks / .local / lib / python3.5 / site-packages / flask / app.py,第2295行,在wsgi_app 响应= self.handle_exception(e)文件 /home/SuperKooks/.local /lib/python3.5/site-packages/flask/app.py,行1741,在handle_exception中 reraise(exc_type,exc_value,tb)文件 /home/SuperKooks/.local/lib /python3.5/site-packages/flask/_compat.py,第35行,加注提高价值文件 /home/SuperKooks/.local/lib/python3.5/site-packages /flask/app.py,第2292行,在w中sgi_app 响应= self.full_dispatch_request()文件 /home/SuperKooks/.local/lib/python3.5/site-packages/flask/app.py,行1815,在full_dispatch_request $ b中$ b rv = self.handle_user_exception(e)文件 /home/SuperKooks/.local/lib/python3.5/site-packages/flask/app.py,第1718行,在handle_user_exception 中reraise(exc_type,exc_value,tb)文件 /home/SuperKooks/.local/lib/python3.5/site-packages/flask/_compat.py,第35行,用于提高的价值文件 /home/SuperKooks/.local/lib/python3.5/site-packages/flask/app.py,行1813,在full_dispatch_request中 rv = self.dispatch_request()在dispatch_request 中的文件 /home/SuperKooks/.local/lib/python3.5/site-packages/flask/app.py,行1799,返回self.view_functions [rule.endpoint](** req .view_args)文件 /mnt/c/Users/SuperKooks/Documents/Coding/HTML/kindle-discord/app.py,第51行,位于chatPage loop.run_until_complete(sendMsg(request) )文件 /usr/lib/python3.5/asyncio/base_events.py,行387,在run_until_complete 中返回future.result()文件 /usr/lib/python3.5/asyncio/futures .py,第274行,结果提高self._exception 文件 /usr/lib/python3.5/asyncio/tasks.py,第239行,在_step result = coro.send(None)文件 /mnt/c/Users/SuperKooks/Documents/Coding/HTML/kindle-discord/app.py,第39行,位于sendMsg 中,等待client.send_message( discord.Object('382416348007104513'),request.form ['message'])文件 /home/SuperKooks/.local/lib/python3.5/site-packages/discord/client.py,行1152,在send_message中数据=自身收益。http.send_message(channel_id,content,guild_id = guild_id,tts = tts,embed = embed) File /home/SuperKooks/.local/lib/ python3.5 / site-packages / discord / http.py,第137行,请求中的r = self.session.request(方法,URL,** kwargs)的收益文件 / home / SuperKooks / .local / lib / python3.5 / site-packages / aiohttp / client.py, 555,在__iter__中 resp = self._coro 的文件 /home/SuperKooks/.local/lib/python3.5/site-packages/aiohttp/client.py,第197行,在_request 中,带有超时(超时,循环= self._loop):文件 /home/SuperKooks/.local/lib/python3.5/site-packages/async_timeout/__init__.py,行39,在__enter__ 中返回self._do_enter()文件 /home/SuperKooks/.local/lib/python3.5/site-packages/async_timeout/__init__.py,第76行,_do_enter 提高RuntimeError('应该使用超时上下文管理器' RuntimeError:超时上下文管理器应该在任务

$ b中使用$ b

解决方案

问题似乎可能由以下原因引起:

elif request.method =='POST': loop = asyncio.new_event_loop() loop.run_until_complete(sendMsg(request))

这将创建一个新的事件循环,并在其中运行 sendMsg(request)新循环。但是, sendMsg 调用 client 对象上在其自己的事件循环中运行的方法。 sendMsg 应该提交到在另一个线程中运行客户端的现有事件循环。为此,您需要:

  • 公开在 startClient 中创建的循环,例如到 client_loop 全局变量;
  • 替换 loop = asyncio.new_event_loop(); loop.run_until_complete(sendMsg(request))并调用 asyncio.run_coroutine_threadsafe 将协程提交到已经在其他线程中运行的事件循环中。

提交代码如下:

elif request.method = ='POST':#将协程提交到事件循环线程 send_fut = asyncio.run_coroutine_threadsafe(sendMsg(request),client_loop)#等待协程完成 send_fut.result()

Background: I am hosting a flask server alongside a discord client

The flask server just needs to pass on messages from the client to discord and from messages from discord to the client.

I am getting the error when I call loop.run_until_complete(sendMsg(request)) I have tried wait_for in sendMsg and wait_for loop.run_until_complete()

I have looked everywhere and haven't found anything so any help would be appreciated.

Code:

import discord import json import os import asyncio from flask import Flask, request, render_template from async_timeout import timeout from threading import Thread from time import sleep client = discord.Client() messages = [] app = Flask(__name__) def startClient(): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) client.run('token') # # Discord Events # @client.event async def on_ready(): print('Discord Client Ready') @client.event async def on_message(message): global messages message.append(message) # # Flask Stuff # async def sendMsg(request): await client.send_message(discord.Object('channel id'), request.form['message']) @app.route("/chat/", methods=['GET', 'POST']) def chatPage(): global messages if request.method == 'GET': return render_template('main.html') elif request.method == 'POST': loop = asyncio.new_event_loop() loop.run_until_complete(sendMsg(request)) return '' @app.route("/chat/get", methods=['GET']) def chatGet(): return json.dumps(messages[int(request.args['lastMessageId']):]) # Start everything os.environ["WERKZEUG_RUN_MAIN"] = 'true' print('Starting discord.py client') Thread(target=startClient).start() print('Starting flask') app.run(host='0.0.0.0', debug=True)

Traceback:

Traceback (most recent call last): File "/home/SuperKooks/.local/lib/python3.5/site-packages/flask/app.py", line 2309, in __call__ return self.wsgi_app(environ, start_response) File "/home/SuperKooks/.local/lib/python3.5/site-packages/flask/app.py", line 2295, in wsgi_app response = self.handle_exception(e) File "/home/SuperKooks/.local/lib/python3.5/site-packages/flask/app.py", line 1741, in handle_exception reraise(exc_type, exc_value, tb) File "/home/SuperKooks/.local/lib/python3.5/site-packages/flask/_compat.py", line 35, in reraise raise value File "/home/SuperKooks/.local/lib/python3.5/site-packages/flask/app.py", line 2292, in wsgi_app response = self.full_dispatch_request() File "/home/SuperKooks/.local/lib/python3.5/site-packages/flask/app.py", line 1815, in full_dispatch_request rv = self.handle_user_exception(e) File "/home/SuperKooks/.local/lib/python3.5/site-packages/flask/app.py", line 1718, in handle_user_exception reraise(exc_type, exc_value, tb) File "/home/SuperKooks/.local/lib/python3.5/site-packages/flask/_compat.py", line 35, in reraise raise value File "/home/SuperKooks/.local/lib/python3.5/site-packages/flask/app.py", line 1813, in full_dispatch_request rv = self.dispatch_request() File "/home/SuperKooks/.local/lib/python3.5/site-packages/flask/app.py", line 1799, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "/mnt/c/Users/SuperKooks/Documents/Coding/HTML/kindle-discord/app.py", line 51, in chatPage loop.run_until_complete(sendMsg(request)) File "/usr/lib/python3.5/asyncio/base_events.py", line 387, in run_until_complete return future.result() File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result raise self._exception File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step result = coro.send(None) File "/mnt/c/Users/SuperKooks/Documents/Coding/HTML/kindle-discord/app.py", line 39, in sendMsg await client.send_message(discord.Object('382416348007104513'), request.form['message']) File "/home/SuperKooks/.local/lib/python3.5/site-packages/discord/client.py", line 1152, in send_message data = yield from self.http.send_message(channel_id, content, guild_id=guild_id, tts=tts, embed=embed) File "/home/SuperKooks/.local/lib/python3.5/site-packages/discord/http.py", line 137, in request r = yield from self.session.request(method, url, **kwargs) File "/home/SuperKooks/.local/lib/python3.5/site-packages/aiohttp/client.py", line 555, in __iter__ resp = yield from self._coro File "/home/SuperKooks/.local/lib/python3.5/site-packages/aiohttp/client.py", line 197, in _request with Timeout(timeout, loop=self._loop): File "/home/SuperKooks/.local/lib/python3.5/site-packages/async_timeout/__init__.py", line 39, in __enter__ return self._do_enter() File "/home/SuperKooks/.local/lib/python3.5/site-packages/async_timeout/__init__.py", line 76, in _do_enter raise RuntimeError('Timeout context manager should be used ' RuntimeError: Timeout context manager should be used inside a task

解决方案

The problem looks like it could be caused by the following:

elif request.method == 'POST': loop = asyncio.new_event_loop() loop.run_until_complete(sendMsg(request))

That creates a new event loop and runs sendMsg(request) in the new loop. However, sendMsg calls a method on the client object running in its own event loop. sendMsg should be submitted to the existing event loop that runs the client in the other thread. To accomplish that, you need to:

  • expose the loop created in startClient, e.g. to a client_loop global variable;
  • replace loop = asyncio.new_event_loop(); loop.run_until_complete(sendMsg(request)) with a call to asyncio.run_coroutine_threadsafe to submit the coroutine to an event loop already running in a different thread.

The submit code would look like this:

elif request.method == 'POST': # submit the coroutine to the event loop thread send_fut = asyncio.run_coroutine_threadsafe(sendMsg(request), client_loop) # wait for the coroutine to finish send_fut.result()

更多推荐

RuntimeError:任务中应使用超时上下文管理器

本文发布于:2023-11-23 10:08:51,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1621058.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:上下文   管理器   中应   RuntimeError

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!