我遇到了一种有趣的行为。对于应用程序,我编写了一个处理客户端的自定义中间件,它不等待响应并断开连接。
class NoResponseReturnMiddleware(BaseHTTPMiddleware):
_ERROR_MESSAGE: str = "No response returned."
def __init__(self, app: ASGIApp, logger: Logger):
super().__init__(app)
self.logger = logger
async def __call__(self, scope, receive, send) -> None:
request = Request(scope, receive, send)
try:
await super().__call__(scope, receive, send)
except RuntimeError as exc:
if await request.is_disconnected() and str(exc) == self._ERROR_MESSAGE:
self.logger.debug(
"Remote client disconnected",
extra={
"url": request.url,
"method": request.method,
"path": request.url.path,
"query": request.url.query,
},
)
else:
raise exc
async def dispatch(self, request, call_next):
return await call_next(request)
但是,当我启动应用程序时,它会上升,尽管我收到了一条消息:
ASGI的“生命周期”协议似乎不受支持。
在本地,应用程序工作正常,但一旦组装并发送到寄存器,然后在kubernetes部署中使用,它的行为会很奇怪,然后在吊舱内完全“死亡”(进入永久重新启动),我就会得到一个错误。
Warning Unhealthy 5m5s (x3 over 5m25s) kubelet Liveness probe failed: Get "http://11.11.11.11.1:8000/": dial tcp 11.11.11.11.1:8000: connect: connection refused
它会不会有某种联系?我读过这会导致服务器崩溃
Upd:
试试看
uvicorn main:app --reload --lifespan on
你会得到一个错误:
assert scope["type"] in ("http", "websocket") AssertionError
修复它:
async def __call__(self, scope, receive, send) -> None:
if scope["type"] in ["http", "websocket"]:
request = Request(scope, receive, send)
...
return
发布于 2022-08-11 06:33:00
如果要继承__call__
,则不应该实现BaseHTTPMiddleware
方法。在使用它时,您应该只实现dispatch
方法,如文档:https://www.starlette.io/middleware/#basehttpmiddleware中提到的那样。
阿斯吉在街区工作。每个中间件(或应用程序)都调用下一个中间件(或应用程序),这些中间件的类型要么是"websocket",要么是"http“或”生存期“。
如果您创建的中间件是为"http“创建的,那么您应该会回到下一个中间件,请参见:
if scope["type"] != "http":
await self.app(scope, send, receive)
# Your middleware code should be here!
我们更新了Starlette文档,提供了有关ASGI中间件的更多信息。它将部署在下一个Starlette发行版上,但您可以在https://github.com/encode/starlette/blob/master/docs/middleware.md#pure-asgi-middleware上阅读它。
https://stackoverflow.com/questions/73258319
复制相似问题