云计算百科
云计算领域专业知识百科平台

第四章 FastMCP 服务器框架之生命周期钩子

目录

  • 生命周期钩子机制概述
  • lifespan参数配置
  • 数据库连接示例分析
  • lifespan_wrapper机制解析
  • lifespan_context访问方式
  • 自定义生命周期钩子模板
  • 应用场景
  • 生命周期钩子机制概述

    FastMCP服务器的生命周期钩子机制允许开发者在服务器启动和关闭时执行自定义的资源管理操作。该机制通过lifespan参数配置一个异步上下文管理器,实现服务器生命周期的精细化控制。生命周期钩子主要用于管理需要在服务器启动时初始化、在关闭时清理的资源,如数据库连接池、缓存客户端和外部服务连接等。

    本节来源

    • server.py

    lifespan参数配置

    lifespan参数接受一个可调用对象,该对象返回一个异步上下文管理器。在Server类的初始化方法中,lifespan参数被直接赋值给实例属性,用于管理服务器的生命周期。对于FastMCP类,lifespan参数通过lifespan_wrapper函数进行包装,以适配底层服务器的生命周期管理机制。

    #mermaid-svg-pamXGzapMzRYZthl {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-pamXGzapMzRYZthl .error-icon{fill:#552222;}#mermaid-svg-pamXGzapMzRYZthl .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-pamXGzapMzRYZthl .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-pamXGzapMzRYZthl .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-pamXGzapMzRYZthl .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-pamXGzapMzRYZthl .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-pamXGzapMzRYZthl .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-pamXGzapMzRYZthl .marker{fill:#333333;stroke:#333333;}#mermaid-svg-pamXGzapMzRYZthl .marker.cross{stroke:#333333;}#mermaid-svg-pamXGzapMzRYZthl svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-pamXGzapMzRYZthl .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-pamXGzapMzRYZthl .cluster-label text{fill:#333;}#mermaid-svg-pamXGzapMzRYZthl .cluster-label span{color:#333;}#mermaid-svg-pamXGzapMzRYZthl .label text,#mermaid-svg-pamXGzapMzRYZthl span{fill:#333;color:#333;}#mermaid-svg-pamXGzapMzRYZthl .node rect,#mermaid-svg-pamXGzapMzRYZthl .node circle,#mermaid-svg-pamXGzapMzRYZthl .node ellipse,#mermaid-svg-pamXGzapMzRYZthl .node polygon,#mermaid-svg-pamXGzapMzRYZthl .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-pamXGzapMzRYZthl .node .label{text-align:center;}#mermaid-svg-pamXGzapMzRYZthl .node.clickable{cursor:pointer;}#mermaid-svg-pamXGzapMzRYZthl .arrowheadPath{fill:#333333;}#mermaid-svg-pamXGzapMzRYZthl .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-pamXGzapMzRYZthl .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-pamXGzapMzRYZthl .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-pamXGzapMzRYZthl .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-pamXGzapMzRYZthl .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-pamXGzapMzRYZthl .cluster text{fill:#333;}#mermaid-svg-pamXGzapMzRYZthl .cluster span{color:#333;}#mermaid-svg-pamXGzapMzRYZthl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-pamXGzapMzRYZthl :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    配置lifespan参数

    定义异步上下文管理器

    实现启动时初始化逻辑

    实现关闭时清理逻辑

    通过yield返回上下文

    将lifespan传递给服务器

    服务器初始化

    图源

    • server.py
    • server.py

    本节来源

    • server.py
    • server.py

    数据库连接示例分析

    在examples/snippets/servers/lowlevel/lifespan.py示例中,展示了如何使用生命周期钩子管理数据库连接。示例定义了一个Database类,包含connect和disconnect方法分别用于建立和断开数据库连接。server_lifespan函数作为生命周期管理器,在try块中初始化数据库连接,并通过yield语句将包含数据库实例的字典传递给服务器上下文。

    #mermaid-svg-HlywSi6HaYDg8a85 {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-HlywSi6HaYDg8a85 .error-icon{fill:#552222;}#mermaid-svg-HlywSi6HaYDg8a85 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HlywSi6HaYDg8a85 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-HlywSi6HaYDg8a85 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HlywSi6HaYDg8a85 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HlywSi6HaYDg8a85 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HlywSi6HaYDg8a85 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HlywSi6HaYDg8a85 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HlywSi6HaYDg8a85 .marker.cross{stroke:#333333;}#mermaid-svg-HlywSi6HaYDg8a85 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HlywSi6HaYDg8a85 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-HlywSi6HaYDg8a85 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-HlywSi6HaYDg8a85 .actor-line{stroke:grey;}#mermaid-svg-HlywSi6HaYDg8a85 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-HlywSi6HaYDg8a85 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-HlywSi6HaYDg8a85 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-HlywSi6HaYDg8a85 .sequenceNumber{fill:white;}#mermaid-svg-HlywSi6HaYDg8a85 #sequencenumber{fill:#333;}#mermaid-svg-HlywSi6HaYDg8a85 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-HlywSi6HaYDg8a85 .messageText{fill:#333;stroke:#333;}#mermaid-svg-HlywSi6HaYDg8a85 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-HlywSi6HaYDg8a85 .labelText,#mermaid-svg-HlywSi6HaYDg8a85 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-HlywSi6HaYDg8a85 .loopText,#mermaid-svg-HlywSi6HaYDg8a85 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-HlywSi6HaYDg8a85 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-HlywSi6HaYDg8a85 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-HlywSi6HaYDg8a85 .noteText,#mermaid-svg-HlywSi6HaYDg8a85 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-HlywSi6HaYDg8a85 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-HlywSi6HaYDg8a85 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-HlywSi6HaYDg8a85 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-HlywSi6HaYDg8a85 .actorPopupMenu{position:absolute;}#mermaid-svg-HlywSi6HaYDg8a85 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-HlywSi6HaYDg8a85 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-HlywSi6HaYDg8a85 .actor-man circle,#mermaid-svg-HlywSi6HaYDg8a85 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-HlywSi6HaYDg8a85 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    FastMCP服务器

    生命周期管理器

    数据库

    启动服务器

    await Database.connect()

    返回数据库实例

    yield {"db" : db}

    处理请求

    关闭服务器

    await db.disconnect()

    断开连接

    清理完成

    FastMCP服务器

    生命周期管理器

    数据库

    图源

    • lifespan.py

    本节来源

    • lifespan.py

    lifespan_wrapper机制解析

    lifespan_wrapper函数负责将FastMCP实例传递给生命周期管理器。该函数接受FastMCP实例和生命周期函数作为参数,返回一个适配底层MCPServer的生命周期管理器。包装函数内部通过async with lifespan(app) as context调用原始的生命周期函数,并将FastMCP实例作为参数传递,实现了框架与生命周期管理器之间的集成。

    #mermaid-svg-4RoDWfg0DQY6S41y {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-4RoDWfg0DQY6S41y .error-icon{fill:#552222;}#mermaid-svg-4RoDWfg0DQY6S41y .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4RoDWfg0DQY6S41y .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-4RoDWfg0DQY6S41y .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4RoDWfg0DQY6S41y .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4RoDWfg0DQY6S41y .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4RoDWfg0DQY6S41y .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4RoDWfg0DQY6S41y .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4RoDWfg0DQY6S41y .marker.cross{stroke:#333333;}#mermaid-svg-4RoDWfg0DQY6S41y svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4RoDWfg0DQY6S41y g.classGroup text{fill:#9370DB;fill:#131300;stroke:none;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:10px;}#mermaid-svg-4RoDWfg0DQY6S41y g.classGroup text .title{font-weight:bolder;}#mermaid-svg-4RoDWfg0DQY6S41y .nodeLabel,#mermaid-svg-4RoDWfg0DQY6S41y .edgeLabel{color:#131300;}#mermaid-svg-4RoDWfg0DQY6S41y .edgeLabel .label rect{fill:#ECECFF;}#mermaid-svg-4RoDWfg0DQY6S41y .label text{fill:#131300;}#mermaid-svg-4RoDWfg0DQY6S41y .edgeLabel .label span{background:#ECECFF;}#mermaid-svg-4RoDWfg0DQY6S41y .classTitle{font-weight:bolder;}#mermaid-svg-4RoDWfg0DQY6S41y .node rect,#mermaid-svg-4RoDWfg0DQY6S41y .node circle,#mermaid-svg-4RoDWfg0DQY6S41y .node ellipse,#mermaid-svg-4RoDWfg0DQY6S41y .node polygon,#mermaid-svg-4RoDWfg0DQY6S41y .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4RoDWfg0DQY6S41y .divider{stroke:#9370DB;stroke:1;}#mermaid-svg-4RoDWfg0DQY6S41y g.clickable{cursor:pointer;}#mermaid-svg-4RoDWfg0DQY6S41y g.classGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-4RoDWfg0DQY6S41y g.classGroup line{stroke:#9370DB;stroke-width:1;}#mermaid-svg-4RoDWfg0DQY6S41y .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-4RoDWfg0DQY6S41y .classLabel .label{fill:#9370DB;font-size:10px;}#mermaid-svg-4RoDWfg0DQY6S41y .relation{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-4RoDWfg0DQY6S41y .dashed-line{stroke-dasharray:3;}#mermaid-svg-4RoDWfg0DQY6S41y #compositionStart,#mermaid-svg-4RoDWfg0DQY6S41y .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4RoDWfg0DQY6S41y #compositionEnd,#mermaid-svg-4RoDWfg0DQY6S41y .composition{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4RoDWfg0DQY6S41y #dependencyStart,#mermaid-svg-4RoDWfg0DQY6S41y .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4RoDWfg0DQY6S41y #dependencyStart,#mermaid-svg-4RoDWfg0DQY6S41y .dependency{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4RoDWfg0DQY6S41y #extensionStart,#mermaid-svg-4RoDWfg0DQY6S41y .extension{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4RoDWfg0DQY6S41y #extensionEnd,#mermaid-svg-4RoDWfg0DQY6S41y .extension{fill:#333333!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4RoDWfg0DQY6S41y #aggregationStart,#mermaid-svg-4RoDWfg0DQY6S41y .aggregation{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4RoDWfg0DQY6S41y #aggregationEnd,#mermaid-svg-4RoDWfg0DQY6S41y .aggregation{fill:#ECECFF!important;stroke:#333333!important;stroke-width:1;}#mermaid-svg-4RoDWfg0DQY6S41y .edgeTerminals{font-size:11px;}#mermaid-svg-4RoDWfg0DQY6S41y :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    使用

    适配

    包含

    FastMCP

    +name : str

    +instructions : str

    +lifespan : Callable

    +_mcp_server : MCPServer

    lifespan_wrapper

    +app : FastMCP

    +lifespan : Callable

    +wrap(_ : MCPServer)

    MCPServer

    +lifespan : Callable

    +request_context : RequestContext

    图源

    • server.py

    本节来源

    • server.py

    lifespan_context访问方式

    在请求处理过程中,可以通过server.request_context访问生命周期上下文。RequestContext类包含一个泛型字段lifespan_context,用于存储生命周期管理器通过yield语句返回的上下文数据。在工具函数中,可以使用ctx = server.request_context获取请求上下文,然后通过ctx.lifespan_context["db"]访问数据库连接等资源。

    #mermaid-svg-zyxWvyo2vWMUgEul {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-zyxWvyo2vWMUgEul .error-icon{fill:#552222;}#mermaid-svg-zyxWvyo2vWMUgEul .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zyxWvyo2vWMUgEul .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-zyxWvyo2vWMUgEul .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zyxWvyo2vWMUgEul .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zyxWvyo2vWMUgEul .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zyxWvyo2vWMUgEul .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zyxWvyo2vWMUgEul .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zyxWvyo2vWMUgEul .marker.cross{stroke:#333333;}#mermaid-svg-zyxWvyo2vWMUgEul svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zyxWvyo2vWMUgEul .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-zyxWvyo2vWMUgEul .cluster-label text{fill:#333;}#mermaid-svg-zyxWvyo2vWMUgEul .cluster-label span{color:#333;}#mermaid-svg-zyxWvyo2vWMUgEul .label text,#mermaid-svg-zyxWvyo2vWMUgEul span{fill:#333;color:#333;}#mermaid-svg-zyxWvyo2vWMUgEul .node rect,#mermaid-svg-zyxWvyo2vWMUgEul .node circle,#mermaid-svg-zyxWvyo2vWMUgEul .node ellipse,#mermaid-svg-zyxWvyo2vWMUgEul .node polygon,#mermaid-svg-zyxWvyo2vWMUgEul .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zyxWvyo2vWMUgEul .node .label{text-align:center;}#mermaid-svg-zyxWvyo2vWMUgEul .node.clickable{cursor:pointer;}#mermaid-svg-zyxWvyo2vWMUgEul .arrowheadPath{fill:#333333;}#mermaid-svg-zyxWvyo2vWMUgEul .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-zyxWvyo2vWMUgEul .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-zyxWvyo2vWMUgEul .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-zyxWvyo2vWMUgEul .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-zyxWvyo2vWMUgEul .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-zyxWvyo2vWMUgEul .cluster text{fill:#333;}#mermaid-svg-zyxWvyo2vWMUgEul .cluster span{color:#333;}#mermaid-svg-zyxWvyo2vWMUgEul div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-zyxWvyo2vWMUgEul :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    收到请求

    获取请求上下文ctx = server.request_context

    访问生命周期上下文db = ctx.lifespan_context['db']

    使用资源执行操作

    返回结果

    图源

    • context.py
    • lifespan.py

    本节来源

    • context.py
    • lifespan.py

    自定义生命周期钩子模板

    以下为配置自定义生命周期钩子的代码模板:

    #mermaid-svg-LpSY1mJgMYGi2ZjT {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-LpSY1mJgMYGi2ZjT .error-icon{fill:#552222;}#mermaid-svg-LpSY1mJgMYGi2ZjT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LpSY1mJgMYGi2ZjT .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-LpSY1mJgMYGi2ZjT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LpSY1mJgMYGi2ZjT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LpSY1mJgMYGi2ZjT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LpSY1mJgMYGi2ZjT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LpSY1mJgMYGi2ZjT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LpSY1mJgMYGi2ZjT .marker.cross{stroke:#333333;}#mermaid-svg-LpSY1mJgMYGi2ZjT svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LpSY1mJgMYGi2ZjT .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-LpSY1mJgMYGi2ZjT .cluster-label text{fill:#333;}#mermaid-svg-LpSY1mJgMYGi2ZjT .cluster-label span{color:#333;}#mermaid-svg-LpSY1mJgMYGi2ZjT .label text,#mermaid-svg-LpSY1mJgMYGi2ZjT span{fill:#333;color:#333;}#mermaid-svg-LpSY1mJgMYGi2ZjT .node rect,#mermaid-svg-LpSY1mJgMYGi2ZjT .node circle,#mermaid-svg-LpSY1mJgMYGi2ZjT .node ellipse,#mermaid-svg-LpSY1mJgMYGi2ZjT .node polygon,#mermaid-svg-LpSY1mJgMYGi2ZjT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LpSY1mJgMYGi2ZjT .node .label{text-align:center;}#mermaid-svg-LpSY1mJgMYGi2ZjT .node.clickable{cursor:pointer;}#mermaid-svg-LpSY1mJgMYGi2ZjT .arrowheadPath{fill:#333333;}#mermaid-svg-LpSY1mJgMYGi2ZjT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-LpSY1mJgMYGi2ZjT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-LpSY1mJgMYGi2ZjT .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-LpSY1mJgMYGi2ZjT .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-LpSY1mJgMYGi2ZjT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LpSY1mJgMYGi2ZjT .cluster text{fill:#333;}#mermaid-svg-LpSY1mJgMYGi2ZjT .cluster span{color:#333;}#mermaid-svg-LpSY1mJgMYGi2ZjT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-LpSY1mJgMYGi2ZjT :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    定义异步上下文管理器@asynccontextmanagerasync def custom_lifespan(…)

    在try块中执行启动逻辑

    初始化数据库连接

    初始化缓存客户端

    初始化外部服务连接

    yield 返回上下文字典

    在finally块中执行清理逻辑

    关闭数据库连接

    关闭缓存连接

    关闭外部服务连接

    End

    图源

    • lifespan_example.py

    本节来源

    • lifespan_example.py

    应用场景

    生命周期钩子机制适用于多种资源管理场景:

    • 数据库连接池管理:在服务器启动时创建连接池,关闭时优雅地释放所有连接
    • 缓存客户端管理:初始化Redis或Memcached客户端连接
    • 外部服务连接:建立与第三方API、消息队列等外部服务的持久连接
    • 文件句柄管理:打开日志文件或其他需要长期持有的文件句柄
    • 定时任务管理:启动后台定时任务或工作线程

    这些场景都需要确保资源在服务器生命周期内正确初始化和清理,避免资源泄漏和连接中断问题。

    本节来源

    • lifespan.py
    • lifespan_example.py
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 第四章 FastMCP 服务器框架之生命周期钩子
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!