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})