Last active
June 11, 2023 04:07
-
-
Save maxneuvians/47fb561a635396ae03b00007a989dd72 to your computer and use it in GitHub Desktop.
Leaky Bucket GenServer in Elixir
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule LeakyBucket.Bucket do | |
@moduledoc """ | |
Simulates a leaky bucket implementation | |
""" | |
use GenServer | |
@initial_amount 0 | |
@increment_rate 1 | |
@leak_rate 2 | |
@leak_interval 500 | |
@size 40 | |
# Public | |
@doc """ | |
Increments the amount of water in the bucket | |
""" | |
def increment do | |
GenServer.call(__MODULE__, :increment) | |
end | |
# Private | |
@doc """ | |
Starts Bucket with initial amount | |
""" | |
def start_link() do | |
GenServer.start_link(__MODULE__, %{count: @initial_amount}, [name: __MODULE__]) | |
end | |
@doc """ | |
Initiates the leak counter | |
""" | |
def init(state) do | |
send self(), :leak | |
{:ok, state} | |
end | |
@doc """ | |
Returns an error because bucket will be too full | |
""" | |
def handle_call(:increment, _from, %{count: count}) when (count + @increment_rate) > @size do | |
{:reply, :too_many_requests, %{count: count}} | |
end | |
@doc """ | |
Increments the amount of water in the bucket | |
""" | |
def handle_call(:increment, _from, %{count: count}) do | |
{:reply, count + @increment_rate, %{count: count + @increment_rate}} | |
end | |
@doc """ | |
Set count to 0 if count is less than leak rate | |
""" | |
def handle_info(:leak, %{count: count}) when count < @leak_rate do | |
Process.send_after(self(), :leak, @leak_interval) | |
{:noreply, %{count: 0}} | |
end | |
@doc """ | |
Leak amount from bucket | |
""" | |
def handle_info(:leak, %{count: count}) do | |
Process.send_after(self(), :leak, @leak_interval) | |
{:noreply, %{count: count - @leak_rate}} | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment