Python-无法对aiohttp使用多个事件循环
我正试图使一个代码类似于这一个工作Python-无法对aiohttp使用多个事件循环,python,python-3.x,aiohttp,aio,python-asyncio,Python,Python 3.x,Aiohttp,Aio,Python Asyncio,我正试图使一个代码类似于这一个工作 福福类: 定义初始化(自): loop=asyncio.get\u event\u loop() self.value=loop.run\u直到完成(self.async\u work()) 异步定义异步工作(自): 返回10 def build_server(): app=web.Application() app.router.add_route('GET','/',hello) web.run_应用程序(应用程序'localhost','12000')
福福类:
定义初始化(自):
loop=asyncio.get\u event\u loop()
self.value=loop.run\u直到完成(self.async\u work())
异步定义异步工作(自):
返回10
def build_server():
app=web.Application()
app.router.add_route('GET','/',hello)
web.run_应用程序(应用程序'localhost','12000')
异步def hello(请求):
foo=等待foo()
返回web.json_响应{'ip':request.remote,'value':foo.value}
做卷曲http://127.0.0.1:/
产生此错误:
Error handling request
Traceback (most recent call last):
File "/usr/local/lib64/python3.6/site-packages/aiohttp/web_protocol.py", line 418, in start
resp = await task
File "/usr/local/lib64/python3.6/site-packages/aiohttp/web_app.py", line 458, in _handle
resp = await handler(request)
File "/usr/local/lib64/python3.6/site-packages/aiohttp/web_urldispatcher.py", line 155, in handler_wrapper
result = old_handler(request)
File "test.py", line 36, in hello
foo = asyncio.get_event_loop().run_until_complete(FooFoo())
File "test.py", line 24, in __init__
self.value = loop.run_until_complete(self.async_work())
File "/usr/lib64/python3.6/asyncio/base_events.py", line 471, in run_until_complete
self.run_forever()
File "/usr/lib64/python3.6/asyncio/base_events.py", line 425, in run_forever
raise RuntimeError('This event loop is already running')
RuntimeError: This event loop is already running
这是因为服务器正在事件循环上运行,并且foooo
希望重新运行循环
我尝试过的解决方案:
- 将
功能更改为具有以下功能的同步功能:hello
,给出相同的错误foo=asyncio.get\u event\u loop()。运行\u直到\u完成(FooFoo())
- 多处理:使用库pool、threading、Multiprocessing、aioprocessing在另一个线程/进程上运行服务器实例,这会产生不同的错误:
- 给出与多处理相同的错误
- 还有
如果有帮助,我正在使用python 3.6.8如果您稍微将逻辑更改为以下内容:
import asyncio
from aiohttp import web
class FooFoo(object):
async def async_work(self):
await asyncio.sleep(1)
self.value = 10
async def hello(request):
foo = FooFoo()
await foo.async_work()
return web.json_response({'ip': request.remote, 'value': foo.value})
def build_server():
app = web.Application()
app.router.add_route('GET', '/', hello)
web.run_app(app, host='localhost', port=8080)
你会让它工作的
更新根据OP评论中的详细信息:
Foooo类是一个客户端,它通过异步方式生成令牌
对服务器的请求。用户不应该实例化foooo,
然后稍后生成一个令牌
我建议使用用于简化复杂对象创建的。我认为这种式样很适合这种情况。为了应用该模式,我们添加了一个新的fooBuilder
类:
async def request_token():
await asyncio.sleep(1)
return 42
class FooFooBuilder(object):
@staticmethod
async def build():
token = await request_token()
# Do token validation and error handling.
return FooFoo(token)
foooo
类将在实例化期间将token
作为其参数:
class FooFoo(object):
def __init__(self, token):
self.value = token
因此,hello
请求处理程序将更改为:
async def hello(request):
foo = await FooFooBuilder.build()
return web.json_response({'ip': request.remote, 'value': foo.value})
使用这种方法,不需要使用多个事件循环来完成任务。我给出的只是一个简单的示例,我需要在
\uuuuu init\uuuu
函数中完成一些工作,因此我无法删除它并添加另一条指令来执行上述工作。所有的事情都必须在实例化过程中完成,如果我能使\uuu init\uuu
异步
,那么它可能会解决这个特定的问题,尽管它会创建更多的问题,而且无论如何,使用异步魔法函数是非法的。你能告诉我为什么在实例化过程中严格要求运行异步代码吗?在这种情况下,您必须等待一些资源能够构建foooo
实例,然后为什么不先使用工厂模式异步收集所有资源,然后在一切就绪后,实例化foooo
类foooo
类是一个客户端,它通过对服务器的异步请求生成令牌。用户不应该实例化foooo
,然后生成令牌。环境需要保持控制,因此一些事情在实例化时完成。好的,那么为什么不创建一个fooobuilder
类,该类将请求一个令牌,然后将其传递给foooo
构造函数并返回其实例呢?类似于wait foo=fooobuilder.build()
的内容,其中在这个静态方法中异步请求一个令牌。我想说的是,你可能会把事情弄得有点复杂,并因此撞到墙上:)你有没有理由觉得需要在构造函数中启动一个事件循环,阻塞它,然后再次尝试等待事件循环的有效负载?您是否正在寻找工厂功能?
async def hello(request):
foo = await FooFooBuilder.build()
return web.json_response({'ip': request.remote, 'value': foo.value})