中间件实现

实现一个并发安全、高性能的中间件,可以使用 sync.Pool 来避免频繁的内存分配和垃圾回收,以提高性能。

基于 sync.Pool 实现的 Context

type Context struct {
    Req        *http.Request
    Resp       http.ResponseWriter
    PathParams map[string]string
    data       map[string]interface{}
    pool       *sync.Pool
}

func (ctx *Context) SetData(key string, value interface{}) {
    ctx.data[key] = value
}

func (ctx *Context) GetData(key string) (interface{}, bool) {
    val, ok := ctx.data[key]
    return val, ok
}

func (ctx *Context) reset(req *http.Request, resp http.ResponseWriter, pathParams map[string]string) {
    ctx.Req = req
    ctx.Resp = resp
    ctx.PathParams = pathParams
    ctx.data = make(map[string]interface{})
}

func (ctx *Context) Release() {
    ctx.pool.Put(ctx)
}

func AcquireContext(pool *sync.Pool, req *http.Request, resp http.ResponseWriter, pathParams map[string]string) *Context {
    c := pool.Get().(*Context)
    c.reset(req, resp, pathParams)
    c.pool = pool
    return c
}

调用方式如下:

func handlerFunc(ctx *Context) {
    // 处理逻辑
    ctx.Resp.Write([]byte("Hello, World!"))
    // 释放上下文对象,以便复用
    ctx.Release()
}

func middleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
        // 从 sync.Pool 中获取上下文对象
        ctx := AcquireContext(ctxPool, req, resp, nil)
        // 在上下文对象中添加需要传递给 handler 的数据
        ctx.SetData("key", "value")
        // 调用下一个处理器
        next.ServeHTTP(resp, req)
    })
}

func main() {
    // 创建一个 sync.Pool
    ctxPool := &sync.Pool{
        New: func() interface{} {
            return &Context{}
        },
    }
    defer func() {
        // 当应用程序退出时,清除 sync.Pool 中的对象
        for i := 0; i < 10; i++ {
            ctx := ctxPool.Get().(*Context)
            ctx.Reset(nil, nil, nil)
            ctx.pool = nil
            ctxPool.Put(ctx)
        }
    }()

    // 创建路由器
    r := NewRouter()

    // 添加中间件
    r.Use(middleware)

    // 添加路由
    r.GET("/", handlerFunc)

    // 启动 HTTP 服务器
    http.ListenAndServe(":8080", r)
}

在 middleware 函数中,从 sync.Pool 中获取一个 Context 对象,并在上下文对象中添加需要传递给 handler 的数据。调用 next.ServeHTTP 方法执行下一个处理器。在 handlerFunc 函数中,从上下文对象中获取需要的数据并进行处理。处理完成后,调用 ctx.Release() 方法释放上下文对象,以便复用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值