diff --git a/lib/towerops/api_tokens.ex b/lib/towerops/api_tokens.ex index 99a31c4e..39f68bf9 100644 --- a/lib/towerops/api_tokens.ex +++ b/lib/towerops/api_tokens.ex @@ -172,28 +172,37 @@ defmodule Towerops.ApiTokens do end defp update_last_used(token) do + timestamp = DateTime.truncate(DateTime.utc_now(), :second) + # In test mode, update synchronously to avoid ownership issues # In production, use Task.start to avoid blocking the request - if Application.get_env(:towerops, :env) == :test do - token - |> Ecto.Changeset.change(last_used_at: DateTime.truncate(DateTime.utc_now(), :second)) - |> Repo.update() - else - # Get the parent process PID before spawning the task - parent = self() + case Application.get_env(:towerops, :env) do + :test -> + update_token_timestamp(token, timestamp) - # Use Task.start to avoid blocking the request - # We don't care if this fails - Task.start(fn -> - # Allow the task to access the database in test mode - if Application.get_env(:towerops, :sql_sandbox) do - Ecto.Adapters.SQL.Sandbox.allow(Repo, parent, self()) - end + _ -> + spawn_async_update(token, timestamp) + end + end - token - |> Ecto.Changeset.change(last_used_at: DateTime.truncate(DateTime.utc_now(), :second)) - |> Repo.update() - end) + defp update_token_timestamp(token, timestamp) do + token + |> Ecto.Changeset.change(last_used_at: timestamp) + |> Repo.update() + end + + defp spawn_async_update(token, timestamp) do + parent = self() + + Task.start(fn -> + maybe_allow_sandbox(parent) + update_token_timestamp(token, timestamp) + end) + end + + defp maybe_allow_sandbox(parent) do + if Application.get_env(:towerops, :sql_sandbox) do + Ecto.Adapters.SQL.Sandbox.allow(Repo, parent, self()) end end end