mirror of
https://github.com/fumiama/ReiBot.git
synced 2026-06-05 00:50:25 +08:00
add more
This commit is contained in:
61
single.go
Normal file
61
single.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package rei
|
||||
|
||||
import (
|
||||
"github.com/RomiChan/syncx"
|
||||
)
|
||||
|
||||
// Option 配置项
|
||||
type Option[K comparable] func(*Single[K])
|
||||
|
||||
// Single 反并发
|
||||
type Single[K comparable] struct {
|
||||
group syncx.Map[K, struct{}]
|
||||
key func(ctx *Ctx) K
|
||||
post func(ctx *Ctx)
|
||||
}
|
||||
|
||||
// WithKeyFn 指定反并发的 Key
|
||||
func WithKeyFn[K comparable](fn func(ctx *Ctx) K) Option[K] {
|
||||
return func(s *Single[K]) {
|
||||
s.key = fn
|
||||
}
|
||||
}
|
||||
|
||||
// WithPostFn 指定反并发拦截后的操作
|
||||
func WithPostFn[K comparable](fn func(ctx *Ctx)) Option[K] {
|
||||
return func(s *Single[K]) {
|
||||
s.post = fn
|
||||
}
|
||||
}
|
||||
|
||||
// New 创建反并发中间件
|
||||
func New[K comparable](op ...Option[K]) *Single[K] {
|
||||
s := Single[K]{}
|
||||
for _, option := range op {
|
||||
option(&s)
|
||||
}
|
||||
return &s
|
||||
}
|
||||
|
||||
// Apply 为指定 Engine 添加反并发功能
|
||||
func (s *Single[K]) Apply(engine *Engine) {
|
||||
engine.UseMidHandler(func(ctx *Ctx) bool {
|
||||
if s.key == nil {
|
||||
return true
|
||||
}
|
||||
key := s.key(ctx)
|
||||
if _, ok := s.group.Load(key); ok {
|
||||
if s.post != nil {
|
||||
defer s.post(ctx)
|
||||
}
|
||||
return false
|
||||
}
|
||||
s.group.Store(key, struct{}{})
|
||||
ctx.State["__single-key__"] = key
|
||||
return true
|
||||
})
|
||||
|
||||
engine.UsePostHandler(func(ctx *Ctx) {
|
||||
s.group.Delete(ctx.State["__single-key__"].(K))
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user