@@ -2,9 +2,6 @@ defmodule Lightning.WebhookRateLimiter do
22 @ moduledoc false
33 use GenServer
44
5- @ capacity 10
6- @ refill_per_sec 2
7-
85 require Logger
96
107 def child_spec ( opts ) do
@@ -17,25 +14,30 @@ defmodule Lightning.WebhookRateLimiter do
1714
1815 % {
1916 id: id ,
20- start: { __MODULE__ , :start_link , [ name ] } ,
17+ start: { __MODULE__ , :start_link , [ Keyword . put ( opts , : name, name ) ] } ,
2118 shutdown: 10_000 ,
2219 restart: :transient
2320 }
2421 end
2522
26- def start_link ( name ) do
23+ def start_link ( opts ) do
24+ name = Keyword . fetch! ( opts , :name )
25+
2726 with { :error , { :already_started , pid } } <-
28- GenServer . start_link ( __MODULE__ , [ ] , name: via_tuple ( name ) ) do
27+ GenServer . start_link ( __MODULE__ , opts , name: via_tuple ( name ) ) do
2928 Logger . info ( "already started at #{ inspect ( pid ) } , returning :ignore" )
3029 :ignore
3130 end
3231 end
3332
3433 @ impl true
35- def init ( [ ] ) do
34+ def init ( opts ) do
3635 Process . flag ( :trap_exit , true )
3736
38- { :ok , % { table: :ets . new ( :table , [ :set ] ) } }
37+ capacity = Keyword . fetch! ( opts , :capacity )
38+ refill = Keyword . fetch! ( opts , :refill_per_second )
39+
40+ { :ok , % { table: :ets . new ( :table , [ :set ] ) , capacity: capacity , refill: refill } }
3941 end
4042
4143 def check_rate ( bucket , cost \\ 1 , name \\ __MODULE__ ) do
@@ -51,8 +53,8 @@ defmodule Lightning.WebhookRateLimiter do
5153 end
5254
5355 @ impl true
54- def handle_call ( { :check_rate , bucket , cost } , _from , % { table: table } = state ) do
55- { :reply , do_check_rate ( table , bucket , cost ) , state }
56+ def handle_call ( { :check_rate , bucket , cost } , _from , state ) do
57+ { :reply , do_check_rate ( state , bucket , cost ) , state }
5658 end
5759
5860 @ impl true
@@ -72,14 +74,18 @@ defmodule Lightning.WebhookRateLimiter do
7274 { :stop , :normal , state }
7375 end
7476
75- def do_check_rate ( table , bucket , cost ) do
77+ def do_check_rate (
78+ % { table: table , capacity: capacity , refill: refill_per_sec } ,
79+ bucket ,
80+ cost
81+ ) do
7682 now = System . monotonic_time ( :millisecond )
7783
78- :ets . insert_new ( table , { bucket , { @ capacity , now } } )
84+ :ets . insert_new ( table , { bucket , { capacity , now } } )
7985 [ { ^ bucket , { level , updated } } ] = :ets . lookup ( table , bucket )
8086
81- refilled = div ( now - updated , 1_000 ) * @ refill_per_sec
82- current = min ( @ capacity , level + refilled )
87+ refilled = div ( now - updated , 1_000 ) * refill_per_sec
88+ current = min ( capacity , level + refilled )
8389
8490 if current >= cost do
8591 level = current - cost
@@ -92,9 +98,6 @@ defmodule Lightning.WebhookRateLimiter do
9298 end
9399 end
94100
95- def capacity , do: @ capacity
96- def refill_per_second , do: @ refill_per_sec
97-
98101 def via_tuple ( name ) ,
99102 do: { :via , Horde.Registry , { Lightning.HordeRegistry , name } }
100103end
0 commit comments