chore(Map): Added pings clean-up logic

This commit is contained in:
Dmitry Popov
2025-05-20 00:03:28 +02:00
parent 3adf3946b5
commit 6914f75bb7
4 changed files with 74 additions and 9 deletions
+8
View File
@@ -21,6 +21,8 @@ defmodule WandererApp.Api.MapPing do
define(:by_map_and_system,
action: :by_map_and_system
)
define(:by_inserted_before, action: :by_inserted_before, args: [:inserted_before])
end
actions do
@@ -65,6 +67,12 @@ defmodule WandererApp.Api.MapPing do
filter(expr(map_id == ^arg(:map_id) and system_id == ^arg(:system_id)))
end
read :by_inserted_before do
argument(:inserted_before, :utc_datetime, allow_nil?: false)
filter(expr(inserted_at <= ^arg(:inserted_before)))
end
end
attributes do
+44 -1
View File
@@ -16,6 +16,9 @@ defmodule WandererApp.Map.Manager do
@garbage_collection_interval :timer.hours(1)
@check_maps_queue_interval :timer.seconds(1)
@pings_cleanup_interval :timer.minutes(10)
@pings_expire_minutes 60
def start_map(map_id) when is_binary(map_id),
do: WandererApp.Queue.push_uniq(@maps_queue, map_id)
@@ -44,6 +47,9 @@ defmodule WandererApp.Map.Manager do
{:ok, garbage_collector_timer} =
:timer.send_interval(@garbage_collection_interval, :garbage_collect)
{:ok, pings_cleanup_timer} =
:timer.send_interval(@pings_cleanup_interval, :cleanup_pings)
try do
Task.async(fn ->
start_last_active_maps()
@@ -56,7 +62,8 @@ defmodule WandererApp.Map.Manager do
{:ok,
%{
garbage_collector_timer: garbage_collector_timer,
check_maps_queue_timer: check_maps_queue_timer
check_maps_queue_timer: check_maps_queue_timer,
pings_cleanup_timer: pings_cleanup_timer
}}
end
@@ -118,6 +125,42 @@ defmodule WandererApp.Map.Manager do
end
end
@impl true
def handle_info(:cleanup_pings, state) do
try do
cleanup_expired_pings()
{:noreply, state}
rescue
e ->
Logger.error("Failed to cleanup pings: #{inspect(e)}")
{:noreply, state}
end
end
def cleanup_expired_pings() do
delete_after_date = DateTime.utc_now() |> DateTime.add(-1 * @pings_expire_minutes, :minute)
case WandererApp.MapPingsRepo.get_by_inserted_before(delete_after_date) do
{:ok, pings} ->
Enum.each(pings, fn %{map_id: map_id, type: type} = ping ->
{:ok, %{system: system}} = ping |> Ash.load([:system])
WandererApp.Map.Server.Impl.broadcast!(map_id, :ping_cancelled, %{
solar_system_id: system.solar_system_id,
type: type
})
Ash.destroy!(ping)
end)
:ok
{:error, error} ->
Logger.error("Failed to fetch expired pings: #{inspect(error)}")
{:error, error}
end
end
defp start_last_active_maps() do
{:ok, last_map_states} =
WandererApp.Api.MapState.get_last_active(
@@ -9,6 +9,9 @@ defmodule WandererApp.MapPingsRepo do
def get_by_map(map_id),
do: WandererApp.Api.MapPing.by_map!(%{map_id: map_id}) |> Ash.load([:character, :system])
def get_by_inserted_before(inserted_before_date),
do: WandererApp.Api.MapPing.by_inserted_before(inserted_before_date)
def create(ping), do: ping |> WandererApp.Api.MapPing.new()
def create!(ping), do: ping |> WandererApp.Api.MapPing.new!()
@@ -72,14 +72,25 @@ defmodule WandererAppWeb.MapPingsEventHandler do
socket
)
when not is_nil(main_character_id) do
map_id
|> WandererApp.Map.Server.add_ping(%{
solar_system_id: solar_system_id,
message: message,
type: type,
character_id: main_character_id,
user_id: current_user.id
})
{:ok, pings} = WandererApp.MapPingsRepo.get_by_map(map_id)
no_exisiting_pings =
pings
|> Enum.filter(fn %{type: type} ->
type == 1
end)
|> Enum.empty?()
if no_exisiting_pings do
map_id
|> WandererApp.Map.Server.add_ping(%{
solar_system_id: solar_system_id,
message: message,
type: type,
character_id: main_character_id,
user_id: current_user.id
})
end
{:noreply, socket}
end