refactor: reduce nesting depth in regenerate_cycles_on_type_change
Split the function into smaller, focused functions to reduce nesting depth
This commit is contained in:
parent
2f83f35bcc
commit
3fad912025
1 changed files with 29 additions and 17 deletions
|
|
@ -705,7 +705,6 @@ defmodule Mv.Membership.Member do
|
||||||
# Deletes future unpaid cycles and regenerates them with the new type/amount
|
# Deletes future unpaid cycles and regenerates them with the new type/amount
|
||||||
# Uses advisory lock to prevent concurrent modifications
|
# Uses advisory lock to prevent concurrent modifications
|
||||||
defp regenerate_cycles_on_type_change(member) do
|
defp regenerate_cycles_on_type_change(member) do
|
||||||
require Ash.Query
|
|
||||||
alias Mv.Repo
|
alias Mv.Repo
|
||||||
|
|
||||||
today = Date.utc_today()
|
today = Date.utc_today()
|
||||||
|
|
@ -714,26 +713,39 @@ defmodule Mv.Membership.Member do
|
||||||
# Use advisory lock to prevent concurrent deletion and regeneration
|
# Use advisory lock to prevent concurrent deletion and regeneration
|
||||||
# This ensures atomicity when multiple updates happen simultaneously
|
# This ensures atomicity when multiple updates happen simultaneously
|
||||||
if Repo.in_transaction?() do
|
if Repo.in_transaction?() do
|
||||||
# Already in transaction: use advisory lock directly
|
regenerate_cycles_in_transaction(member, today, lock_key)
|
||||||
Ecto.Adapters.SQL.query!(Repo, "SELECT pg_advisory_xact_lock($1)", [lock_key])
|
|
||||||
do_regenerate_cycles_on_type_change(member, today)
|
|
||||||
else
|
else
|
||||||
# Not in transaction: start new transaction with advisory lock
|
regenerate_cycles_new_transaction(member, today, lock_key)
|
||||||
Repo.transaction(fn ->
|
|
||||||
Ecto.Adapters.SQL.query!(Repo, "SELECT pg_advisory_xact_lock($1)", [lock_key])
|
|
||||||
|
|
||||||
case do_regenerate_cycles_on_type_change(member, today) do
|
|
||||||
:ok -> :ok
|
|
||||||
{:error, reason} -> Repo.rollback(reason)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|> case do
|
|
||||||
{:ok, result} -> result
|
|
||||||
{:error, reason} -> {:error, reason}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Already in transaction: use advisory lock directly
|
||||||
|
defp regenerate_cycles_in_transaction(member, today, lock_key) do
|
||||||
|
alias Mv.Repo
|
||||||
|
|
||||||
|
Ecto.Adapters.SQL.query!(Repo, "SELECT pg_advisory_xact_lock($1)", [lock_key])
|
||||||
|
do_regenerate_cycles_on_type_change(member, today)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Not in transaction: start new transaction with advisory lock
|
||||||
|
defp regenerate_cycles_new_transaction(member, today, lock_key) do
|
||||||
|
alias Mv.Repo
|
||||||
|
|
||||||
|
Repo.transaction(fn ->
|
||||||
|
Ecto.Adapters.SQL.query!(Repo, "SELECT pg_advisory_xact_lock($1)", [lock_key])
|
||||||
|
|
||||||
|
case do_regenerate_cycles_on_type_change(member, today) do
|
||||||
|
:ok -> :ok
|
||||||
|
{:error, reason} -> Repo.rollback(reason)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|> handle_transaction_result()
|
||||||
|
end
|
||||||
|
|
||||||
|
# Handle transaction result
|
||||||
|
defp handle_transaction_result({:ok, result}), do: result
|
||||||
|
defp handle_transaction_result({:error, reason}), do: {:error, reason}
|
||||||
|
|
||||||
# Performs the actual cycle deletion and regeneration
|
# Performs the actual cycle deletion and regeneration
|
||||||
defp do_regenerate_cycles_on_type_change(member, today) do
|
defp do_regenerate_cycles_on_type_change(member, today) do
|
||||||
require Ash.Query
|
require Ash.Query
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue