Skip to content
Permalink
Browse files

Make bootup sequence wait for farmware installion

  • Loading branch information...
ConnorRigby committed Nov 7, 2019
1 parent 85d10d7 commit 9bf48c70c5bd3150bc6d4c07f594a232f222a418
@@ -2,7 +2,7 @@ defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.FarmwareInstallation do
use GenServer
require FarmbotCore.Logger

alias FarmbotCore.{Asset.Repo, BotState, JSON}
alias FarmbotCore.{Asset.Repo, BotState, DepTracker, JSON}
alias FarmbotCore.Asset.FarmwareInstallation, as: FWI
alias FarmbotCore.Asset.FarmwareInstallation.Manifest

@@ -21,6 +21,7 @@ defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.FarmwareInstallation do
end

def init(fwi) do
:ok = DepTracker.register_asset(fwi, :init)
{:ok, %{fwi: fwi, backoff: 0}, 0}
end

@@ -39,6 +40,7 @@ defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.FarmwareInstallation do
:ok <- install_zip(updated, zip_binary),
:ok <- install_farmware_tools(updated),
:ok <- write_manifest(updated) do
:ok = DepTracker.register_asset(fwi, :complete)
FarmbotCore.Logger.success(1, "Installed Farmware: #{updated.manifest.package}")
# TODO(Connor) -> No reason to keep this process alive?
BotState.report_farmware_installed(updated.manifest.package, Manifest.view(updated.manifest))
@@ -80,6 +82,8 @@ defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.FarmwareInstallation do
{:noreply, %{state | fwi: updated}, 0}

error ->
:ok = DepTracker.register_asset(fwi, :complete)
BotState.report_farmware_installed(fwi.manifest.package, Manifest.view(fwi.manifest))
backoff = state.backoff + @back_off_time_ms
timeout = @error_retry_time_ms + backoff
error_log(fwi, "failed to check for updates. Trying again in #{timeout}ms #{inspect(error)}")
@@ -92,13 +96,15 @@ defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.FarmwareInstallation do
# Installed is newer than remote.
:gt ->
success_log(updated, "up to date.")
:ok = DepTracker.register_asset(updated, :complete)
BotState.report_farmware_installed(updated.manifest.package, Manifest.view(updated.manifest))

{:noreply, %{state | fwi: updated}}

# No difference between installed and remote.
:eq ->
success_log(updated, "up to date.")
:ok = DepTracker.register_asset(updated, :complete)
BotState.report_farmware_installed(updated.manifest.package, Manifest.view(updated.manifest))

{:noreply, %{state | fwi: updated}}
@@ -111,6 +117,7 @@ defimpl FarmbotCore.AssetWorker, for: FarmbotCore.Asset.FarmwareInstallation do
:ok <- install_zip(updated, zip_binary),
:ok <- install_farmware_tools(updated),
:ok <- write_manifest(updated) do
:ok = DepTracker.register_asset(updated, :complete)
BotState.report_farmware_installed(updated.manifest.package, Manifest.view(updated.manifest))
{:noreply, %{state | fwi: updated, backoff: 0}}

@@ -66,7 +66,7 @@ defmodule FarmbotExt.API.EagerLoader do
* a remote `id` field.
"""
def cache(%Changeset{data: %module{}} = changeset) do
Logger.info("Caching #{inspect(changeset)}")
# Logger.info("Caching #{inspect(changeset)}")
id = Changeset.get_field(changeset, :id)
updated_at = Changeset.get_field(changeset, :updated_at)
id || change_error(changeset, "Can't cache a changeset with no :id attribute")
@@ -95,19 +95,19 @@ defmodule FarmbotExt.API.Reconciler do

case get_changeset(local_item || module, item, cached_cs) do
{:insert, %Changeset{} = cs} ->
Logger.info("insert: #{inspect(cs)}")
# Logger.info("insert: #{inspect(cs)}")
item = module.render(Changeset.apply_changes(cs))
:ok = Command.update(module, item.id, item)
sync_changeset

{:update, %Changeset{} = cs} ->
Logger.info("update: #{inspect(cs)}")
# Logger.info("update: #{inspect(cs)}")
item = module.render(Changeset.apply_changes(cs))
:ok = Command.update(module, item.id, item)
sync_changeset

nil ->
Logger.info("Local data: #{local_item.__struct__} is current.")
# Logger.info("Local data: #{local_item.__struct__} is current.")
sync_changeset
end
end
@@ -116,7 +116,7 @@ defmodule FarmbotExt.API.Reconciler do

# A module is passed in if there is no local copy of the data.
defp get_changeset(module, %Item{} = sync_item, nil) when is_atom(module) do
Logger.info("Local data: #{module} does not exist. Using HTTP to get data.")
# Logger.info("Local data: #{module} does not exist. Using HTTP to get data.")
{:ok, changeset} = API.get_changeset(module, "#{sync_item.id}")
{:insert, changeset}
end
@@ -3,7 +3,12 @@ defmodule FarmbotOS.BootupSequenceWorker do
require Logger
require FarmbotCore.Logger
alias FarmbotCore.{Asset, BotState, DepTracker}
alias FarmbotCore.Asset.Peripheral

alias FarmbotCore.Asset.{
FarmwareInstalation,
Peripheral
}

alias FarmbotCeleryScript.AST

def start_link(args) do
@@ -125,13 +130,7 @@ defmodule FarmbotOS.BootupSequenceWorker do
state

%{boot_sequence_id: id} ->
peripherals_loaded? =
Enum.all?(DepTracker.get_asset(Peripheral), fn
{{Peripheral, _}, :complete} -> true
_ -> false
end)

peripherals_loaded? && send(self(), :start_sequence)
dependency_assets_loaded?() && send(self(), :start_sequence)
%{state | sequence_id: id}
end
end
@@ -141,4 +140,28 @@ defmodule FarmbotOS.BootupSequenceWorker do
|> AST.Factory.rpc_request("fbos_config.bootup_sequence")
|> AST.Factory.execute(sequence_id)
end

defp dependency_assets_loaded?() do
peripherals =
Enum.all?(DepTracker.get_asset(Peripheral), fn
{{Peripheral, _}, :complete} ->
true

{{kind, id}, status} ->
Logger.debug("bootup sequence still waiting on: #{kind}.#{id} status=#{status}")
false
end)

farmware =
Enum.all?(DepTracker.get_asset(FarmwareInstalation), fn
{{FarmwareInstalation, _}, :complete} ->
true

{{kind, id}, status} ->
Logger.debug("bootup sequence still waiting on: #{kind}.#{id} status=#{status}")
false
end)

peripherals && farmware
end
end

0 comments on commit 9bf48c7

Please sign in to comment.
You can’t perform that action at this time.