Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions lib/supavisor/erl_sys_mon.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,23 @@ defmodule Supavisor.ErlSysMon do
"""

use GenServer
alias Supavisor.Helpers

require Logger

def start_link(args) do
GenServer.start_link(__MODULE__, args, name: __MODULE__)
name = args[:name] || __MODULE__
GenServer.start_link(__MODULE__, args, name: name)
end

def init(_args) do
:erlang.system_monitor(self(), [
:busy_dist_port,
:busy_port,
{:long_gc, 250},
{:long_schedule, 100}
{:long_schedule, 100},
{:long_message_queue, {0, 1_000}},
{:large_heap, Helpers.mb_to_words(25)}
])

{:ok, []}
Expand Down
14 changes: 14 additions & 0 deletions lib/supavisor/helpers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -378,4 +378,18 @@ defmodule Supavisor.Helpers do
def validate_name(name) do
byte_size(name) in 1..@max_length and String.printable?(name)
end

@doc """
Converts megabytes to Erlang words.

## Examples

iex> Supavisor.Helpers.mb_to_words(1)
131_072

iex> Supavisor.Helpers.mb_to_words(1.5)
196_608
"""
@spec mb_to_words(number()) :: pos_integer()
def mb_to_words(mb), do: round(mb * 1_048_576 / :erlang.system_info(:wordsize))
end
44 changes: 44 additions & 0 deletions test/supavisor/erl_sys_mon_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
defmodule Supavisor.ErlSysMonTest do
use ExUnit.Case, async: false
import ExUnit.CaptureLog
alias Supavisor.ErlSysMon

test "starts and configures monitor with custom name" do
assert {:ok, pid} = ErlSysMon.start_link(name: __MODULE__)
assert Process.whereis(__MODULE__) == pid

{monitor_pid, settings} = :erlang.system_monitor()
assert monitor_pid == pid

[
:busy_dist_port,
:busy_port,
{:long_gc, 250},
{:long_schedule, 100},
{:long_message_queue, {0, 1_000}},
{:large_heap, 3_276_800}
]
|> Enum.each(&assert &1 in settings)

test_msg = {:monitor, self(), :test_pid, :busy_port}

log =
capture_log(fn ->
send(pid, test_msg)
Process.sleep(100)
end)

assert log =~ "Supavisor.ErlSysMon message:"
assert log =~ inspect(test_msg)

Process.exit(pid, :normal)
end

test "starts with default name when no args provided" do
pid = Process.whereis(ErlSysMon)
assert is_pid(pid)
assert Process.alive?(pid)

assert {:error, {:already_started, ^pid}} = ErlSysMon.start_link([])
end
end
Loading