Compare commits

...

8 Commits

Author SHA1 Message Date
CI
cbadfc4ac4 chore: release version v1.62.4
Some checks failed
Build / 🚀 Deploy to test env (fly.io) (push) Has been cancelled
Build / Manual Approval (push) Has been cancelled
Build / 🛠 Build (1.17, 18.x, 27) (push) Has been cancelled
Build / 🛠 Build Docker Images (linux/amd64) (push) Has been cancelled
Build / 🛠 Build Docker Images (linux/arm64) (push) Has been cancelled
Build / merge (push) Has been cancelled
Build / 🏷 Create Release (push) Has been cancelled
2025-05-10 12:08:58 +00:00
Dmitry Popov
3d88ae4452 fix(Core): Fixed map characters got untracked 2025-05-10 13:46:49 +02:00
CI
6d99c54af7 chore: release version v1.62.3
Some checks failed
Build / 🚀 Deploy to test env (fly.io) (push) Has been cancelled
Build / Manual Approval (push) Has been cancelled
Build / 🛠 Build (1.17, 18.x, 27) (push) Has been cancelled
Build / 🛠 Build Docker Images (linux/amd64) (push) Has been cancelled
Build / 🛠 Build Docker Images (linux/arm64) (push) Has been cancelled
Build / merge (push) Has been cancelled
Build / 🏷 Create Release (push) Has been cancelled
2025-05-08 12:14:20 +00:00
Dmitry Popov
2b7901e9a8 Merge branch 'main' of github.com:wanderer-industries/wanderer 2025-05-08 12:20:14 +02:00
Dmitry Popov
fb06dd1dbc fix(Core): Fixed map characters got untracked 2025-05-08 12:20:09 +02:00
CI
f8ba36b8be chore: release version v1.62.2
Some checks failed
Build / 🚀 Deploy to test env (fly.io) (push) Has been cancelled
Build / Manual Approval (push) Has been cancelled
Build / 🛠 Build (1.17, 18.x, 27) (push) Has been cancelled
Build / 🛠 Build Docker Images (linux/amd64) (push) Has been cancelled
Build / 🛠 Build Docker Images (linux/arm64) (push) Has been cancelled
Build / merge (push) Has been cancelled
Build / 🏷 Create Release (push) Has been cancelled
2025-05-05 18:51:41 +00:00
Dmitry Popov
5bf9d99b3d Merge branch 'main' of github.com:wanderer-industries/wanderer 2025-05-05 20:32:17 +02:00
Dmitry Popov
7cad05342a fix(Core): Fixed audit export API 2025-05-05 20:32:14 +02:00
11 changed files with 152 additions and 132 deletions

View File

@@ -2,6 +2,33 @@
<!-- changelog -->
## [v1.62.4](https://github.com/wanderer-industries/wanderer/compare/v1.62.3...v1.62.4) (2025-05-10)
### Bug Fixes:
* Core: Fixed map characters got untracked
## [v1.62.3](https://github.com/wanderer-industries/wanderer/compare/v1.62.2...v1.62.3) (2025-05-08)
### Bug Fixes:
* Core: Fixed map characters got untracked
## [v1.62.2](https://github.com/wanderer-industries/wanderer/compare/v1.62.1...v1.62.2) (2025-05-05)
### Bug Fixes:
* Core: Fixed audit export API
## [v1.62.1](https://github.com/wanderer-industries/wanderer/compare/v1.62.0...v1.62.1) (2025-05-05)

View File

