Last active
June 8, 2019 23:19
-
-
Save LukeWood/7fd2c49ea452ed8f204fb23500dac924 to your computer and use it in GitHub Desktop.
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 Stopwatch.Client do | |
def subscribe(pid, func) do | |
GenServer.cast(pid, {:subscribe, func}) | |
end | |
end |
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
{:ok, pid} = Stopwatch.Supervisor.new_stopwatch() | |
Stopwatch.Client.subscribe(pid, fn elapsed_millis -> IO.inspect(elapsed_millis) end) | |
# > prints time elapsed every interval |
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 Stopwatch.Server do | |
use GenServer | |
@tick_interval 100 | |
def start_link() do | |
Genserver.start(__MODULE__, %{notify_callbacks: [], start_time: os.system_time(:millisecond)}) | |
end | |
def init(time) do | |
schedule_tick(self()) | |
{:ok, state} | |
end | |
# You can listen for these events from other modules after starting a stopwatch | |
def handle_cast({:subscribe, func}, state) do | |
{:noreply, Map.put(state, :notify_callbacks, [func | notify_callbacks])} | |
end | |
# Call all functions in notify_callbacks with the elapsed amount of time | |
def handle_info(:tick, state = %{notify_callbacks: notify_callbacks, start_time: start_time) do | |
elapsed_time = os.system_time(:millisecond)-start_time | |
Enum.map(notify_callbacks, fn func -> func.(elapsed_time) end) | |
schedule_tick(self()) | |
{:noreply, state} | |
end | |
def schedule_tick(pid) do | |
Process.send_after(pid, :tick, @tick_interval) | |
end | |
end |
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 Stopwatch.Supervisor do | |
use DynamicSupervisor | |
def start_link() do | |
DynamicSupervisor.start_link(__MODULE__, :ok, name: __MODULE__) | |
end | |
def new_stopwatch() do | |
spec = {Stopwatch.Server, []} | |
DynamicSupervisor.start_child(__MODULE__, spec) | |
end | |
def init(:ok) do | |
DynamicSupervisor.init( | |
strategy: :one_for_one, | |
extra_arguments: [] | |
) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment