mirror of
https://github.com/wanderer-industries/wanderer
synced 2025-12-14 11:46:10 +00:00
fix: updated connections cleanup logic
Some checks are pending
Build / 🚀 Deploy to test env (fly.io) (push) Waiting to run
Build / Manual Approval (push) Blocked by required conditions
Build / 🛠 Build (1.17, 18.x, 27) (push) Blocked by required conditions
Build / 🛠 Build Docker Images (linux/amd64) (push) Blocked by required conditions
Build / 🛠 Build Docker Images (linux/arm64) (push) Blocked by required conditions
Build / merge (push) Blocked by required conditions
Build / 🏷 Create Release (push) Blocked by required conditions
Some checks are pending
Build / 🚀 Deploy to test env (fly.io) (push) Waiting to run
Build / Manual Approval (push) Blocked by required conditions
Build / 🛠 Build (1.17, 18.x, 27) (push) Blocked by required conditions
Build / 🛠 Build Docker Images (linux/amd64) (push) Blocked by required conditions
Build / 🛠 Build Docker Images (linux/arm64) (push) Blocked by required conditions
Build / merge (push) Blocked by required conditions
Build / 🏷 Create Release (push) Blocked by required conditions
This commit is contained in:
@@ -217,7 +217,6 @@ export enum OutCommand {
|
|||||||
getSystemKills = 'get_system_kills',
|
getSystemKills = 'get_system_kills',
|
||||||
getSystemsKills = 'get_systems_kills',
|
getSystemsKills = 'get_systems_kills',
|
||||||
openSettings = 'open_settings',
|
openSettings = 'open_settings',
|
||||||
hideActivity = 'hide_activity',
|
|
||||||
showActivity = 'show_activity',
|
showActivity = 'show_activity',
|
||||||
hideTracking = 'hide_tracking',
|
hideTracking = 'hide_tracking',
|
||||||
showTracking = 'show_tracking',
|
showTracking = 'show_tracking',
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ defmodule WandererApp.Api.MapState do
|
|||||||
default_accept [
|
default_accept [
|
||||||
:map_id,
|
:map_id,
|
||||||
:systems_last_activity,
|
:systems_last_activity,
|
||||||
:connections_eol_time
|
:connections_eol_time,
|
||||||
|
:connections_start_time
|
||||||
]
|
]
|
||||||
|
|
||||||
defaults [:read, :update, :destroy]
|
defaults [:read, :update, :destroy]
|
||||||
@@ -45,6 +46,7 @@ defmodule WandererApp.Api.MapState do
|
|||||||
upsert_fields [
|
upsert_fields [
|
||||||
:systems_last_activity,
|
:systems_last_activity,
|
||||||
:connections_eol_time,
|
:connections_eol_time,
|
||||||
|
:connections_start_time,
|
||||||
:updated_at
|
:updated_at
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
@@ -63,6 +65,10 @@ defmodule WandererApp.Api.MapState do
|
|||||||
allow_nil?(true)
|
allow_nil?(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
attribute :connections_start_time, WandererApp.Schema.AshErlangBinary do
|
||||||
|
allow_nil?(true)
|
||||||
|
end
|
||||||
|
|
||||||
attribute :connections_eol_time, WandererApp.Schema.AshErlangBinary do
|
attribute :connections_eol_time, WandererApp.Schema.AshErlangBinary do
|
||||||
allow_nil?(true)
|
allow_nil?(true)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -81,6 +81,11 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
|||||||
:timer.hours(get_connection_auto_expire_hours() - get_connection_auto_eol_hours()) +
|
:timer.hours(get_connection_auto_expire_hours() - get_connection_auto_eol_hours()) +
|
||||||
:timer.minutes(get_eol_expire_timeout_mins())
|
:timer.minutes(get_eol_expire_timeout_mins())
|
||||||
|
|
||||||
|
def get_connection_expire_timeout(),
|
||||||
|
do:
|
||||||
|
:timer.hours(get_connection_auto_expire_hours()) +
|
||||||
|
:timer.minutes(get_eol_expire_timeout_mins())
|
||||||
|
|
||||||
def init_eol_cache(map_id, connections_eol_time) do
|
def init_eol_cache(map_id, connections_eol_time) do
|
||||||
eol_expire_timeout = get_eol_expire_timeout()
|
eol_expire_timeout = get_eol_expire_timeout()
|
||||||
|
|
||||||
@@ -94,6 +99,15 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def init_start_cache(map_id, connections_start_time) when not is_nil(connections_start_time) do
|
||||||
|
connections_start_time
|
||||||
|
|> Enum.each(fn {connection_id, start_time} ->
|
||||||
|
set_start_time(map_id, connection_id, start_time)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def init_start_cache(_map_id, _connections_start_time), do: :ok
|
||||||
|
|
||||||
def add_connection(
|
def add_connection(
|
||||||
%{map_id: map_id} = state,
|
%{map_id: map_id} = state,
|
||||||
%{
|
%{
|
||||||
@@ -158,7 +172,7 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
|||||||
),
|
),
|
||||||
do:
|
do:
|
||||||
update_connection(state, :update_time_status, [:time_status], connection_update, fn
|
update_connection(state, :update_time_status, [:time_status], connection_update, fn
|
||||||
%{id: connection_id, time_status: time_status} ->
|
%{time_status: old_time_status}, %{id: connection_id, time_status: time_status} ->
|
||||||
case time_status == @connection_time_status_eol do
|
case time_status == @connection_time_status_eol do
|
||||||
true ->
|
true ->
|
||||||
WandererApp.Cache.put(
|
WandererApp.Cache.put(
|
||||||
@@ -168,7 +182,10 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
|||||||
)
|
)
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
WandererApp.Cache.delete("map_#{map_id}:conn_#{connection_id}:mark_eol_time")
|
if old_time_status == @connection_time_status_eol do
|
||||||
|
WandererApp.Cache.delete("map_#{map_id}:conn_#{connection_id}:mark_eol_time")
|
||||||
|
set_start_time(map_id, connection_id, DateTime.utc_now())
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -205,18 +222,22 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
|||||||
def cleanup_connections(%{map_id: map_id} = state) do
|
def cleanup_connections(%{map_id: map_id} = state) do
|
||||||
connection_auto_expire_hours = get_connection_auto_expire_hours()
|
connection_auto_expire_hours = get_connection_auto_expire_hours()
|
||||||
connection_auto_eol_hours = get_connection_auto_eol_hours()
|
connection_auto_eol_hours = get_connection_auto_eol_hours()
|
||||||
|
connection_eol_expire_timeout_hours = get_eol_expire_timeout_mins() / 60
|
||||||
|
|
||||||
state =
|
state =
|
||||||
map_id
|
map_id
|
||||||
|> WandererApp.Map.list_connections!()
|
|> WandererApp.Map.list_connections!()
|
||||||
|> Enum.filter(fn %{
|
|> Enum.filter(fn %{
|
||||||
|
id: connection_id,
|
||||||
inserted_at: inserted_at,
|
inserted_at: inserted_at,
|
||||||
solar_system_source: solar_system_source_id,
|
solar_system_source: solar_system_source_id,
|
||||||
solar_system_target: solar_system_target_id,
|
solar_system_target: solar_system_target_id,
|
||||||
type: type
|
type: type
|
||||||
} ->
|
} ->
|
||||||
|
connection_start_time = get_start_time(map_id, connection_id)
|
||||||
|
|
||||||
type != @connection_type_stargate &&
|
type != @connection_type_stargate &&
|
||||||
DateTime.diff(DateTime.utc_now(), inserted_at, :hour) >=
|
DateTime.diff(DateTime.utc_now(), connection_start_time, :hour) >=
|
||||||
connection_auto_eol_hours &&
|
connection_auto_eol_hours &&
|
||||||
is_connection_valid(
|
is_connection_valid(
|
||||||
:wormholes,
|
:wormholes,
|
||||||
@@ -242,7 +263,6 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
|||||||
|> WandererApp.Map.list_connections!()
|
|> WandererApp.Map.list_connections!()
|
||||||
|> Enum.filter(fn %{
|
|> Enum.filter(fn %{
|
||||||
id: connection_id,
|
id: connection_id,
|
||||||
inserted_at: inserted_at,
|
|
||||||
solar_system_source: solar_system_source_id,
|
solar_system_source: solar_system_source_id,
|
||||||
solar_system_target: solar_system_target_id,
|
solar_system_target: solar_system_target_id,
|
||||||
type: type
|
type: type
|
||||||
@@ -273,10 +293,9 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
|||||||
|
|
||||||
not is_connection_exist ||
|
not is_connection_exist ||
|
||||||
(type != @connection_type_stargate && is_connection_valid &&
|
(type != @connection_type_stargate && is_connection_valid &&
|
||||||
(DateTime.diff(DateTime.utc_now(), inserted_at, :hour) >=
|
DateTime.diff(DateTime.utc_now(), connection_mark_eol_time, :hour) >=
|
||||||
connection_auto_expire_hours ||
|
connection_auto_expire_hours - connection_auto_eol_hours +
|
||||||
DateTime.diff(DateTime.utc_now(), connection_mark_eol_time, :hour) >=
|
+connection_eol_expire_timeout_hours)
|
||||||
connection_auto_expire_hours - connection_auto_eol_hours))
|
|
||||||
end)
|
end)
|
||||||
|> Enum.reduce(state, fn %{
|
|> Enum.reduce(state, fn %{
|
||||||
solar_system_source: solar_system_source_id,
|
solar_system_source: solar_system_source_id,
|
||||||
@@ -341,6 +360,10 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
|||||||
type: connection_type
|
type: connection_type
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if connection_type == @connection_type_wormhole do
|
||||||
|
set_start_time(map_id, connection.id, DateTime.utc_now())
|
||||||
|
end
|
||||||
|
|
||||||
WandererApp.Map.add_connection(map_id, connection)
|
WandererApp.Map.add_connection(map_id, connection)
|
||||||
|
|
||||||
Impl.broadcast!(map_id, :maybe_select_system, %{
|
Impl.broadcast!(map_id, :maybe_select_system, %{
|
||||||
@@ -386,6 +409,24 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get_start_time(map_id, connection_id) do
|
||||||
|
case WandererApp.Cache.get("map_#{map_id}:conn_#{connection_id}:start_time") do
|
||||||
|
nil ->
|
||||||
|
set_start_time(map_id, connection_id, DateTime.utc_now())
|
||||||
|
DateTime.utc_now()
|
||||||
|
|
||||||
|
value ->
|
||||||
|
value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_start_time(map_id, connection_id, start_time) do
|
||||||
|
WandererApp.Cache.put(
|
||||||
|
"map_#{map_id}:conn_#{connection_id}:start_time",
|
||||||
|
start_time
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def maybe_add_connection(_map_id, _location, _old_location, _character_id), do: :ok
|
def maybe_add_connection(_map_id, _location, _old_location, _character_id), do: :ok
|
||||||
|
|
||||||
def can_add_location(_scope, nil), do: false
|
def can_add_location(_scope, nil), do: false
|
||||||
@@ -499,6 +540,8 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
|||||||
Impl.broadcast!(map_id, :remove_connections, [connection])
|
Impl.broadcast!(map_id, :remove_connections, [connection])
|
||||||
map_id |> WandererApp.Map.remove_connection(connection)
|
map_id |> WandererApp.Map.remove_connection(connection)
|
||||||
|
|
||||||
|
WandererApp.Cache.delete("map_#{map_id}:conn_#{connection.id}:start_time")
|
||||||
|
|
||||||
_error ->
|
_error ->
|
||||||
:ok
|
:ok
|
||||||
end
|
end
|
||||||
@@ -534,7 +577,7 @@ defmodule WandererApp.Map.Server.ConnectionsImpl do
|
|||||||
connection |> Map.merge(update_map)
|
connection |> Map.merge(update_map)
|
||||||
) do
|
) do
|
||||||
if not is_nil(callback_fn) do
|
if not is_nil(callback_fn) do
|
||||||
callback_fn.(updated_connection)
|
callback_fn.(connection, updated_connection)
|
||||||
end
|
end
|
||||||
|
|
||||||
Impl.broadcast!(map_id, :update_connection, updated_connection)
|
Impl.broadcast!(map_id, :update_connection, updated_connection)
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ defmodule WandererApp.Map.Server.Impl do
|
|||||||
Process.send_after(self(), :update_characters, @update_characters_timeout)
|
Process.send_after(self(), :update_characters, @update_characters_timeout)
|
||||||
Process.send_after(self(), :update_tracked_characters, 100)
|
Process.send_after(self(), :update_tracked_characters, 100)
|
||||||
Process.send_after(self(), :update_presence, @update_presence_timeout)
|
Process.send_after(self(), :update_presence, @update_presence_timeout)
|
||||||
Process.send_after(self(), :cleanup_connections, 5000)
|
Process.send_after(self(), :cleanup_connections, 5_000)
|
||||||
Process.send_after(self(), :cleanup_systems, 10_000)
|
Process.send_after(self(), :cleanup_systems, 10_000)
|
||||||
Process.send_after(self(), :cleanup_characters, :timer.minutes(5))
|
Process.send_after(self(), :cleanup_characters, :timer.minutes(5))
|
||||||
Process.send_after(self(), :backup_state, @backup_state_timeout)
|
Process.send_after(self(), :backup_state, @backup_state_timeout)
|
||||||
@@ -359,9 +359,12 @@ defmodule WandererApp.Map.Server.Impl do
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
connections_eol_time =
|
connections =
|
||||||
map_id
|
map_id
|
||||||
|> WandererApp.Map.list_connections!()
|
|> WandererApp.Map.list_connections!()
|
||||||
|
|
||||||
|
connections_eol_time =
|
||||||
|
connections
|
||||||
|> Enum.reduce(%{}, fn %{id: connection_id} = _connection, acc ->
|
|> Enum.reduce(%{}, fn %{id: connection_id} = _connection, acc ->
|
||||||
case WandererApp.Cache.get("map_#{map_id}:conn_#{connection_id}:mark_eol_time") do
|
case WandererApp.Cache.get("map_#{map_id}:conn_#{connection_id}:mark_eol_time") do
|
||||||
nil ->
|
nil ->
|
||||||
@@ -372,10 +375,18 @@ defmodule WandererApp.Map.Server.Impl do
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
connections_start_time =
|
||||||
|
connections
|
||||||
|
|> Enum.reduce(%{}, fn %{id: connection_id} = _connection, acc ->
|
||||||
|
connection_start_time = ConnectionsImpl.get_start_time(map_id, connection_id)
|
||||||
|
acc |> Map.put_new(connection_id, connection_start_time)
|
||||||
|
end)
|
||||||
|
|
||||||
WandererApp.Api.MapState.create(%{
|
WandererApp.Api.MapState.create(%{
|
||||||
map_id: map_id,
|
map_id: map_id,
|
||||||
systems_last_activity: systems_last_activity,
|
systems_last_activity: systems_last_activity,
|
||||||
connections_eol_time: connections_eol_time
|
connections_eol_time: connections_eol_time,
|
||||||
|
connections_start_time: connections_start_time
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -396,10 +407,12 @@ defmodule WandererApp.Map.Server.Impl do
|
|||||||
{:ok,
|
{:ok,
|
||||||
%{
|
%{
|
||||||
systems_last_activity: systems_last_activity,
|
systems_last_activity: systems_last_activity,
|
||||||
connections_eol_time: connections_eol_time
|
connections_eol_time: connections_eol_time,
|
||||||
|
connections_start_time: connections_start_time
|
||||||
}} ->
|
}} ->
|
||||||
SystemsImpl.init_last_activity_cache(map_id, systems_last_activity)
|
SystemsImpl.init_last_activity_cache(map_id, systems_last_activity)
|
||||||
ConnectionsImpl.init_eol_cache(map_id, connections_eol_time)
|
ConnectionsImpl.init_eol_cache(map_id, connections_eol_time)
|
||||||
|
ConnectionsImpl.init_start_cache(map_id, connections_start_time)
|
||||||
|
|
||||||
state
|
state
|
||||||
|
|
||||||
|
|||||||
@@ -82,8 +82,7 @@ defmodule WandererAppWeb.MapEventHandler do
|
|||||||
]
|
]
|
||||||
|
|
||||||
@map_activity_ui_events [
|
@map_activity_ui_events [
|
||||||
"show_activity",
|
"show_activity"
|
||||||
"hide_activity"
|
|
||||||
]
|
]
|
||||||
|
|
||||||
@map_routes_events [
|
@map_routes_events [
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
defmodule WandererApp.Repo.Migrations.MapStateConnectionsStartTime do
|
||||||
|
@moduledoc """
|
||||||
|
Updates resources based on their most recent snapshots.
|
||||||
|
|
||||||
|
This file was autogenerated with `mix ash_postgres.generate_migrations`
|
||||||
|
"""
|
||||||
|
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def up do
|
||||||
|
alter table(:map_state_v1) do
|
||||||
|
add :connections_start_time, :binary
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
alter table(:map_state_v1) do
|
||||||
|
remove :connections_start_time
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
123
priv/resource_snapshots/repo/map_state_v1/20250313123433.json
Normal file
123
priv/resource_snapshots/repo/map_state_v1/20250313123433.json
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
{
|
||||||
|
"attributes": [
|
||||||
|
{
|
||||||
|
"allow_nil?": false,
|
||||||
|
"default": "fragment(\"gen_random_uuid()\")",
|
||||||
|
"generated?": false,
|
||||||
|
"primary_key?": true,
|
||||||
|
"references": null,
|
||||||
|
"size": null,
|
||||||
|
"source": "id",
|
||||||
|
"type": "uuid"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_nil?": true,
|
||||||
|
"default": "nil",
|
||||||
|
"generated?": false,
|
||||||
|
"primary_key?": false,
|
||||||
|
"references": null,
|
||||||
|
"size": null,
|
||||||
|
"source": "systems_last_activity",
|
||||||
|
"type": "binary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_nil?": true,
|
||||||
|
"default": "nil",
|
||||||
|
"generated?": false,
|
||||||
|
"primary_key?": false,
|
||||||
|
"references": null,
|
||||||
|
"size": null,
|
||||||
|
"source": "connections_start_time",
|
||||||
|
"type": "binary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_nil?": true,
|
||||||
|
"default": "nil",
|
||||||
|
"generated?": false,
|
||||||
|
"primary_key?": false,
|
||||||
|
"references": null,
|
||||||
|
"size": null,
|
||||||
|
"source": "connections_eol_time",
|
||||||
|
"type": "binary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_nil?": false,
|
||||||
|
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
|
||||||
|
"generated?": false,
|
||||||
|
"primary_key?": false,
|
||||||
|
"references": null,
|
||||||
|
"size": null,
|
||||||
|
"source": "inserted_at",
|
||||||
|
"type": "utc_datetime_usec"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_nil?": false,
|
||||||
|
"default": "fragment(\"(now() AT TIME ZONE 'utc')\")",
|
||||||
|
"generated?": false,
|
||||||
|
"primary_key?": false,
|
||||||
|
"references": null,
|
||||||
|
"size": null,
|
||||||
|
"source": "updated_at",
|
||||||
|
"type": "utc_datetime_usec"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_nil?": true,
|
||||||
|
"default": "nil",
|
||||||
|
"generated?": false,
|
||||||
|
"primary_key?": false,
|
||||||
|
"references": {
|
||||||
|
"deferrable": false,
|
||||||
|
"destination_attribute": "id",
|
||||||
|
"destination_attribute_default": null,
|
||||||
|
"destination_attribute_generated": null,
|
||||||
|
"index?": false,
|
||||||
|
"match_type": null,
|
||||||
|
"match_with": null,
|
||||||
|
"multitenancy": {
|
||||||
|
"attribute": null,
|
||||||
|
"global": null,
|
||||||
|
"strategy": null
|
||||||
|
},
|
||||||
|
"name": "map_state_v1_map_id_fkey",
|
||||||
|
"on_delete": null,
|
||||||
|
"on_update": null,
|
||||||
|
"primary_key?": true,
|
||||||
|
"schema": "public",
|
||||||
|
"table": "maps_v1"
|
||||||
|
},
|
||||||
|
"size": null,
|
||||||
|
"source": "map_id",
|
||||||
|
"type": "uuid"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"base_filter": null,
|
||||||
|
"check_constraints": [],
|
||||||
|
"custom_indexes": [],
|
||||||
|
"custom_statements": [],
|
||||||
|
"has_create_action": true,
|
||||||
|
"hash": "D554156984BC94421114631306D835FDF58CA4A3FFE70CCD436B9DA006F9A96E",
|
||||||
|
"identities": [
|
||||||
|
{
|
||||||
|
"all_tenants?": false,
|
||||||
|
"base_filter": null,
|
||||||
|
"index_name": "map_state_v1_uniq_map_id_index",
|
||||||
|
"keys": [
|
||||||
|
{
|
||||||
|
"type": "atom",
|
||||||
|
"value": "map_id"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "uniq_map_id",
|
||||||
|
"nils_distinct?": true,
|
||||||
|
"where": null
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"multitenancy": {
|
||||||
|
"attribute": null,
|
||||||
|
"global": null,
|
||||||
|
"strategy": null
|
||||||
|
},
|
||||||
|
"repo": "Elixir.WandererApp.Repo",
|
||||||
|
"schema": null,
|
||||||
|
"table": "map_state_v1"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user