Skip to content

Commit f90fd64

Browse files
committed
perf(group): GroupOf.ServeHTTP 中减少不必要的 types.Context 分配
1 parent 4a3b40b commit f90fd64

File tree

4 files changed

+32
-15
lines changed

4 files changed

+32
-15
lines changed

examples/ctx/ctx.go

+16-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ package ctx
66
import (
77
"net/http"
88

9+
"github.com/issue9/mux/v7"
10+
"github.com/issue9/mux/v7/group"
911
"github.com/issue9/mux/v7/types"
1012
)
1113

@@ -16,11 +18,15 @@ type (
1618
P types.Route
1719
}
1820

21+
Router = mux.RouterOf[Handler]
22+
23+
Routers = group.GroupOf[Handler]
24+
1925
Handler interface {
2026
Handle(*CTX)
2127
}
2228

23-
HandlerFunc func(ctx *CTX)
29+
HandlerFunc func(*CTX)
2430
)
2531

2632
func (f HandlerFunc) Handle(c *CTX) { f(c) }
@@ -45,3 +51,12 @@ func methodNotAllowedBuilder(p types.Node) Handler {
4551
func notFound(ctx *CTX) {
4652
ctx.W.WriteHeader(http.StatusNotFound)
4753
}
54+
55+
func NewRouters(o ...mux.Option) *Routers {
56+
return group.NewGroupOf[Handler](call, HandlerFunc(notFound), methodNotAllowedBuilder, optionsHandlerBuilder, o...)
57+
}
58+
59+
// NewRouter 声明适用于官方 http.Handler 接口的路由
60+
func NewRouter(name string, o ...mux.Option) *Router {
61+
return mux.NewRouterOf[Handler](name, call, HandlerFunc(notFound), methodNotAllowedBuilder, optionsHandlerBuilder, o...)
62+
}

group/group.go

+7-5
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,17 @@ func NewGroupOf[T any](call mux.CallOf[T], notFound T, methodNotAllowedBuilder,
5353
}
5454

5555
func (g *GroupOf[T]) ServeHTTP(w http.ResponseWriter, r *http.Request) {
56-
for _, router := range g.routers {
57-
ps := types.NewContext()
58-
defer ps.Destroy()
56+
ctx := types.NewContext()
57+
defer ctx.Destroy()
5958

60-
if ok := router.m.Match(r, ps); ok {
61-
router.r.ServeContext(w, r, ps)
59+
for _, router := range g.routers {
60+
if ok := router.m.Match(r, ctx); ok {
61+
router.r.ServeContext(w, r, ctx)
6262
return
6363
}
64+
ctx.Reset()
6465
}
66+
6567
g.call(w, r, nil, g.notFound)
6668
}
6769

group/match.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ import (
1515
type Matcher interface {
1616
// Match 验证请求是否符合当前对象的要求
1717
//
18-
// ok 表示是否匹配成功
19-
Match(*http.Request, *types.Context) (ok bool)
18+
// 返回值表示是否匹配成功
19+
Match(*http.Request, *types.Context) bool
2020
}
2121

22-
type MatcherFunc func(*http.Request, *types.Context) (ok bool)
22+
type MatcherFunc func(*http.Request, *types.Context) bool
2323

2424
func (f MatcherFunc) Match(r *http.Request, p *types.Context) bool { return f(r, p) }
2525

@@ -29,7 +29,7 @@ func anyRouter(*http.Request, *types.Context) bool { return true }
2929
//
3030
// 前一个对象返回的实例将作为下一个对象的输入参数。
3131
func AndMatcher(m ...Matcher) Matcher {
32-
return MatcherFunc(func(r *http.Request, ctx *types.Context) (ok bool) {
32+
return MatcherFunc(func(r *http.Request, ctx *types.Context) bool {
3333
for _, mm := range m {
3434
if !mm.Match(r, ctx) {
3535
return false

router.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,9 @@ func (r *RouterOf[T]) URL(strict bool, pattern string, params map[string]string)
179179
}
180180

181181
func (r *RouterOf[T]) ServeHTTP(w http.ResponseWriter, req *http.Request) {
182-
p := types.NewContext()
183-
defer p.Destroy()
184-
r.ServeContext(w, req, p)
182+
ctx := types.NewContext()
183+
defer ctx.Destroy()
184+
r.ServeContext(w, req, ctx)
185185
}
186186

187187
func (r *RouterOf[T]) ServeContext(w http.ResponseWriter, req *http.Request, ctx *types.Context) {
@@ -194,11 +194,11 @@ func (r *RouterOf[T]) ServeContext(w http.ResponseWriter, req *http.Request, ctx
194194
}
195195

196196
ctx.Path = req.URL.Path
197-
node, h, exists := r.tree.Handler(ctx, req.Method)
197+
node, h, ok := r.tree.Handler(ctx, req.Method)
198198
ctx.SetNode(node)
199199
ctx.SetRouterName(r.Name())
200200

201-
if exists {
201+
if ok { // !ok 即为 405 或是 404 状态
202202
r.cors.Handle(node, w.Header(), req)
203203
if req.Method == http.MethodHead {
204204
w = &headResponse{ResponseWriter: w}

0 commit comments

Comments
 (0)