Your Question
我想要通过注册中间件的方式实现对Gorm的限流器,但是我尝试了,实现Plugin接口并不能操作本次查询链路终止。
The document you expected this should be explained
// GormRateLimiter Gorm限流器
func GormRateLimiter(db *gorm.DB, r *rate.Limiter) {
err := db.Callback().Query().Before("*").Register("RateLimitGormMiddleware", func(d *gorm.DB) {
if !r.Allow() {
d.AddError(GormToManyRequestError)
global.Log.Error(GormToManyRequestError.Error())
return
}
})
if err != nil {
panic(err)
}
}
Expected answer
// 定义限流中间件结构体
type gormRateLimiter struct {
limiter *rate.Limiter
}
func newGormLimiter(limiter *rate.Limiter) *gormRateLimiter {
return &gormRateLimiter{limiter: limiter}
}
func (r *gormRateLimiter) Name() string {
return "RateLimitMiddleware"
}
func (r *gormRateLimiter) Initialize(db *gorm.DB) (err error) {
err = db.Callback().Query().Before("*").Register("RateLimitGormMiddleware", func(d *gorm.DB) {
if !r.limiter.Allow() {
d.AddError(GormToManyRequestError)
global.Log.Error(GormToManyRequestError.Error())
return
}
})
return err
}
是不是应该把这种AOP方案做的更加完善和对开发者更友好一些呢?
Comment From: jinzhu
返回一下 Error 就好了,其它的Callback会判断有 error 不执行,不应该真正的 abort 防止事务未commit/rollback 等