rename cpu-usage to scheduler-usage, promote to farmbot_core

pull/1035/head
Connor Rigby 2019-10-02 13:05:01 -07:00 committed by Connor Rigby
parent 3e2da27323
commit 7508dea74f
7 changed files with 58 additions and 49 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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,