Add global registry system, refresh token when internet is back up

pull/435/head
connor rigby 2018-01-30 09:53:38 -08:00
parent 8e834fb7d5
commit 6de2fae14d
5 changed files with 61 additions and 6 deletions

View File

@ -20,6 +20,7 @@ defmodule Farmbot.Bootstrap.AuthTask do
def init([]) do
timer = Process.send_after(self(), :refresh, @refresh_time)
Farmbot.System.Registry.subscribe(self())
{:ok, timer, :hibernate}
end
@ -29,7 +30,7 @@ defmodule Farmbot.Bootstrap.AuthTask do
end
end
def handle_info(:refresh, _old_timer) do
defp do_refresh do
auth_task = Application.get_env(:farmbot, :behaviour)[:authorization]
{email, pass, server} = {fetch_email(), fetch_pass(), fetch_server()}
# Logger.busy(3, "refreshing token: #{email} - #{server}")
@ -48,10 +49,21 @@ defmodule Farmbot.Bootstrap.AuthTask do
{:error, err} ->
msg = "Token failed to reauthorize: #{email} - #{server} #{inspect err}"
Logger.error(1, msg)
refresh_timer(self(), 30_000)
# If refresh failed, try again more often
refresh_timer(self(), 15_000)
end
end
def handle_info(:refresh, _old_timer) do
do_refresh()
end
def handle_info({Farmbot.System.Registry, {:network, :dns_up}}, _old_timer) do
do_refresh()
end
def handle_info({Farmbot.System.Registry, _}, timer), do: {:noreply, timer}
def handle_call(:force_refresh, _, old_timer) do
Logger.info 1, "Forcing a token refresh."
if Process.read_timer(old_timer) do

View File

@ -0,0 +1,31 @@
defmodule Farmbot.System.Registry do
@moduledoc "Farmbot System Global Registry"
@reg FarmbotRegistry
@doc false
def start_link do
GenServer.start_link(__MODULE__, [], [name: __MODULE__])
end
@doc "Dispatch a global event from a namespace."
def dispatch(namespace, event) do
GenServer.call(__MODULE__, {:dispatch, namespace, event})
end
def subscribe(pid) do
Elixir.Registry.register(@reg, __MODULE__, pid)
end
def init([]) do
opts = [keys: :duplicate, partitions: System.schedulers_online, name: @reg]
{:ok, reg} = Elixir.Registry.start_link(opts)
{:ok, %{reg: reg}}
end
def handle_call({:dispatch, ns, event}, _from, state) do
Elixir.Registry.dispatch(@reg, __MODULE__, fn(entries) ->
for {pid, _} <- entries, do: send(pid, {__MODULE__, {ns, event}})
end)
{:reply, :ok, state}
end
end

View File

@ -12,6 +12,7 @@ defmodule Farmbot.System.Supervisor do
def init([]) do
before_init_children = [
worker(Farmbot.System.Registry, []),
worker(Farmbot.System.Init.KernelMods, [[], []]),
worker(Farmbot.System.Init.FSCheckup, [[], []]),
supervisor(Farmbot.System.Init.Ecto, [[], []]),

View File

@ -22,9 +22,9 @@ defmodule Farmbot.Target.Network.Manager do
init(args)
end
SystemRegistry.register()
{:ok, _} = Registry.register(Nerves.NetworkInterface, interface, [])
{:ok, _} = Registry.register(Nerves.Udhcpc, interface, [])
{:ok, _} = Registry.register(Nerves.WpaSupplicant, interface, [])
{:ok, _} = Elixir.Registry.register(Nerves.NetworkInterface, interface, [])
{:ok, _} = Elixir.Registry.register(Nerves.Udhcpc, interface, [])
{:ok, _} = Elixir.Registry.register(Nerves.WpaSupplicant, interface, [])
Network.setup(interface, opts)
{:ok, %{interface: interface, ip_address: nil, connected: false, not_found_timer: nil, ntp_timer: nil, dns_timer: nil}}
end
@ -105,9 +105,11 @@ defmodule Farmbot.Target.Network.Manager do
# If we weren't previously connected, send a log.
unless state.connected do
Logger.success 3, "Farmbot was reconnected to the internet: #{inspect aliases}"
Farmbot.System.Registry.dispatch(:network, :dns_up)
end
{:noreply, %{state | connected: true, dns_timer: restart_dns_timer(nil, 45_000)}}
{:error, err} ->
Farmbot.System.Registry.dispatch(:network, :dns_down)
Logger.warn 3, "Farmbot was disconnected from the internet: #{inspect err}"
{:noreply, %{state | connected: false, dns_timer: restart_dns_timer(nil, 10_000)}}
end
@ -151,7 +153,6 @@ defmodule Farmbot.Target.Network.Manager do
if Farmbot.System.ConfigStorage.get_config_value(:bool, "settings", "first_boot") do
Process.send_after(self(), :ntp_timer, 10_000 + rand)
else
Process.send_after(self(), :ntp_timer, 300000 + rand)
end
end

View File

@ -0,0 +1,10 @@
defmodule Farmbot.System.RegistryTest do
use ExUnit.Case
alias Farmbot.System.Registry
test "subscribes and dispatches global events" do
Registry.subscribe(self())
Registry.dispatch(:hello, :world)
assert_receive {Registry, {:hello, :world}}
end
end