From 7508dea74ffb3f115f165949a8d478ba26ae9e19 Mon Sep 17 00:00:00 2001 From: Connor Rigby Date: Wed, 2 Oct 2019 13:05:01 -0700 Subject: [PATCH] rename cpu-usage to scheduler-usage, promote to farmbot_core --- farmbot_core/lib/farmbot_core/bot_state.ex | 8 ++-- .../bot_state/scheduler_usage_reporter.ex | 44 +++++++++++++++++++ .../lib/farmbot_core/bot_state/supervisor.ex | 3 +- .../bot_state_ng/informational_settings.ex | 8 ++-- farmbot_core/test/bot_state_ng_test.exs | 6 +-- .../platform/target/info_workers/cpu_usage.ex | 36 --------------- .../target/info_workers/supervisor.ex | 2 - 7 files changed, 58 insertions(+), 49 deletions(-) create mode 100644 farmbot_core/lib/farmbot_core/bot_state/scheduler_usage_reporter.ex delete mode 100644 farmbot_os/platform/target/info_workers/cpu_usage.ex diff --git a/farmbot_core/lib/farmbot_core/bot_state.ex b/farmbot_core/lib/farmbot_core/bot_state.ex index 8882bc0f..424a3338 100644 --- a/farmbot_core/lib/farmbot_core/bot_state.ex +++ b/farmbot_core/lib/farmbot_core/bot_state.ex @@ -119,8 +119,8 @@ defmodule FarmbotCore.BotState do GenServer.call(bot_state_server, {:report_memory_usage, megabytes}) end - def report_cpu_usage(bot_state_server \\ __MODULE__, percent) do - GenServer.call(bot_state_server, {:report_cpu_usage, percent}) + def report_scheduler_usage(bot_state_server \\ __MODULE__, percent) do + GenServer.call(bot_state_server, {:report_scheduler_usage, percent}) end def report_soc_temp(bot_state_server \\ __MODULE__, temp_celcius) do @@ -377,8 +377,8 @@ defmodule FarmbotCore.BotState do {:reply, reply, state} end - def handle_call({:report_cpu_usage, percent}, _form, state) do - change = %{informational_settings: %{cpu_usage: percent}} + def handle_call({:report_scheduler_usage, average_percent}, _form, state) do + change = %{informational_settings: %{scheduler_usage: average_percent}} {reply, state} = BotStateNG.changeset(state.tree, change) diff --git a/farmbot_core/lib/farmbot_core/bot_state/scheduler_usage_reporter.ex b/farmbot_core/lib/farmbot_core/bot_state/scheduler_usage_reporter.ex new file mode 100644 index 00000000..35082eeb --- /dev/null +++ b/farmbot_core/lib/farmbot_core/bot_state/scheduler_usage_reporter.ex @@ -0,0 +1,44 @@ +defmodule FarmbotCore.BotState.SchedulerUsageReporter do + alias FarmbotCore.BotState + use GenServer + @default_timeout_ms 5000 + + def start_link(args) do + GenServer.start_link(__MODULE__, args) + end + + def init(_args) do + _ = :msacc.start() + {:ok, %{}, @default_timeout_ms} + end + + def handle_info(:timeout, state) do + scheduler_info = for %{ + type: type, + id: id, + counters: %{ + aux: aux, + check_io: check_io, + emulator: emulator, + gc: gc, + other: other, + port: port, + sleep: sleep + } + } when type in [:scheduler, :dirty_cpu_scheduler] <- :msacc.stats() do + denominator = aux + check_io + emulator + gc + other + port + sleep + numerator = denominator - sleep + {"#{type}_#{id}", numerator / denominator} + end + + average = calculate_average(scheduler_info, Enum.count(scheduler_info)) + _ = BotState.report_scheduler_usage(average) + {:noreply, state, @default_timeout_ms} + end + + defp calculate_average(usage, count, acc \\ 0) + defp calculate_average([{_, usage} | rest], count, acc), + do: calculate_average(rest, count, acc + usage) + defp calculate_average([], count, acc), + do: round((acc / count) * 100) +end \ No newline at end of file diff --git a/farmbot_core/lib/farmbot_core/bot_state/supervisor.ex b/farmbot_core/lib/farmbot_core/bot_state/supervisor.ex index 696a2a86..1496dbca 100644 --- a/farmbot_core/lib/farmbot_core/bot_state/supervisor.ex +++ b/farmbot_core/lib/farmbot_core/bot_state/supervisor.ex @@ -8,7 +8,8 @@ defmodule FarmbotCore.BotState.Supervisor do def init([]) do children = [ FarmbotCore.BotState, - FarmbotCore.BotState.FileSystem + FarmbotCore.BotState.FileSystem, + FarmbotCore.BotState.SchedulerUsageReporter ] Supervisor.init(children, [strategy: :one_for_all]) end diff --git a/farmbot_core/lib/farmbot_core/bot_state_ng/informational_settings.ex b/farmbot_core/lib/farmbot_core/bot_state_ng/informational_settings.ex index 97a01c27..0c081265 100644 --- a/farmbot_core/lib/farmbot_core/bot_state_ng/informational_settings.ex +++ b/farmbot_core/lib/farmbot_core/bot_state_ng/informational_settings.ex @@ -24,7 +24,7 @@ defmodule FarmbotCore.BotStateNG.InformationalSettings do field(:uptime, :integer) field(:memory_usage, :integer) field(:disk_usage, :integer) - field(:cpu_usage, :integer) + field(:scheduler_usage, :integer) field(:sync_status, :string, default: "sync_now") field(:locked, :boolean, default: false) field(:last_status, :string) @@ -57,7 +57,9 @@ defmodule FarmbotCore.BotStateNG.InformationalSettings do uptime: informational_settings.uptime, memory_usage: informational_settings.memory_usage, disk_usage: informational_settings.disk_usage, - cpu_usage: informational_settings.cpu_usage, + scheduler_usage: informational_settings.scheduler_usage, + # this field is required for the frontend. Maybe remove in the future. + cpu_usage: informational_settings.scheduler_usage, sync_status: informational_settings.sync_status, locked: informational_settings.locked, last_status: informational_settings.last_status, @@ -86,7 +88,7 @@ defmodule FarmbotCore.BotStateNG.InformationalSettings do :uptime, :memory_usage, :disk_usage, - :cpu_usage, + :scheduler_usage, :sync_status, :locked, :last_status, diff --git a/farmbot_core/test/bot_state_ng_test.exs b/farmbot_core/test/bot_state_ng_test.exs index 07ca60f9..dceb8c55 100644 --- a/farmbot_core/test/bot_state_ng_test.exs +++ b/farmbot_core/test/bot_state_ng_test.exs @@ -89,14 +89,14 @@ defmodule FarmbotCore.BotStateNGTest do assert mut.informational_settings.memory_usage == 512 end - test "reports cpu_usage" do + test "reports scheduler usage" do orig = BotStateNG.new() mut = - BotStateNG.changeset(orig, %{informational_settings: %{cpu_usage: 10}}) + BotStateNG.changeset(orig, %{informational_settings: %{scheduler_usage: 10}}) |> Ecto.Changeset.apply_changes() - assert mut.informational_settings.cpu_usage == 10 + assert mut.informational_settings.scheduler_usage == 10 end test "reports uptime" do diff --git a/farmbot_os/platform/target/info_workers/cpu_usage.ex b/farmbot_os/platform/target/info_workers/cpu_usage.ex deleted file mode 100644 index 8fb8ac5b..00000000 --- a/farmbot_os/platform/target/info_workers/cpu_usage.ex +++ /dev/null @@ -1,36 +0,0 @@ -defmodule FarmbotOS.Platform.Target.InfoWorker.CpuUsage do - @moduledoc false - - use GenServer - @default_timeout_ms 60_000 - @error_timeout_ms 5_000 - alias FarmbotCore.BotState - - def start_link(args) do - GenServer.start_link(__MODULE__, args) - end - - def init([]) do - {:ok, nil, 0} - end - - def handle_info(:timeout, state) do - usage = collect_report() - - if GenServer.whereis(BotState) do - BotState.report_cpu_usage(usage) - {:noreply, state, @default_timeout_ms} - else - {:noreply, state, @error_timeout_ms} - end - end - - def collect_report do - :erlang.system_flag(:scheduler_wall_time, true) - stat0 = :lists.sort(:erlang.statistics(:scheduler_wall_time)) - Process.sleep(1000) - stat1 = :lists.sort(:erlang.statistics(:scheduler_wall_time)) - {active, total} = Enum.zip(stat0, stat1) |> List.foldl({0, 0}, fn {{_, a0, t0}, {_, a1, t1}}, {ai, ti} -> {ai + (a1 - a0), ai + (t1 - t0)} end) - ((active / total) * (:erlang.system_info(:schedulers) + :erlang.system_info(:dirty_cpu_schedulers))) / :erlang.system_info(:logical_processors_available) - end -end diff --git a/farmbot_os/platform/target/info_workers/supervisor.ex b/farmbot_os/platform/target/info_workers/supervisor.ex index 0da6cdcd..86ebc375 100644 --- a/farmbot_os/platform/target/info_workers/supervisor.ex +++ b/farmbot_os/platform/target/info_workers/supervisor.ex @@ -4,7 +4,6 @@ defmodule FarmbotOS.Platform.Target.InfoWorker.Supervisor do alias FarmbotOS.Platform.Target.InfoWorker.{ DiskUsage, - CpuUsage, MemoryUsage, SocTemp, Throttle, @@ -19,7 +18,6 @@ defmodule FarmbotOS.Platform.Target.InfoWorker.Supervisor do def init([]) do children = [ DiskUsage, - CpuUsage, MemoryUsage, SocTemp, Throttle,