limiter icon indicating copy to clipboard operation
limiter copied to clipboard

another dynamic limit need

Open diemus opened this issue 1 year ago • 9 comments

I have multiple resources that are being requested, each with varying capacities. Therefore, I need to implement rate limiting based on the capacity of each individual resource.

diemus avatar Apr 17 '23 03:04 diemus

This can be easily implemented. Example of the Gin framework

// 5-S
middleware1 := mgin.NewMiddleware(limiter.New(store, rate))
// 100-S
middleware2 := mgin.NewMiddleware(limiter.New(store, rate))

router.Use(func(ctx *gin.Context) {
    if(ctx.Request.URL == "/api/v1") {
       middleware1(ctx)
       return
    }
    if(ctx.Request.URL == "/api/v2") {
       middleware2(ctx)
       return
    }
})

myml avatar May 17 '23 09:05 myml

thanks for the example, but what if some user want higher quotas for the same resource? should i generate all possible middleware ?

diemus avatar May 19 '23 04:05 diemus

This depends on the specific business. Below is pseudocode provided as a reference:

var cache sync.Map
router.Use(func(ctx *gin.Context) {
    uid := getUserID(ctx)
    if v,ok := cache.Load(uid); ok {
        h := v.(gin.HandlerFunc)
        h(ctx)
        return
    }
    rate := genRateByUserID(uid)
    h = mgin.NewMiddleware(limiter.New(store, rate))
    cache.Store(uid, h)
    h(ctx)
})

Please pay attention to the store used by the limiter. If you are using Redis for storage, you will need to use different prefixes. However, if you are using in-memory storage, you should not encounter any issues.

myml avatar May 19 '23 05:05 myml

Thank you for this very nice library. I was wondering, performance wise, how scalable is this approach? For let's say 10k users. My current understanding is that my program would need to store all the middleware in memory.

quentinlesceller avatar May 29 '23 19:05 quentinlesceller

Regarding the performance and scalability of this approach, I haven't personally tested it. However, using Redis as a middleware storage can be a viable option for achieving scalability.

myml avatar May 30 '23 14:05 myml

Thank you @myml for answering these questions.

novln avatar May 30 '23 15:05 novln

Thank you for your answer. Indeed that could be interesting. Gonna try with the local approach one and then see how well it scales.

quentinlesceller avatar May 30 '23 15:05 quentinlesceller

@myml Thank you for your answer, I guess probably using lower level code is more elegant, I checked the store interface. it's looks more flexibile to do something like dynamic rate limit. I can just pass in different users id as keys and set different rate.

diemus avatar Jun 09 '23 11:06 diemus

@myml In the above way, I will still find that the request for interface /api/v1 may be calculated on interface /api/v2

ibarryyan avatar Aug 30 '23 12:08 ibarryyan