refactoring of modules

This commit is contained in:
Owen
2025-01-13 14:29:47 +01:00
committed by Owen Rees
parent 1c84a97fb8
commit 498c5ebd6f
7 changed files with 124 additions and 112 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ defmodule PlantIdDiscordBot.Application do
PlantIdDiscordBot.ProcessRegistry,
PlantIdDiscordBot.Consumer,
PlantIdDiscordBot.RateLimiter,
{PlantIdDiscordBot.Metrics, []},
{PlantIdDiscordBot.Metrics.Requests, []},
PlantIdDiscordBot.Scheduler,
{Plug.Cowboy,
scheme: :http,
+7 -94
View File
@@ -1,101 +1,14 @@
defmodule PlantIdDiscordBot.Metrics do
use Agent
alias PlantIdDiscordBot.Metrics
alias PlantIdDiscordBot.Metrics.Requests
@file_path "priv/metrics"
defstruct [
:guild_id,
:guild_name,
:first_request_at,
:last_request_at,
:total_requests
]
def start_link(_opts) do
initial_state =
case File.exists?(Path.join(@file_path, "requests")) do
true -> read()
false -> %{}
end
Agent.start_link(fn -> initial_state end, name: via_tuple(:metrics))
def backup() do
Requests.write()
end
defp via_tuple(key) do
PlantIdDiscordBot.ProcessRegistry.via_tuple({__MODULE__, key})
def increase_request_count(guild_id, guild_name) do
Requests.put(guild_id, guild_name)
end
defp get_pid do
[{pid, _value}] = Registry.lookup(PlantIdDiscordBot.ProcessRegistry, {__MODULE__, :metrics})
pid
end
def get(key) do
get_pid()
|> Agent.get(&Map.get(&1, key))
end
def get_all() do
get_pid()
|> Agent.get(& &1)
end
def put(guild_id, guild_name) do
get_pid()
|> Agent.update(fn state ->
case Map.get(state, guild_id) do
nil ->
Map.put(state, guild_id, %Metrics{
guild_id: guild_id,
guild_name: guild_name,
first_request_at: DateTime.utc_now(),
last_request_at: DateTime.utc_now(),
total_requests: 1
})
existing ->
Map.put(state, guild_id, %Metrics{
existing
| last_request_at: DateTime.utc_now(),
total_requests: existing.total_requests + 1
})
end
end)
end
@doc """
Reset metrics state and remove the saved file from disk.
"""
def reset() do
get_pid()
|> Agent.update(fn _ -> %{} end)
file = Path.join(@file_path, "requests")
if File.exists?(file) do
File.rm!(Path.join(@file_path, "requests"))
end
end
@doc """
Write the current state to disk. To be consumed by a CRON job.
"""
def write() do
File.mkdir_p!("priv/metrics")
data =
get_all()
|> :erlang.term_to_binary()
File.write!(Path.join(@file_path, "requests"), data)
end
@doc """
Read the state from disk. To be loaded into state on process start.
"""
def read() do
File.read!(Path.join(@file_path, "requests"))
|> :erlang.binary_to_term()
end
def requests(guild_id), do: Requests.get(guild_id)
def requests(), do: Requests.get_all()
end
+6 -11
View File
@@ -1,11 +1,11 @@
defmodule PlantIdDiscordBot.Metrics.Message do
def start() do
PlantIdDiscordBot.Metrics.get_all()
def send() do
PlantIdDiscordBot.Metrics.requests()
|> format_message()
|> send_message()
|> do_send_message()
end
def format_message(data) do
defp format_message(data) do
embeds =
Enum.map(data, fn {guild_id, metrics} ->
first_request_at =
@@ -30,15 +30,10 @@ defmodule PlantIdDiscordBot.Metrics.Message do
%{embeds: embeds}
end
def send_message(data) do
defp do_send_message(data) do
webhook_url = Application.get_env(:plantid_discord_bot, :metrics_webhook_url)
body = Jason.encode!(data)
headers = [
{"Content-Type", "application/json"}
]
headers = [{"Content-Type", "application/json"}]
HTTPoison.post!(webhook_url, body, headers)
end
end
+104
View File
@@ -0,0 +1,104 @@
defmodule PlantIdDiscordBot.Metrics.Requests do
use Agent
alias PlantIdDiscordBot.Metrics.Requests
alias PlantIdDiscordBot.ProcessRegistry
@file_path "priv/metrics"
defstruct [
:guild_id,
:guild_name,
:first_request_at,
:last_request_at,
:total_requests
]
def start_link(_opts) do
initial_state =
case File.exists?(Path.join(@file_path, "requests")) do
true -> read()
false -> %{}
end
Agent.start_link(fn -> initial_state end, name: via_tuple(:requests))
end
defp via_tuple(key) do
ProcessRegistry.via_tuple({__MODULE__, key})
end
defp get_pid do
[{pid, _value}] = Registry.lookup(ProcessRegistry, {__MODULE__, :requests})
pid
end
def get(key) do
get_pid()
|> Agent.get(&Map.get(&1, key))
end
def get_all() do
get_pid()
|> Agent.get(& &1)
end
def put(guild_id, guild_name) do
get_pid()
|> Agent.update(fn state ->
case Map.get(state, guild_id) do
nil ->
request_time = DateTime.utc_now()
Map.put(state, guild_id, %Requests{
guild_id: guild_id,
guild_name: guild_name,
first_request_at: request_time,
last_request_at: request_time,
total_requests: 1
})
existing ->
Map.put(state, guild_id, %Requests{
existing
| last_request_at: DateTime.utc_now(),
total_requests: existing.total_requests + 1
})
end
end)
end
@doc """
Reset metrics state and remove the saved file from disk.
"""
def reset() do
get_pid()
|> Agent.update(fn _ -> %{} end)
file = Path.join(@file_path, "requests")
if File.exists?(file) do
File.rm!(Path.join(@file_path, "requests"))
end
end
@doc """
Write the current state to disk. To be consumed by a CRON job.
"""
def write() do
File.mkdir_p!("priv/metrics")
data =
get_all()
|> :erlang.term_to_binary()
File.write!(Path.join(@file_path, "requests"), data)
end
@doc """
Read the state from disk. To be loaded into state on process start.
"""
def read() do
File.read!(Path.join(@file_path, "requests"))
|> :erlang.binary_to_term()
end
end
+2 -2
View File
@@ -117,7 +117,7 @@ defmodule PlantIdDiscordBot.Cog.PlantNet do
{:ok, %{name: guild_name}} = GuildCache.get(guild_id)
RateLimiter.increase_counter(guild_id)
Metrics.put(guild_id, guild_name)
Metrics.increase_request_count(guild_id, guild_name)
Api.create_followup_message(interaction.application_id, interaction.token, %{
content: response_message <> "\n#{original_images}"
@@ -140,7 +140,7 @@ defmodule PlantIdDiscordBot.Cog.PlantNet do
{:ok, %{name: guild_name}} = GuildCache.get(guild_id)
RateLimiter.increase_counter(guild_id)
Metrics.put(guild_id, guild_name)
Metrics.increase_request_count(guild_id, guild_name)
Api.create_followup_message(interaction.application_id, interaction.token, %{
content: "Species Not Found"
@@ -80,7 +80,7 @@ defmodule PlantIdDiscordBot.Cog.PlantNetMessage do
response_message = Parser.parse(body)
RateLimiter.increase_counter(guild_id)
Metrics.put(guild_id, guild_name)
Metrics.increase_request_count(guild_id, guild_name)
# Nostrum.Api.create_message/2 is deprecated but the new function is not available in v0.10 of the library
# Nostrum.Api.message/2 will be the new function
@@ -99,7 +99,7 @@ defmodule PlantIdDiscordBot.Cog.PlantNetMessage do
{:ok, %HTTPoison.Response{status_code: 404}} ->
RateLimiter.increase_counter(guild_id)
Metrics.put(guild_id, guild_name)
Metrics.increase_request_count(guild_id, guild_name)
Api.create_message(message.channel_id,
content: "Species Not Found",