提问人:Tekay37 提问时间:11/9/2023 最后编辑:Tekay37 更新时间:11/9/2023 访问量:40
Python Windows 服务仅在作为 -debug 启动时运行
python windows service only runs when started as -debug
问:
我有一个运行 hypercorn 的 Windows 服务。在 python 3.7 中一切正常。现在我们想将我们的服务移动到 python 3.11,但是在启动服务时出现错误:
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
但是,这仅在通过 启动服务时发生,当我通过 启动它时不会发生。在后一种情况下,服务运行没有问题。sc start service_name
pytonservice.exe -debug service_name
失败的代码如下所示:
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() # fails here
loop.run_until_complete(serve(dispatcher, hypercorn_cfg, shutdown_trigger=shutdown_trigger.wait))
我读到对 asyncio 进行了一些更改,包括 ,这导致了一些错误,但据称这些错误已在 3.9 中修复。get_event_loop()
然而。我也尝试用
asyncio.run(serve(dispatcher, hypercorn_cfg, shutdown_trigger=shutdown_trigger.wait))
但是,我收到同样的错误。当我完全省略shutdown_trigger时,同样的问题。
服务等级没什么特别的:
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():
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)
我不明白如何定期运行服务将代码放在不同的线程中,我不知道该怎么做(或者在这种情况下如何以不同的方式启动 hypercorn)。
编辑:
我还检查了我所在的线程:在这两种情况下都有 5 个线程,当前线程是 .MainThread
这是否表明 python 中仍然存在错误?
答:
1赞
Tekay37
11/9/2023
#1
没关系。我找到了解决方案。出于某种原因,默认值不喜欢作为服务运行。WindowsProactorEventLoopPolicy
添加
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
解决了问题。如果有人能向我解释,为什么会这样,那就太好了。
祝你有美好的一天,亲爱的 StackOverflowers。🌻
下一个:有没有办法逆转的运动
评论