@@ -33,7 +33,7 @@ defmodule WandererApp.Character.Tracker do
status: binary()
}
@online_error_timeout :timer.minutes(2)
@online_error_timeout :timer.minutes(5)
@forbidden_ttl :timer.minutes(1)
@pubsub_client Application.compile_env(:wanderer_app, :pubsub_client)
@@ -49,7 +49,7 @@ defmodule WandererApp.Character.Tracker do
|> new()
end
def update_track_settings(character_id, track_settings) do
def update_settings(character_id, track_settings) do
{:ok, character_state} = WandererApp.Character.get_character_state(character_id)
{:ok,
@@ -494,7 +494,7 @@ defmodule WandererApp.Character.Tracker do
state,
location
) do
location = get_location(location)
location = get_location(location)
if not is_location_started?(character_id) do
WandererApp.Cache.lookup!("character:#{character_id}:start_solar_system_id", nil)
@@ -544,14 +544,18 @@ defmodule WandererApp.Character.Tracker do
)
defp is_location_updated?(
%{solar_system_id: new_solar_system_id, station_id: new_station_id, structure_id: new_structure_id} = _location,
%{
solar_system_id: new_solar_system_id,
station_id: new_station_id,
structure_id: new_structure_id
} = _location,
solar_system_id,
structure_id,
station_id
),
do:
solar_system_id != new_solar_system_id ||
solar_system_id != new_solar_system_id ||
solar_system_id != new_solar_system_id ||
structure_id != new_structure_id ||
station_id != new_station_id
@@ -724,14 +728,7 @@ defmodule WandererApp.Character.Tracker do
)
end
WandererApp.Character.update_character(character_id, %{online: false})
%{
state
| track_ship: false,
track_online: false,
track_location: false
}
state
end
defp maybe_stop_tracking(

View File

@@ -31,9 +31,7 @@ defmodule WandererApp.Character.TrackerManager do
def init(args) do
Logger.info("#{__MODULE__} started")
{:ok, tracked_characters} = WandererApp.Cache.lookup("tracked_characters", [])
{:ok, Impl.init(args |> Keyword.merge(characters: tracked_characters)), {:continue, :start}}
{:ok, Impl.init(args), {:continue, :start}}
end
@impl true

View File

@@ -32,71 +32,65 @@ defmodule WandererApp.Character.TrackerManager.Impl do
|> new()
end
def start(%{opts: opts} = state) do
opts[:characters]
|> Enum.reduce(state, fn character_id, acc ->
start_tracking(acc, character_id, %{})
def start(state) do
{:ok, tracked_characters} = WandererApp.Cache.lookup("tracked_characters", [])
tracked_characters
|> Enum.each(fn character_id ->
start_tracking(state, character_id, %{})
end)
state
end
def start_tracking(%__MODULE__{characters: characters} = state, character_id, opts) do
case Enum.member?(characters, character_id) do
true ->
state
def start_tracking(state, character_id, opts) do
with {:ok, characters} <- WandererApp.Cache.lookup("tracked_characters", []),
false <- Enum.member?(characters, character_id) do
Logger.debug(fn -> "Start character tracker: #{inspect(character_id)}" end)
false ->
Logger.debug(fn -> "Start character tracker: #{inspect(character_id)}" end)
tracked_characters = [character_id | characters] |> Enum.uniq()
WandererApp.Cache.insert("tracked_characters", tracked_characters)
WandererApp.TaskWrapper.start_link(WandererApp.Character, :update_character_state, [
character_id,
%{opts: opts}
])
WandererApp.Character.TrackerPoolDynamicSupervisor.start_tracking(character_id)
tracked_characters = [character_id | state.characters] |> Enum.uniq()
WandererApp.Cache.insert("tracked_characters", tracked_characters)
WandererApp.Character.TrackerPoolDynamicSupervisor.start_tracking(character_id)
%{state | characters: tracked_characters}
WandererApp.TaskWrapper.start_link(WandererApp.Character, :update_character_state, [
character_id,
%{opts: opts}
])
end
state
end
def stop_tracking(%__MODULE__{characters: characters} = state, character_id) do
case Enum.member?(characters, character_id) do
true ->
{:ok, character_state} = WandererApp.Character.get_character_state(character_id, false)
def stop_tracking(state, character_id) do
with {:ok, characters} <- WandererApp.Cache.lookup("tracked_characters", []),
true <- Enum.member?(characters, character_id),
{:ok, %{start_time: start_time}} <-
WandererApp.Character.get_character_state(character_id, false) do
Logger.debug(fn -> "Shutting down character tracker: #{inspect(character_id)}" end)
case character_state do
nil ->
state
WandererApp.Cache.delete("character:#{character_id}:last_active_time")
WandererApp.Cache.delete("character:#{character_id}:location_started")
WandererApp.Cache.delete("character:#{character_id}:start_solar_system_id")
WandererApp.Character.delete_character_state(character_id)
%{start_time: start_time} ->
duration = DateTime.diff(DateTime.utc_now(), start_time, :second)
tracked_characters =
characters |> Enum.reject(fn c_id -> c_id == character_id end)
:telemetry.execute([:wanderer_app, :character, :tracker, :running], %{
duration: duration
})
WandererApp.Cache.insert("tracked_characters", tracked_characters)
:telemetry.execute([:wanderer_app, :character, :tracker, :stopped], %{count: 1})
Logger.debug(fn -> "Shutting down character tracker: #{inspect(character_id)}" end)
WandererApp.Character.TrackerPoolDynamicSupervisor.stop_tracking(character_id)
WandererApp.Cache.delete("character:#{character_id}:location_started")
WandererApp.Cache.delete("character:#{character_id}:start_solar_system_id")
WandererApp.Character.delete_character_state(character_id)
duration = DateTime.diff(DateTime.utc_now(), start_time, :second)
tracked_characters =
state.characters |> Enum.reject(fn c_id -> c_id == character_id end)
:telemetry.execute([:wanderer_app, :character, :tracker, :running], %{
duration: duration
})
WandererApp.Cache.insert("tracked_characters", tracked_characters)
WandererApp.Character.TrackerPoolDynamicSupervisor.stop_tracking(character_id)
%{state | characters: tracked_characters}
end
false ->
state
:telemetry.execute([:wanderer_app, :character, :tracker, :stopped], %{count: 1})
end
state
end
def update_track_settings(
@@ -118,7 +112,7 @@ defmodule WandererApp.Character.TrackerManager.Impl do
)
{:ok, character_state} =
WandererApp.Character.Tracker.update_track_settings(character_id, track_settings)
WandererApp.Character.Tracker.update_settings(character_id, track_settings)
WandererApp.Character.update_character_state(character_id, character_state)
else
@@ -135,12 +129,12 @@ defmodule WandererApp.Character.TrackerManager.Impl do
end
def get_characters(
%{
characters: characters
} = state,
state,
_opts \\ []
),
do: {characters, state}
) do
{:ok, characters} = WandererApp.Cache.lookup("tracked_characters", [])
{characters, state}
end
def handle_event({ref, result}, state) do
Process.demonitor(ref, [:flush])
@@ -163,13 +157,12 @@ defmodule WandererApp.Character.TrackerManager.Impl do
def handle_info(
:garbage_collect,
%{
characters: characters
} =
state
state
) do
Process.send_after(self(), :garbage_collect, @garbage_collection_interval)
{:ok, characters} = WandererApp.Cache.lookup("tracked_characters", [])
characters
|> Task.async_stream(
fn character_id ->
@@ -213,15 +206,15 @@ defmodule WandererApp.Character.TrackerManager.Impl do
WandererApp.Cache.get_and_remove!("character_untrack_queue", [])
|> Task.async_stream(
fn {map_id, character_id} ->
WandererApp.Cache.delete("map_#{map_id}:character_#{character_id}:tracked")
if not character_is_present(map_id, character_id) do
{:ok, character_state} =
WandererApp.Character.Tracker.update_settings(character_id, %{
map_id: map_id,
track: false
})
{:ok, character_state} =
WandererApp.Character.Tracker.update_track_settings(character_id, %{
map_id: map_id,
track: false
})
WandererApp.Character.update_character_state(character_id, character_state)
WandererApp.Character.update_character_state(character_id, character_state)
end
end,
max_concurrency: System.schedulers_online(),
on_timeout: :kill_task,
@@ -233,21 +226,23 @@ defmodule WandererApp.Character.TrackerManager.Impl do
end
def handle_info({:stop_track, character_id}, state) do
WandererApp.Cache.has_key?("character:#{character_id}:is_stop_tracking")
|> case do
false ->
WandererApp.Cache.insert("character:#{character_id}:is_stop_tracking", true)
Logger.debug(fn -> "Stopping character tracker: #{inspect(character_id)}" end)
state = state |> stop_tracking(character_id)
WandererApp.Cache.delete("character:#{character_id}:is_stop_tracking")
state
_ ->
state
if not WandererApp.Cache.has_key?("character:#{character_id}:is_stop_tracking") do
WandererApp.Cache.insert("character:#{character_id}:is_stop_tracking", true)
Logger.debug(fn -> "Stopping character tracker: #{inspect(character_id)}" end)
stop_tracking(state, character_id)
WandererApp.Cache.delete("character:#{character_id}:is_stop_tracking")
end
state
end
def handle_info(_event, state),
do: state
defp character_is_present(map_id, character_id) do
{:ok, presence_character_ids} =
WandererApp.Cache.lookup("map_#{map_id}:presence_character_ids", [])
Enum.member?(presence_character_ids, character_id)
end
end

View File

@@ -167,10 +167,18 @@ defmodule WandererApp.Character.TrackerPool do
def handle_info(
:update_online,
state
%{
characters: characters
} =
state
) do
Process.send_after(self(), :update_online, @update_online_interval)
characters
|> Enum.each(fn character_id ->
WandererApp.Character.update_character(character_id, %{online: false})
end)
{:noreply, state}
end

View File

@@ -120,7 +120,7 @@ defmodule WandererApp.Character.TrackingUtils do
{:ok, updated_settings} =
WandererApp.MapCharacterSettingsRepo.untrack(existing_settings)
:ok = untrack_characters([character], map_id, caller_pid)
:ok = untrack([character], map_id, caller_pid)
:ok = remove_characters([character], map_id)
{:ok, updated_settings}
else
@@ -131,7 +131,7 @@ defmodule WandererApp.Character.TrackingUtils do
{:ok, %{tracked: false} = existing_settings} ->
if track do
{:ok, updated_settings} = WandererApp.MapCharacterSettingsRepo.track(existing_settings)
:ok = track_characters([character], map_id, true, caller_pid)
:ok = track([character], map_id, true, caller_pid)
:ok = add_characters([character], map_id, true)
{:ok, updated_settings}
else
@@ -148,7 +148,7 @@ defmodule WandererApp.Character.TrackingUtils do
tracked: true
})
:ok = track_characters([character], map_id, true, caller_pid)
:ok = track([character], map_id, true, caller_pid)
:ok = add_characters([character], map_id, true)
{:ok, settings}
else
@@ -161,25 +161,23 @@ defmodule WandererApp.Character.TrackingUtils do
end
# Helper functions for character tracking
def track_characters(_, _, false, _), do: :ok
def track_characters([], _map_id, _is_track_character?, _), do: :ok
def track(_, _, false, _), do: :ok
def track([], _map_id, _is_track_character?, _), do: :ok
def track_characters([character | characters], map_id, true, caller_pid) do
def track([character | characters], map_id, true, caller_pid) do
with :ok <- track_character(character, map_id, caller_pid) do
track_characters(characters, map_id, true, caller_pid)
track(characters, map_id, true, caller_pid)
end
end
def track_character(
%{
id: character_id,
eve_id: eve_id,
corporation_id: corporation_id,
alliance_id: alliance_id
},
map_id,
caller_pid
) do
defp track_character(
%{
id: character_id,
eve_id: eve_id
},
map_id,
caller_pid
) do
with false <- is_nil(caller_pid) do
WandererAppWeb.Presence.track(caller_pid, map_id, character_id, %{})
@@ -202,20 +200,17 @@ defmodule WandererApp.Character.TrackingUtils do
end
end
def untrack_characters(characters, map_id, caller_pid) do
def untrack(characters, map_id, caller_pid) do
with false <- is_nil(caller_pid) do
character_ids = characters |> Enum.map(& &1.id)
characters
|> Enum.each(fn character ->
WandererAppWeb.Presence.untrack(caller_pid, map_id, character.id)
WandererApp.Cache.put(
"#{inspect(caller_pid)}_map_#{map_id}:character_#{character.id}:tracked",
false
)
:ok = Phoenix.PubSub.unsubscribe(WandererApp.PubSub, "character:#{character.eve_id}")
end)
WandererApp.Map.Server.untrack_characters(map_id, character_ids)
:ok
else
true ->

View File

@@ -32,7 +32,7 @@ defmodule WandererApp.Esi.ApiClient do
}
@cache_opts [cache: true]
@retry_opts [max_retries: 1, retry_log_level: :warning]
@retry_opts [max_retries: 0, retry_log_level: :warning]
@timeout_opts [pool_timeout: 15_000, receive_timeout: :timer.seconds(30)]
@api_retry_count 1
@@ -490,7 +490,11 @@ defmodule WandererApp.Esi.ApiClient do
try do
case Req.get(
"#{@base_url}#{path}",
api_opts |> with_user_agent_opts() |> with_cache_opts() |> Keyword.merge(@retry_opts) |> Keyword.merge(@timeout_opts)
api_opts
|> with_user_agent_opts()
|> with_cache_opts()
|> Keyword.merge(@retry_opts)
|> Keyword.merge(@timeout_opts)
) do
{:ok, %{status: 200, body: body}} ->
{:ok, body}

