Skip to content

Commit

Permalink
feat: add HandlerNameOperator interface
Browse files Browse the repository at this point in the history
  • Loading branch information
li-jin-gou committed Jan 9, 2024
1 parent 4ae92ca commit 61b0f21
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 9 deletions.
58 changes: 50 additions & 8 deletions pkg/app/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,8 @@ func (ctx *RequestContext) GetIndex() int8 {
return ctx.index
}

// SetIndex reset the handler's execution index
// Disclaimer: You can loop yourself to deal with this, use wisely.
func (ctx *RequestContext) SetIndex(index int8) {
ctx.index = index
}
Expand All @@ -337,20 +339,60 @@ type HandlerFunc func(c context.Context, ctx *RequestContext)
// HandlersChain defines a HandlerFunc array.
type HandlersChain []HandlerFunc

var handlerNames = make(map[uintptr]string)
type HandlerNameOperator interface {
SetHandlerName(handler HandlerFunc, name string)
GetHandlerName(handler HandlerFunc) string
}

func SetHandlerNameOperator(o HandlerNameOperator) {
inbuiltHandlerNameOperator = o
}

type inbuiltHandlerNameOperatorStruct struct {
handlerNames map[uintptr]string
}

func (o *inbuiltHandlerNameOperatorStruct) SetHandlerName(handler HandlerFunc, name string) {
o.handlerNames[getFuncAddr(handler)] = name
}

func (o *inbuiltHandlerNameOperatorStruct) GetHandlerName(handler HandlerFunc) string {
return o.handlerNames[getFuncAddr(handler)]
}

type concurrentHandlerNameOperatorStruct struct {
handlerNames map[uintptr]string
lock sync.RWMutex
}

func (o *concurrentHandlerNameOperatorStruct) SetHandlerName(handler HandlerFunc, name string) {
o.lock.Lock()
defer o.lock.Unlock()
o.handlerNames[getFuncAddr(handler)] = name
}

func (o *concurrentHandlerNameOperatorStruct) GetHandlerName(handler HandlerFunc) string {
o.lock.RLock()
defer o.lock.RUnlock()
return o.handlerNames[getFuncAddr(handler)]
}

func SetConcurrentHandlerNameOperator() {
SetHandlerNameOperator(&concurrentHandlerNameOperatorStruct{handlerNames: map[uintptr]string{}})
}

func init() {
inbuiltHandlerNameOperator = &inbuiltHandlerNameOperatorStruct{handlerNames: map[uintptr]string{}}
}

var handlerRWLock sync.RWMutex
var inbuiltHandlerNameOperator HandlerNameOperator

func SetHandlerName(handler HandlerFunc, name string) {
handlerRWLock.Lock()
defer handlerRWLock.Unlock()
handlerNames[getFuncAddr(handler)] = name
inbuiltHandlerNameOperator.SetHandlerName(handler, name)
}

func GetHandlerName(handler HandlerFunc) string {
handlerRWLock.RLock()
defer handlerRWLock.RUnlock()
return handlerNames[getFuncAddr(handler)]
return inbuiltHandlerNameOperator.GetHandlerName(handler)
}

func getFuncAddr(v interface{}) uintptr {
Expand Down
31 changes: 30 additions & 1 deletion pkg/app/context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 +1353,9 @@ func TestIndex(t *testing.T) {
assert.DeepEqual(t, exc, res)
}

func TestHandlerName(t *testing.T) {
func TestConcurrentHandlerName(t *testing.T) {
SetConcurrentHandlerNameOperator()
defer SetHandlerNameOperator(&inbuiltHandlerNameOperatorStruct{handlerNames: map[uintptr]string{}})
h := func(c context.Context, ctx *RequestContext) {}
SetHandlerName(h, "test1")
for i := 0; i < 50; i++ {
Expand All @@ -1375,6 +1377,13 @@ func TestHandlerName(t *testing.T) {
assert.DeepEqual(t, "test2", name)
}

func TestHandlerName(t *testing.T) {
h := func(c context.Context, ctx *RequestContext) {}
SetHandlerName(h, "test1")
name := GetHandlerName(h)
assert.DeepEqual(t, "test1", name)
}

func TestHijack(t *testing.T) {
ctx := NewContext(0)
h := func(c network.Conn) {}
Expand Down Expand Up @@ -1663,3 +1672,23 @@ func TestRequestContext_VisitAll(t *testing.T) {
})
})
}

func BenchmarkInbuiltHandlerNameOperator(b *testing.B) {
for n := 0; n < b.N; n++ {
fn := func(c context.Context, ctx *RequestContext) {
}
SetHandlerName(fn, fmt.Sprintf("%d", n))
GetHandlerName(fn)
}
}

func BenchmarkConcurrentHandlerNameOperator(b *testing.B) {
SetConcurrentHandlerNameOperator()
defer SetHandlerNameOperator(&inbuiltHandlerNameOperatorStruct{handlerNames: map[uintptr]string{}})
for n := 0; n < b.N; n++ {
fn := func(c context.Context, ctx *RequestContext) {
}
SetHandlerName(fn, fmt.Sprintf("%d", n))
GetHandlerName(fn)
}
}

0 comments on commit 61b0f21

Please sign in to comment.