Current section

Files

Jump to
snowhite lib modules stock_market server.ex
Raw

lib/modules/stock_market/server.ex

defmodule Snowhite.Modules.StockMarket.Server do
use GenServer
alias Snowhite.Modules.StockMarket
@sync_timer :timer.minutes(5)
def start_link(opts) do
name =
case Keyword.get(opts, :name, __MODULE__) do
nil -> __MODULE__
name -> name
end
GenServer.start_link(__MODULE__, opts, name: name)
end
def prices(name \\ __MODULE__) do
GenServer.call(name, :prices)
end
@impl GenServer
def init(opts) do
symbols = Keyword.fetch!(opts, :symbols)
adapter = Keyword.fetch!(opts, :adapter)
adapter_options = Keyword.get(opts, :adapter_options, [])
send(self(), :sync)
{:ok, %{prices: [], symbols: symbols, adapter: adapter, adapter_options: adapter_options}}
end
@impl GenServer
def handle_info(:sync, state) do
state = update_prices(state)
Phoenix.PubSub.broadcast!(Snowhite.PubSub, "snowhite:modules:stockmarket", :updated)
Process.send_after(self(), :sync, @sync_timer)
{:noreply, state}
end
@impl GenServer
def handle_call(:prices, _, %{prices: prices} = state) do
{:reply, prices, state}
end
defp update_prices(
%{adapter: adapter, symbols: symbols, adapter_options: adapter_options} = state
) do
prices =
Enum.reduce(symbols, [], fn symbol, acc ->
case StockMarket.Adapter.invoke(adapter, symbol, adapter_options) do
nil ->
acc
symbol ->
[symbol | acc]
end
end)
Map.put(state, :prices, prices)
end
end