From 7d24e56bd9d0123ff2bd5fcfc4ba3825b5246553 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Sun, 22 Mar 2026 16:47:17 -0500 Subject: [PATCH] fix: wrap Gaiia sync upserts in transaction and remove stale device_role_source ref (#118) - Wrap upsert_nodes in Repo.transaction so all upserts share one DB connection, preventing pool exhaustion under load - Remove stale device_role_source reference from form test Reviewed-on: https://git.mcintire.me/graham/towerops-web/pulls/118 --- lib/towerops/gaiia/sync.ex | 16 ++++++++++++++-- test/towerops_web/live/device_live/form_test.exs | 3 +-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/towerops/gaiia/sync.ex b/lib/towerops/gaiia/sync.ex index 767e8812..7627faab 100644 --- a/lib/towerops/gaiia/sync.ex +++ b/lib/towerops/gaiia/sync.ex @@ -11,6 +11,7 @@ defmodule Towerops.Gaiia.Sync do alias Towerops.Gaiia.Client alias Towerops.Gaiia.SubscriberMatching alias Towerops.Integrations + alias Towerops.Repo require Logger @@ -57,13 +58,24 @@ defmodule Towerops.Gaiia.Sync do end defp upsert_nodes(org_id, nodes, type) do + case Repo.transaction(fn -> do_upsert_nodes(org_id, nodes, type) end) do + {:ok, count} -> + count + + {:error, reason} -> + Logger.error("Gaiia #{type} upsert transaction failed: #{inspect(reason)}") + 0 + end + end + + defp do_upsert_nodes(org_id, nodes, type) do Enum.reduce(nodes, 0, fn node, count -> case upsert_node(org_id, node, type) do {:ok, _} -> count + 1 - {:error, changeset} -> - Logger.warning("Failed to upsert Gaiia #{type}: #{inspect(changeset.errors)}") + {:error, cs} -> + Logger.warning("Failed to upsert Gaiia #{type}: #{inspect(cs.errors)}") count end end) diff --git a/test/towerops_web/live/device_live/form_test.exs b/test/towerops_web/live/device_live/form_test.exs index 6adc2159..4152c571 100644 --- a/test/towerops_web/live/device_live/form_test.exs +++ b/test/towerops_web/live/device_live/form_test.exs @@ -336,8 +336,7 @@ defmodule ToweropsWeb.DeviceLive.FormTest do site_id: site.id, organization_id: organization.id, snmp_enabled: true, - device_role: "router", - device_role_source: "manual" + device_role: "router" }) {:ok, _view, html} = live(conn, ~p"/devices/#{device.id}/edit")