Leu*_*uko 7 python multiprocessing fastapi uvicorn
我正在寻找将 uvicorn.run() 与 FastAPI 应用程序一起使用但没有 uvicorn.run() 阻塞线程的可能性。我已经尝试使用进程、子进程和线程,但没有任何效果。我的问题是我想从另一个进程启动服务器,该进程在启动服务器后应该继续执行其他任务。另外,我在从另一个进程关闭服务器时遇到了问题。
有没有人知道如何使用 uvicorn.run() 非阻塞以及如何从另一个进程中阻止它?
问候 LeukoClassic
Eli*_*jas 11
@HadiAlqattan 给出的方法将不起作用,因为uvicorn.run期望在主线程中运行。signal only works in main thread会引发诸如此类的错误。
正确的做法是:
import contextlib
import time
import threading
import uvicorn
class Server(uvicorn.Server):
def install_signal_handlers(self):
pass
@contextlib.contextmanager
def run_in_thread(self):
thread = threading.Thread(target=self.run)
thread.start()
try:
while not self.started:
time.sleep(1e-3)
yield
finally:
self.should_exit = True
thread.join()
config = Config("example:app", host="127.0.0.1", port=5000, log_level="info")
server = Server(config=config)
with server.run_in_thread():
# Server is started.
...
# Server will be stopped once code put here is completed
...
# Server stopped.
Run Code Online (Sandbox Code Playgroud)
使用 pytest 夹具在本地运行实时测试服务器非常方便:
# conftest.py
import pytest
@pytest.fixture(scope="session")
def server():
server = ...
with server.run_in_thread():
yield
Run Code Online (Sandbox Code Playgroud)
根据Uvicorn文档,没有以编程方式停止服务器的方法。相反,您只能通过按ctrl + c (官方)来停止服务器。
但我有一个技巧可以使用多处理标准库和这三个简单的函数以编程方式解决这个问题:
from multiprocessing import Process
import uvicorn
# global process variable
proc = None
def run():
"""
This function to run configured uvicorn server.
"""
uvicorn.run(app=app, host=host, port=port)
def start():
"""
This function to start a new process (start the server).
"""
global proc
# create process instance and set the target to run function.
# use daemon mode to stop the process whenever the program stopped.
proc = Process(target=run, args=(), daemon=True)
proc.start()
def stop():
"""
This function to join (stop) the process (stop the server).
"""
global proc
# check if the process is not None
if proc:
# join (stop) the process with a timeout setten to 0.25 seconds.
# using timeout (the optional arg) is too important in order to
# enforce the server to stop.
proc.join(0.25)
Run Code Online (Sandbox Code Playgroud)
有了同样的想法,你可以:
使用示例:
from time import sleep
if __name__ == "__main__":
# to start the server call start function.
start()
# run some codes ....
# to stop the server call stop function.
stop()
Run Code Online (Sandbox Code Playgroud)
您可以阅读更多有关:
| 归档时间: |
|
| 查看次数: |
8254 次 |
| 最近记录: |