Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/kostya/limiter
Rate limiter for Crystal. Memory and Redis based.
https://github.com/kostya/limiter
Last synced: 11 days ago
JSON representation
Rate limiter for Crystal. Memory and Redis based.
- Host: GitHub
- URL: https://github.com/kostya/limiter
- Owner: kostya
- License: mit
- Created: 2016-07-10T18:41:08.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2021-04-10T13:01:24.000Z (over 3 years ago)
- Last Synced: 2024-10-25T01:30:48.538Z (19 days ago)
- Language: Crystal
- Homepage:
- Size: 23.4 KB
- Stars: 35
- Watchers: 4
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# limiter
Rate limiter for Crystal. Memory and Redis based. Redis limiter is shared (unlike Memory limiter which is local for process), so it can be used across multiple processes.
## Installation
Add this to your application's `shard.yml`:
```yaml
dependencies:
limiter:
github: kostya/limiter
```## Basic Limiter Usage
```crystal
require "limiter"
limiter = Limiter::Memory.new
limiter.add_limit(2.seconds, 10) # allow 10 requests per 2.seconds
limiter.add_limit(1.hour, 1000) # allow 1000 requests per 1.hourres = limiter.request? { some_high_cost_action } # => return value of block or nil
res = limiter.request! { some_high_cost_action } # => return value of block or raise Limiter::Error```
## Example Memory Limiter
```crystal
require "limiter"limiter = Limiter::Memory.new
limiter.add_limit(2.seconds, 10) # allow 10 requests per 2.seconds
limiter.add_limit(1.hour, 1000) # allow 1000 requests per 1.hourrecord Result, val : Float64
def some_high_cost_action : Result
# ...
sleep 0.1
# ...
return Result.new(rand)
endres = [] of Result
limited_count = 01000.times do
if val = limiter.request? { some_high_cost_action }
res << val
else
limited_count += 1
end
endp res.size
p limited_count
```## Example Redis Limiter
```crystal
require "redis"
require "limiter"redis_client = Redis::PooledClient.new
limiter = Limiter::Redis(Redis::PooledClient).new(redis_client, "my_limiter1")
limiter.add_limit(2.seconds, 10) # allow 10 requests per 2.seconds
limiter.add_limit(1.hour, 1000) # allow 1000 requests per 1.hourrecord Result, val : Float64
def some_high_cost_action : Result
# ...
sleep 0.1
# ...
return Result.new(rand)
endres = [] of Result
50.times do
if val = limiter.request? { some_high_cost_action }
res << val
else
x = limiter.next_usage_after
puts "processed: #{res.size}, next usage after #{x} seconds"
sleep(x)
end
endputs "processed #{res.size}"
```