简体   繁体   English

如何同时维护多个run_forever处理程序?

[英]How to maintain multiple run_forever handlers simultaneously?

Imagine you have a background processing daemon which could be controlled by a web interface. 假设您有一个后台处理守护程序,可以通过Web界面进行控制。

So, the app is an object with some methods responsible for handling requests and one special method that needs to be called repeatedly from time to time, regardless of requests state. 因此,该应用程序是一个对象,具有一些负责处理请求的方法和一个特殊方法,无论请求状态如何,都需要不时地反复调用它。

When using aiohttp , the web part is fairly straightforward: you just instantiate an application instance, and set things up as per aiohttp.web.run_app source. 使用aiohttp ,Web部件非常简单:您只需实例化一个应用程序实例,然后根据aiohttp.web.run_app源进行设置。 Everything is clear. 一切都清楚了。 Now let's say your app instance has that special method, call it app.process , which is structured like so: 现在,假设您的应用实例具有该特殊方法,将其app.process ,其结构如下:

async def process(self):
    while self._is_running:
        await self._process_single_job()

With this approach you could call loop.run_until_complete(app.process()) , but it blocks, obviously, and thus leaves no opportunity to set up the web part. 使用这种方法,您可以调用loop.run_until_complete(app.process()) ,但是显然它会阻塞,因此没有机会设置Web部件。 Surely, I could have split these two responsibilities into separate processes and establish their communication by means of a database, but that would complicate things, so I would prefer to avoid this way if at all possible. 当然,我可以将这两个职责划分为单独的流程,并通过数据库建立它们的通信,但这会使事情复杂化,因此,我将尽可能避免这种方式。

So, how do I make the event loop call some method repeatedly while still running a web app? 因此,如何在仍然运行Web应用程序的同时使事件循环重复调用某些方法?

You have to schedule the execution of app.process() as a task using loop.create_task : 您必须使用loop.create_taskapp.process()的执行安排为任务:

import asyncio
from aiohttp import web

class MyApp(web.Application):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.process_task = self.loop.create_task(self.process())
        self.on_shutdown.append(lambda app: app.process_task.cancel())

    async def process(self):
        while True:
            print(await asyncio.sleep(1, result='ping'))

if __name__ == '__main__':
    web.run_app(MyApp())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM