我有以下FastAPI应用程序:
from fastapi import FastAPI
import socket
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/healthcheck")
def health_check():
result = some_network_operation()
return result
def some_network_operation():
HOST = "192.168.30.12" # This host does not exist so the connection will time out
PORT = 4567
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(10)
s.connect((HOST, PORT))
s.sendall(b"Are you ok?")
data = s.recv(1024)
print(data)
这是一个简单的应用程序,有两个路由:
/
处理程序,即同步的async
/healthcheck
处理程序。对于这个特殊的例子,如果您调用/healthcheck
,它将在10秒后才能完成,因为套接字连接将超时。但是,如果同时调用/
,它将立即返回响应,因为FastAPI的主线程没有被阻塞。这是有意义的,因为根据文档,FastAPI在外部线程池上运行同步处理程序。
我的问题是,如果我们完全有可能通过在health_check
方法中执行一些操作来阻止应用程序(阻塞FastAPI的主线程)。
发布于 2022-12-02 21:34:13
我想我可能对我的问题有一个答案,那就是,在某些奇怪的边缘情况下,同步端点处理程序可以阻止FastAPI。
例如,如果我们将示例中的some_network_operation
调整为以下内容,它将阻塞整个应用程序。
def some_network_operation():
""" No, this is not a network operation, but it illustrates the point """
block = pow (363,100000000000000)
我根据这个问题得出了这个结论:pow function blocking all threads with ThreadPoolExecutor。
看来吉尔是这里的罪魁祸首。
这个问题建议使用多处理模块(它将绕过GIL)。然而,我尝试了这一点,但仍然导致了同样的行为。所以我的根本问题还没有解决。
不管是哪种方式,下面都是为重现问题而编辑的问题中的整个示例:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
@app.get("/healthcheck")
def health_check():
result = some_network_operation()
return result
def some_network_operation():
block = pow(363,100000000000000)
https://stackoverflow.com/questions/74636003
复制相似问题