首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用自定义中间件时ASGI寿命的问题

使用自定义中间件时ASGI寿命的问题
EN

Stack Overflow用户
提问于 2022-08-06 08:31:43
回答 1查看 354关注 0票数 1

我遇到了一种有趣的行为。对于应用程序,我编写了一个处理客户端的自定义中间件,它不等待响应并断开连接。

代码语言:javascript
运行
复制
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部署中使用,它的行为会很奇怪,然后在吊舱内完全“死亡”(进入永久重新启动),我就会得到一个错误。

代码语言:javascript
运行
复制
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

修复它:

代码语言:javascript
运行
复制
    async def __call__(self, scope, receive, send) -> None:
        if scope["type"] in ["http", "websocket"]:
            request = Request(scope, receive, send)
            ...
        return
EN

回答 1

Stack Overflow用户

发布于 2022-08-11 06:33:00

如果要继承__call__,则不应该实现BaseHTTPMiddleware方法。在使用它时,您应该只实现dispatch方法,如文档:https://www.starlette.io/middleware/#basehttpmiddleware中提到的那样。

阿斯吉在街区工作。每个中间件(或应用程序)都调用下一个中间件(或应用程序),这些中间件的类型要么是"websocket",要么是"http“或”生存期“。

如果您创建的中间件是为"http“创建的,那么您应该会回到下一个中间件,请参见:

代码语言:javascript
运行
复制
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上阅读它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73258319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档