Further refactor Preloader to allow for error recovery
Previous system would crash the calling processes with a `MatchError` instead of returning an error. The end result after this commit is still the same - the auto_sync channel will attempt a resync every 5 seconds. The log messages/user experience should just be better now.pull/974/head
parent
11220c3697
commit
eefdbfc883
|
@ -57,7 +57,7 @@ defmodule FarmbotExt.AMQP.AutoSyncChannel do
|
|||
else
|
||||
{:error, reason} ->
|
||||
BotState.set_sync_status("sync_error")
|
||||
Logger.error("Error preloading. #{reason}")
|
||||
FarmbotCore.Logger.error(1, "Error preloading. #{inspect(reason)}")
|
||||
Process.send_after(self(), :preload, 5000)
|
||||
{:noreply, state}
|
||||
end
|
||||
|
|
|
@ -147,22 +147,35 @@ defmodule FarmbotExt.API do
|
|||
|
||||
@doc "helper for `GET`ing a path."
|
||||
def get_body!(path) do
|
||||
case API.get!(API.client(), path) do
|
||||
%{body: body, status: 200} ->
|
||||
case API.get(API.client(), path) do
|
||||
{:ok, %{body: body, status: 200}} ->
|
||||
{:ok, body}
|
||||
|
||||
%{body: error, status: status} ->
|
||||
msg = """
|
||||
HTTP Error getting: #{path}
|
||||
Status Code = #{status}
|
||||
{:ok, %{body: error, status: status}} when is_binary(error) ->
|
||||
get_body_error(path, status, error)
|
||||
|
||||
#{error}
|
||||
"""
|
||||
{:ok, %{body: %{"error" => error}, status: status}} when is_binary(error) ->
|
||||
get_body_error(path, status, error)
|
||||
|
||||
{:error, msg}
|
||||
{:ok, %{body: error, status: status}} when is_binary(error) ->
|
||||
get_body_error(path, status, inspect(error))
|
||||
|
||||
{:error, reason} ->
|
||||
{:error, reason}
|
||||
end
|
||||
end
|
||||
|
||||
defp get_body_error(path, status, error) when is_binary(error) do
|
||||
msg = """
|
||||
HTTP Error getting: #{path}
|
||||
Status Code = #{status}
|
||||
|
||||
#{error}
|
||||
"""
|
||||
|
||||
{:error, msg}
|
||||
end
|
||||
|
||||
@callback get_changeset(module) :: {:ok, %Ecto.Changeset{}} | {:error, term()}
|
||||
@callback get_changeset(data :: module | map(), Path.t()) ::
|
||||
{:ok, %Ecto.Changeset{}} | {:error, term()}
|
||||
|
|
|
@ -10,7 +10,11 @@ defmodule FarmbotExt.API.EagerLoader do
|
|||
require Logger
|
||||
use GenServer
|
||||
|
||||
@doc "Does a ton of HTTP requests to preload the cache"
|
||||
@doc """
|
||||
Does a ton of HTTP requests to preload the cache
|
||||
Failure in this function is less than ideal and should probably return an
|
||||
error
|
||||
"""
|
||||
def preload(%Sync{} = sync) do
|
||||
SyncGroup.all_groups()
|
||||
|> Enum.map(fn asset_module ->
|
||||
|
@ -24,14 +28,23 @@ defmodule FarmbotExt.API.EagerLoader do
|
|||
end)
|
||||
|> List.flatten()
|
||||
|> Enum.map(&Task.await(&1, :infinity))
|
||||
|> Enum.reduce([], fn
|
||||
{:ok, changeset}, errors ->
|
||||
:ok = cache(changeset)
|
||||
errors
|
||||
|
||||
:ok
|
||||
error, errors ->
|
||||
[error | errors]
|
||||
end)
|
||||
|> case do
|
||||
[] -> :ok
|
||||
errors -> {:error, errors}
|
||||
end
|
||||
end
|
||||
|
||||
def preload(asset_module, %{id: id}) when is_atom(asset_module) do
|
||||
local = Repo.one(from(m in asset_module, where: m.id == ^id)) || asset_module
|
||||
{:ok, changeset} = API.get_changeset(local, id)
|
||||
:ok = cache(changeset)
|
||||
API.get_changeset(local, id)
|
||||
end
|
||||
|
||||
@doc "Get a Changeset by module and id. May return nil"
|
||||
|
|
|
@ -34,7 +34,7 @@ defmodule FarmbotExt.API.Preloader do
|
|||
|
||||
FarmbotCore.Logger.success(3, "Successfully synced bootup resources.")
|
||||
|
||||
:ok = maybe_auto_sync(sync_changeset, auto_sync_change || Query.auto_sync?())
|
||||
maybe_auto_sync(sync_changeset, auto_sync_change || Query.auto_sync?())
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -52,19 +52,27 @@ defmodule FarmbotExt.API.Preloader do
|
|||
|> Repo.transaction()
|
||||
|
||||
FarmbotCore.Logger.success(3, "bootup auto sync complete")
|
||||
:ok
|
||||
else
|
||||
error -> FarmbotCore.Logger.error(3, "bootup auto sync failed #{inspect(error)}")
|
||||
error ->
|
||||
FarmbotCore.Logger.error(3, "bootup auto sync failed #{inspect(error)}")
|
||||
error
|
||||
end
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
# When auto_sync is disabled preload the sync.
|
||||
defp maybe_auto_sync(sync_changeset, false) do
|
||||
FarmbotCore.Logger.busy(3, "preloading sync")
|
||||
sync = Changeset.apply_changes(sync_changeset)
|
||||
EagerLoader.preload(sync)
|
||||
FarmbotCore.Logger.success(3, "preloaded sync ok")
|
||||
:ok
|
||||
|
||||
case EagerLoader.preload(sync) do
|
||||
:ok ->
|
||||
FarmbotCore.Logger.success(3, "preloaded sync ok")
|
||||
:ok
|
||||
|
||||
error ->
|
||||
FarmbotCore.Logger.error(3, "Failed ot preload sync")
|
||||
error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue