Python3.11下Windows服务启动Hypercorn报错仅Debug模式可运行
Python 3.11下Windows服务启动Hypercorn报错:set_wakeup_fd only works in main thread of the main interpreter
原本在Python 3.7环境下,运行Hypercorn的Windows服务一切正常。升级到Python 3.11后,使用sc start service_name启动服务时出现如下报错:
Traceback (most recent call last): File "...\service.py", line 108, in main run_hypercorn(app, self.host, self.port, self.shutdown_trigger) File "...\run.py", line 36, in run_hypercorn asyncio.run(serve(dispatcher, hypercorn_cfg, shutdown_trigger=shutdown_trigger.wait)) File "asyncio\runners.py", line 189, in run File "asyncio\runners.py", line 59, in __enter__ File "asyncio\runners.py", line 137, in _lazy_init File "asyncio\events.py", line 806, in new_event_loop File "asyncio\events.py", line 695, in new_event_loop File "asyncio\windows_events.py", line 315, in __init__ File "asyncio\proactor_events.py", line 642, in __init__ ValueError: set_wakeup_fd only works in main thread of the main interpreter
但使用pytonservice.exe -debug service_name启动时,服务可正常运行。
相关代码
run_hypercorn函数
import asyncio from hypercorn.config import Config as HypercornConfig from hypercorn.asyncio import serve from hypercorn.middleware import DispatcherMiddleware def run_hypercorn(app, host, port, shutdown_trigger=None): dav = dav_app(...) dispatcher = DispatcherMiddleware( { '/dav': dav, '': app, } ) hypercorn_cfg = HypercornConfig() hypercorn_cfg.bind = f'{host}:{port}' if shutdown_trigger is None: asyncio.run(serve(dispatcher, hypercorn_cfg)) else: loop = asyncio.get_event_loop() # 报错位置 loop.run_until_complete(serve(dispatcher, hypercorn_cfg, shutdown_trigger=shutdown_trigger.wait))
Windows服务类
class AppServerSvc(win32serviceutil.ServiceFramework): _svc_name_ = "" _svc_display_name_ = "" def __init__(self, args): self.shutdown_trigger = asyncio.Event() self.app: FastAPI = None self.config: Config = None self.port: int = None self.host: str = None def SvcDoRun(self, *args, **kwargs): self.ReportServiceStatus(win32service.SERVICE_START_PENDING) self.main() def main(self): from ___.app import app from ___.run import run_hypercorn, run_uvicorn self.config = Config.new('config.ini', installation_folder=self.path) self.app = app self.port = self.config.webserver.get('port', None) self.host = self.config.webserver.get('host', None) self.app.state.config = self.config self.ReportServiceStatus(win32service.SERVICE_RUNNING) run_hypercorn(app, self.host, self.port, self.shutdown_trigger) if __name__ == '__main__': win32serviceutil.HandleCommandLine(AppServerSvc)
已尝试的操作
- 了解到asyncio的
get_event_loop()等功能曾有变更导致bug,据称3.9版本已修复,但问题仍存在 - 尝试改用
asyncio.run(serve(dispatcher, hypercorn_cfg, shutdown_trigger=shutdown_trigger.wait))调用 - 完全移除shutdown_trigger参数,仍出现相同报错
- 检查线程情况:两种启动方式下均有5个线程,当前线程均为
MainThread
疑问
- 无法理解常规启动服务为何会触发该错误,不知道如何调整Hypercorn的启动方式
- 该问题是否是Python仍未修复的bug?
内容的提问来源于stack exchange,提问作者Tekay37
相关产品推荐
相关产品推荐

