From bea0f7d6012c475a4e4d83a3e6419acf293c2fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=8D=9A=E4=BF=AE?= Date: Fri, 26 Mar 2021 21:54:15 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=8E=A8=20pooling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/middleware/auth.go | 23 +++++++++++++++++++++-- server/middleware/pool/pool.go | 25 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 server/middleware/pool/pool.go diff --git a/server/middleware/auth.go b/server/middleware/auth.go index 632dd506..ab827cd6 100644 --- a/server/middleware/auth.go +++ b/server/middleware/auth.go @@ -7,11 +7,13 @@ import ( "os" "path" "strconv" + "strings" "sync" "time" "github.com/Monkey-Mouse/mo2/mo2utils/mo2errors" "github.com/Monkey-Mouse/mo2/server/controller/badresponse" + "github.com/Monkey-Mouse/mo2/server/middleware/pool" "github.com/gin-gonic/gin" "github.com/go-redis/redis" @@ -31,6 +33,13 @@ var rdb *redis.Client var dicChan chan *concurrent.Map = make(chan *concurrent.Map) var lock = sync.Mutex{} var errAuth = errors.New("authentication failed") +var strpool *pool.Pool = &pool.Pool{} + +func init() { + strpool.Init(func() interface{} { + return strings.Builder{} + }) +} // H handlermap, like gin router var H = handlerMap{handlers, "", make([][]string, 0), -1} @@ -104,11 +113,16 @@ func resetBlocker() { } func redisCheckRL(prop string, ip string, limit int) bool { + sb := strpool.Rent().(strings.Builder) + sb.Reset() + sb.WriteString(prop) + sb.WriteString(ip) + defer strpool.Return(sb) // rate limit logic if limit < 0 { return true } - key := prop + ip + key := sb.String() re, err := rdb.HIncrBy(redisHashSet, key, 1).Result() if err != nil { log.Fatal(err) @@ -121,11 +135,16 @@ func redisCheckRL(prop string, ip string, limit int) bool { } func checkRL(prop string, ip string, limit int) bool { + sb := strpool.Rent().(strings.Builder) + sb.Reset() + sb.WriteString(prop) + sb.WriteString(ip) + defer strpool.Return(sb) // rate limit logic if limit < 0 { return true } - key := prop + ip + key := sb.String() dic := <-dicChan lock.Lock() v, ext := dic.Load(key) diff --git a/server/middleware/pool/pool.go b/server/middleware/pool/pool.go new file mode 100644 index 00000000..af5cd818 --- /dev/null +++ b/server/middleware/pool/pool.go @@ -0,0 +1,25 @@ +package pool + +import "container/list" + +type Pool struct { + pool list.List + fac ObjFactory +} + +type ObjFactory func() interface{} + +func (p *Pool) Rent() interface{} { + if p.pool.Len() == 0 { + return p.fac() + } + return p.pool.Remove(p.pool.Back()) +} + +func (p *Pool) Return(e interface{}) { + p.pool.PushBack(e) +} +func (p *Pool) Init(fac ObjFactory) { + p.pool.Init() + p.fac = fac +} From e1022ef63be404818019e721d48ecb0c5e60645c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=8D=9A=E4=BF=AE?= Date: Fri, 26 Mar 2021 22:09:10 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=90=9B=20fix=20concurrency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/middleware/pool/pool.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/server/middleware/pool/pool.go b/server/middleware/pool/pool.go index af5cd818..6ef130be 100644 --- a/server/middleware/pool/pool.go +++ b/server/middleware/pool/pool.go @@ -1,6 +1,9 @@ package pool -import "container/list" +import ( + "container/list" + "sync" +) type Pool struct { pool list.List @@ -9,7 +12,11 @@ type Pool struct { type ObjFactory func() interface{} +var lock = sync.Mutex{} + func (p *Pool) Rent() interface{} { + lock.Lock() + defer lock.Unlock() if p.pool.Len() == 0 { return p.fac() } @@ -17,6 +24,8 @@ func (p *Pool) Rent() interface{} { } func (p *Pool) Return(e interface{}) { + lock.Lock() + defer lock.Unlock() p.pool.PushBack(e) } func (p *Pool) Init(fac ObjFactory) { From d5e75722f9978d17f19d7dacd7a723eb7bff8ca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=8D=9A=E4=BF=AE?= Date: Fri, 26 Mar 2021 22:41:32 +0800 Subject: [PATCH 3/4] remove pool --- server/middleware/auth.go | 12 ++++++++---- server/middleware/pool/pool.go | 3 +++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/server/middleware/auth.go b/server/middleware/auth.go index ab827cd6..f9fe98f8 100644 --- a/server/middleware/auth.go +++ b/server/middleware/auth.go @@ -113,11 +113,15 @@ func resetBlocker() { } func redisCheckRL(prop string, ip string, limit int) bool { - sb := strpool.Rent().(strings.Builder) + // sb := strpool.Rent().(strings.Builder) + // sb.Reset() + // sb.WriteString(prop) + // sb.WriteString(ip) + // defer strpool.Return(sb) + sb := strings.Builder{} sb.Reset() sb.WriteString(prop) sb.WriteString(ip) - defer strpool.Return(sb) // rate limit logic if limit < 0 { return true @@ -135,11 +139,11 @@ func redisCheckRL(prop string, ip string, limit int) bool { } func checkRL(prop string, ip string, limit int) bool { - sb := strpool.Rent().(strings.Builder) + sb := strings.Builder{} sb.Reset() sb.WriteString(prop) sb.WriteString(ip) - defer strpool.Return(sb) + // defer strpool.Return(sb) // rate limit logic if limit < 0 { return true diff --git a/server/middleware/pool/pool.go b/server/middleware/pool/pool.go index 6ef130be..715397e2 100644 --- a/server/middleware/pool/pool.go +++ b/server/middleware/pool/pool.go @@ -22,6 +22,9 @@ func (p *Pool) Rent() interface{} { } return p.pool.Remove(p.pool.Back()) } +func (p *Pool) Len() int { + return p.pool.Len() +} func (p *Pool) Return(e interface{}) { lock.Lock() From 1dcc5254786362835fe755f5701cc35747bb4f2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=8D=9A=E4=BF=AE?= Date: Fri, 26 Mar 2021 22:48:19 +0800 Subject: [PATCH 4/4] try fix --- server/middleware/auth.go | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/server/middleware/auth.go b/server/middleware/auth.go index f9fe98f8..76ba00f7 100644 --- a/server/middleware/auth.go +++ b/server/middleware/auth.go @@ -37,7 +37,7 @@ var strpool *pool.Pool = &pool.Pool{} func init() { strpool.Init(func() interface{} { - return strings.Builder{} + return &strings.Builder{} }) } @@ -113,15 +113,11 @@ func resetBlocker() { } func redisCheckRL(prop string, ip string, limit int) bool { - // sb := strpool.Rent().(strings.Builder) - // sb.Reset() - // sb.WriteString(prop) - // sb.WriteString(ip) - // defer strpool.Return(sb) - sb := strings.Builder{} + sb := strpool.Rent().(*strings.Builder) sb.Reset() sb.WriteString(prop) sb.WriteString(ip) + defer strpool.Return(sb) // rate limit logic if limit < 0 { return true @@ -139,11 +135,11 @@ func redisCheckRL(prop string, ip string, limit int) bool { } func checkRL(prop string, ip string, limit int) bool { - sb := strings.Builder{} + sb := strpool.Rent().(*strings.Builder) sb.Reset() sb.WriteString(prop) sb.WriteString(ip) - // defer strpool.Return(sb) + defer strpool.Return(sb) // rate limit logic if limit < 0 { return true @@ -270,7 +266,7 @@ func (h handlerMap) HandlerWithRL( handler gin.HandlerFunc, ratelimit int, roles ...string) { - if roles != nil && len(roles) != 0 { + if len(roles) != 0 { h.roles = append(h.roles, roles) } key := handlerKey{