nif ci fixes and dialyzer fixes

This commit is contained in:
Graham McIntire 2026-01-30 12:38:50 -06:00
parent 0214c2a100
commit de1ad8bc8a
14 changed files with 39 additions and 53 deletions

View file

@ -354,9 +354,9 @@ defmodule SnmpKit.SnmpLib.Cache do
@impl GenServer @impl GenServer
def init(opts) do def init(opts) do
# Create ETS tables # Create ETS tables
:ets.new(@cache_table, [:named_table, :set, :public, read_concurrency: true]) _ = :ets.new(@cache_table, [:named_table, :set, :public, read_concurrency: true])
:ets.new(@stats_table, [:named_table, :set, :public]) _ = :ets.new(@stats_table, [:named_table, :set, :public])
:ets.new(@access_table, [:named_table, :bag, :public]) _ = :ets.new(@access_table, [:named_table, :bag, :public])
state = %__MODULE__{ state = %__MODULE__{
max_size: Keyword.get(opts, :max_size, @default_max_size), max_size: Keyword.get(opts, :max_size, @default_max_size),

View file

@ -350,9 +350,9 @@ defmodule SnmpKit.SnmpLib.Config do
@impl GenServer @impl GenServer
def init(opts) do def init(opts) do
# Create ETS tables for fast access # Create ETS tables for fast access
:ets.new(@config_table, [:named_table, :set, :public, read_concurrency: true]) _ = :ets.new(@config_table, [:named_table, :set, :public, read_concurrency: true])
:ets.new(@schema_table, [:named_table, :set, :public, read_concurrency: true]) _ = :ets.new(@schema_table, [:named_table, :set, :public, read_concurrency: true])
:ets.new(@watchers_table, [:named_table, :bag, :public]) _ = :ets.new(@watchers_table, [:named_table, :bag, :public])
# Detect environment # Detect environment
environment = detect_environment(opts) environment = detect_environment(opts)

View file

@ -332,9 +332,9 @@ defmodule SnmpKit.SnmpLib.Dashboard do
@impl GenServer @impl GenServer
def init(opts) do def init(opts) do
# Create ETS tables for metrics storage # Create ETS tables for metrics storage
:ets.new(@metrics_table, [:named_table, :bag, :public]) _ = :ets.new(@metrics_table, [:named_table, :bag, :public])
:ets.new(@alerts_table, [:named_table, :bag, :public]) _ = :ets.new(@alerts_table, [:named_table, :bag, :public])
:ets.new(@timeseries_table, [:named_table, :ordered_set, :public]) _ = :ets.new(@timeseries_table, [:named_table, :ordered_set, :public])
state = %__MODULE__{ state = %__MODULE__{
port: Keyword.get(opts, :port, @default_port), port: Keyword.get(opts, :port, @default_port),

View file

@ -404,11 +404,9 @@ defmodule SnmpKit.SnmpLib.ErrorHandler do
@spec quarantined?(device_id()) :: boolean() @spec quarantined?(device_id()) :: boolean()
def quarantined?(device_id) do def quarantined?(device_id) do
case get_device_stats(device_id) do case get_device_stats(device_id) do
{:ok, stats} -> {:ok, _stats} ->
case stats.quarantine_until do # quarantine_until is always nil in current implementation
nil -> false false
until_time -> System.monotonic_time(:millisecond) < until_time
end
{:error, _} -> {:error, _} ->
false false
@ -649,16 +647,8 @@ defmodule SnmpKit.SnmpLib.ErrorHandler do
# Simplified calculation - in production would use historical percentiles # Simplified calculation - in production would use historical percentiles
base_calculation = trunc(stats.avg_response_time * safety_factor) base_calculation = trunc(stats.avg_response_time * safety_factor)
# Adjust based on circuit state # Adjust based on circuit state (currently always :closed)
adjustment = adjustment = 1.0
case stats.circuit_state do
# Longer timeout for unhealthy devices
:open -> 2.0
# Moderate timeout during testing
:half_open -> 1.5
# Normal timeout for healthy devices
:closed -> 1.0
end
calculated = trunc(base_calculation * adjustment) calculated = trunc(base_calculation * adjustment)

View file

@ -65,7 +65,7 @@ defmodule SnmpKit.SnmpLib.Manager do
@type version :: :v1 | :v2c @type version :: :v1 | :v2c
@type operation_result :: {:ok, snmp_value()} | {:error, atom() | {atom(), any()}} @type operation_result :: {:ok, snmp_value()} | {:error, atom() | {atom(), any()}}
@type bulk_result :: {:ok, [varbind()]} | {:error, atom() | {atom(), any()}} @type bulk_result :: {:ok, [varbind()]} | {:error, atom() | {atom(), any()}}
@type varbind :: {oid(), snmp_value()} @type varbind :: {oid(), atom(), snmp_value()}
@type manager_opts :: [ @type manager_opts :: [
community: community(), community: community(),
@ -671,6 +671,10 @@ defmodule SnmpKit.SnmpLib.Manager do
{:error, :invalid_response} {:error, :invalid_response}
end end
defp extract_bulk_result(%{pdu: %{error_status: error_status}}) when error_status != 0 do
{:error, decode_error_status(error_status)}
end
defp extract_bulk_result(%{pdu: %{varbinds: varbinds}}) do defp extract_bulk_result(%{pdu: %{varbinds: varbinds}}) do
valid_varbinds = valid_varbinds =
Enum.filter(varbinds, fn {_oid, type, value} -> Enum.filter(varbinds, fn {_oid, type, value} ->
@ -693,10 +697,6 @@ defmodule SnmpKit.SnmpLib.Manager do
{:ok, valid_varbinds} {:ok, valid_varbinds}
end end
defp extract_bulk_result(%{pdu: %{error_status: error_status}}) when error_status != 0 do
{:error, decode_error_status(error_status)}
end
defp extract_bulk_result(_), do: {:error, :invalid_response} defp extract_bulk_result(_), do: {:error, :invalid_response}
defp extract_set_result(%{pdu: %{error_status: 0}}) do defp extract_set_result(%{pdu: %{error_status: 0}}) do

View file

@ -16,7 +16,7 @@ defmodule SnmpKit.SnmpLib.PDU do
%{ %{
type: :get_request | :get_next_request | :get_response | :set_request | :get_bulk_request, type: :get_request | :get_next_request | :get_response | :set_request | :get_bulk_request,
request_id: non_neg_integer(), request_id: non_neg_integer(),
error_status: 0..5, error_status: 0..18,
error_index: non_neg_integer(), error_index: non_neg_integer(),
varbinds: [varbind()], varbinds: [varbind()],
# GETBULK only: # GETBULK only:

View file

@ -57,7 +57,7 @@ defmodule SnmpKit.SnmpLib.PDU.Constants do
@type snmp_version :: :v1 | :v2c | :v2 | :v3 | 0 | 1 | 3 @type snmp_version :: :v1 | :v2c | :v2 | :v3 | 0 | 1 | 3
@type pdu_type :: @type pdu_type ::
:get_request | :get_next_request | :get_response | :set_request | :get_bulk_request :get_request | :get_next_request | :get_response | :set_request | :get_bulk_request
@type error_status :: 0..5 @type error_status :: 0..18
@type oid :: [non_neg_integer()] | binary() @type oid :: [non_neg_integer()] | binary()
@type snmp_value :: any() @type snmp_value :: any()
@type varbind :: {oid(), atom(), snmp_value()} @type varbind :: {oid(), atom(), snmp_value()}

View file

@ -22,9 +22,10 @@ defmodule Towerops.Application do
# Note: With pre-compiled MIBs, this may no longer be needed # Note: With pre-compiled MIBs, this may no longer be needed
snmpkit_ebin = Application.app_dir(:towerops, "../snmpkit/ebin") snmpkit_ebin = Application.app_dir(:towerops, "../snmpkit/ebin")
if File.dir?(snmpkit_ebin) do _ =
_ = :code.add_patha(to_charlist(snmpkit_ebin)) if File.dir?(snmpkit_ebin) do
end :code.add_patha(to_charlist(snmpkit_ebin))
end
# Run migrations on startup (Ecto handles locking for concurrent runs) # Run migrations on startup (Ecto handles locking for concurrent runs)
_ = _ =
@ -61,13 +62,7 @@ defmodule Towerops.Application do
# Add each directory to net-snmp's search path # Add each directory to net-snmp's search path
Enum.each(mib_dirs, fn dir -> Enum.each(mib_dirs, fn dir ->
case ToweropsNative.load_mib_directory(dir) do :ok = ToweropsNative.load_mib_directory(dir)
:ok ->
:ok
{:error, reason} ->
Logger.warning("Failed to load MIB directory #{dir}: #{inspect(reason)}")
end
end) end)
# Initialize the MIB library (loads all MIBs into memory) # Initialize the MIB library (loads all MIBs into memory)

View file

@ -159,8 +159,8 @@ defmodule ToweropsWeb.DeviceLive.Show do
defp maybe_subscribe_and_schedule_refresh(socket, device_id) do defp maybe_subscribe_and_schedule_refresh(socket, device_id) do
if connected?(socket) do if connected?(socket) do
Phoenix.PubSub.subscribe(Towerops.PubSub, "device:#{device_id}") _ = Phoenix.PubSub.subscribe(Towerops.PubSub, "device:#{device_id}")
Process.send_after(self(), :refresh_data, 10_000) _ = Process.send_after(self(), :refresh_data, 10_000)
end end
:ok :ok

View file

@ -58,7 +58,7 @@ defmodule ToweropsWeb.GraphLive.Show do
defp maybe_subscribe_to_device(socket, device_id) do defp maybe_subscribe_to_device(socket, device_id) do
if connected?(socket) do if connected?(socket) do
Phoenix.PubSub.subscribe(Towerops.PubSub, "device:#{device_id}") _ = Phoenix.PubSub.subscribe(Towerops.PubSub, "device:#{device_id}")
end end
:ok :ok

View file

@ -50,7 +50,6 @@ defmodule ToweropsWeb.Plugs.RemoteIpLogger do
defp format_remote_ip({a, b, c, d}), do: "#{a}.#{b}.#{c}.#{d}" defp format_remote_ip({a, b, c, d}), do: "#{a}.#{b}.#{c}.#{d}"
defp format_remote_ip({a, b, c, d, e, f, g, h}), do: format_ipv6({a, b, c, d, e, f, g, h}) defp format_remote_ip({a, b, c, d, e, f, g, h}), do: format_ipv6({a, b, c, d, e, f, g, h})
defp format_remote_ip(_), do: "unknown"
defp format_ipv6({a, b, c, d, e, f, g, h}) do defp format_ipv6({a, b, c, d, e, f, g, h}) do
Enum.map_join([a, b, c, d, e, f, g, h], ":", &Integer.to_string(&1, 16)) Enum.map_join([a, b, c, d, e, f, g, h], ":", &Integer.to_string(&1, 16))

View file

@ -27,7 +27,7 @@ defmodule ToweropsWeb.Plugs.UpdateSessionActivity do
token = get_session(conn, :user_token) token = get_session(conn, :user_token)
if token do if token do
Task.start(fn -> update_session_activity(token) end) _ = Task.start(fn -> update_session_activity(token) end)
end end
conn conn

View file

@ -161,14 +161,16 @@ defmodule ToweropsWeb.UserAuth do
remember_me = get_session(conn, :user_remember_me) remember_me = get_session(conn, :user_remember_me)
# Create browser session in background with metadata # Create browser session in background with metadata
Task.start(fn -> _ =
create_browser_session_from_conn(conn, user, user_token) Task.start(fn ->
end) create_browser_session_from_conn(conn, user, user_token)
end)
# Record successful login attempt in background # Record successful login attempt in background
Task.start(fn -> _ =
record_successful_login(conn, user, params) Task.start(fn ->
end) record_successful_login(conn, user, params)
end)
conn conn
|> renew_session(user) |> renew_session(user)

View file

@ -10,7 +10,7 @@ defmodule Towerops.MixProject do
start_permanent: Mix.env() == :prod, start_permanent: Mix.env() == :prod,
aliases: aliases(), aliases: aliases(),
deps: deps(), deps: deps(),
compilers: [:towerops_nif, :phoenix_live_view] ++ Mix.compilers(), compilers: [:phoenix_live_view] ++ Mix.compilers(),
listeners: [Phoenix.CodeReloader], listeners: [Phoenix.CodeReloader],
dialyzer: dialyzer() dialyzer: dialyzer()
] ]