View File

@@ -335,7 +335,7 @@ defmodule WandererAppWeb.MapCharactersEventHandler do
defp handle_tracking_event({:track_characters, map_characters, track_character}, socket, map_id) do
:ok =
WandererApp.Character.TrackingUtils.track_characters(
WandererApp.Character.TrackingUtils.track(
map_characters,
map_id,
track_character,

View File

@@ -56,18 +56,12 @@ defmodule WandererAppWeb.MapCoreEventHandler do
case track_character do
false ->
:ok =
WandererApp.Character.TrackingUtils.untrack_characters(
map_characters,
map_id,
self()
)
:ok = WandererApp.Character.TrackingUtils.untrack(map_characters, map_id, self())
:ok = WandererApp.Character.TrackingUtils.remove_characters(map_characters, map_id)
_ ->
:ok =
WandererApp.Character.TrackingUtils.track_characters(
WandererApp.Character.TrackingUtils.track(
map_characters,
map_id,
true,

View File

@@ -291,6 +291,8 @@ defmodule WandererAppWeb.MapEventHandler do
def push_map_event(socket, _type, _body), do: socket
def map_ui_character_stat(nil), do: nil
def map_ui_character_stat(character),
do:
character

View File

@@ -3,7 +3,7 @@ defmodule WandererApp.MixProject do
@source_url "https://github.com/wanderer-industries/wanderer"
@version "1.62.1"
@version "1.62.4"
def project do
[