diff --git a/lib/beet_round_server/bidding_rounds.ex b/lib/beet_round_server/bidding_rounds.ex index b1613ce..f230afb 100644 --- a/lib/beet_round_server/bidding_rounds.ex +++ b/lib/beet_round_server/bidding_rounds.ex @@ -37,6 +37,27 @@ defmodule BeetRoundServer.BiddingRounds do """ def get_bidding_round!(id), do: Repo.get!(BiddingRound, id) + def get_highest_bidding_round!() do + query = + Ecto.Query.from(bidding_round in BiddingRound, + order_by: [desc: bidding_round.round_number], + limit: 1 + ) + + Repo.one(query) + end + + def get_bidding_round_by_number!(round_number) do + query = + Ecto.Query.from(bidding_round in BiddingRound, + where: bidding_round.round_number == ^round_number, + order_by: [desc: bidding_round.inserted_at], + limit: 1 + ) + + Repo.one(query) + end + @doc """ Creates a bidding_round. diff --git a/lib/beet_round_server/bidding_rounds/bidding_round_facade.ex b/lib/beet_round_server/bidding_rounds/bidding_round_facade.ex new file mode 100644 index 0000000..b036285 --- /dev/null +++ b/lib/beet_round_server/bidding_rounds/bidding_round_facade.ex @@ -0,0 +1,118 @@ +defmodule BeetRoundServer.BiddingRounds.BiddingRoundFacade do + alias BeetRoundServer.BiddingRounds.BiddingRound + alias BeetRoundServer.BiddingRounds + alias BeetRoundServer.BiddingRounds.BiddingRoundServer + + def restart_if_necessary() do + last_round = get_highest_bidding_round() + + if last_round.stopped == false do + IO.puts("There is a last round, that wasn't stopped. Should be running...") + + if !isAlive() do + IO.puts("...but it isn't. Restarting last round...") + restart_hightest_round() + end + end + end + + def get_highest_bidding_round() do + last_round = BiddingRounds.get_highest_bidding_round!() + + if last_round != nil do + last_round + else + %BiddingRound{round_number: 0, stopped: true, id: "00000000-0000-0000-0000-000000000000"} + end + end + + def get_current_round do + restart_if_necessary() + + if GenServer.whereis(CurrentRoundServer) == nil do + IO.puts("CurrentRoundServer isn't alive. Returning 0...") + # %BiddingRound{round_number: 0, stopped: true, id: "00000000-0000-0000-0000-000000000000"} + 0 + else + GenServer.call(CurrentRoundServer, :val) + end + end + + def start_new_round() do + if isAlive() do + IO.puts("CurrentRoundServer is alive! Please stop the server before starting a new round") + {:error, "A current round is running! Please stop it, before starting a new round."} + else + IO.puts("CurrentRoundServer isn't alive. Starting instance...") + + last_round = BiddingRounds.get_highest_bidding_round!() + + cond do + last_round == nil -> + IO.puts("No bidding round found. Starting first round...") + + round_number = 1 + + BiddingRoundServer.start(round_number) + BiddingRounds.create_bidding_round(%{round_number: round_number}) + + last_round.stopped == false -> + IO.puts("Last bidding round not stopped. Restarting round...") + + BiddingRoundServer.start(last_round.round_number) + + true -> + IO.puts("Last bidding round has stopped. Starting a new round...") + + round_number = last_round.round_number + 1 + + BiddingRoundServer.start(round_number) + BiddingRounds.create_bidding_round(%{round_number: round_number}) + end + end + end + + def restart_hightest_round() do + IO.puts("Restarting hightest round...") + + if isAlive() do + IO.puts("Server is alive. Nothing to do...") + IO.puts(["Current round: ", GenServer.call(CurrentRoundServer, :val)]) + else + IO.puts("Server isn't alive. Trying to restart last round.") + + last_round = BiddingRounds.get_highest_bidding_round!() + + cond do + last_round == nil -> + IO.puts("No bidding round found! Can't restart round...") + {:error, "No bidding round found! Nothing to restart."} + + true -> + IO.puts("Last bidding round found. Restarting...") + + BiddingRoundServer.start(last_round.round_number) + BiddingRounds.update_bidding_round(last_round, %{stopped: false}) + end + end + end + + def stop_current_round() do + IO.puts("Stopping current round...") + + if isAlive() do + IO.puts("Server is alive. Shutting down and writing to DB...") + current_round_number = GenServer.call(CurrentRoundServer, :val) + GenServer.stop(CurrentRoundServer) + + current_round = BiddingRounds.get_bidding_round_by_number!(current_round_number) + BiddingRounds.update_bidding_round(current_round, %{stopped: true}) + else + IO.puts("Server isn't alive. Nothing to shut down.") + end + end + + def isAlive() do + GenServer.whereis(CurrentRoundServer) != nil + end +end diff --git a/lib/beet_round_server/bidding_rounds/bidding_round_server.ex b/lib/beet_round_server/bidding_rounds/bidding_round_server.ex new file mode 100644 index 0000000..af40265 --- /dev/null +++ b/lib/beet_round_server/bidding_rounds/bidding_round_server.ex @@ -0,0 +1,39 @@ +defmodule BeetRoundServer.BiddingRounds.BiddingRoundServer do + use GenServer + def inc(pid), do: GenServer.cast(pid, :inc) + def dec(pid), do: GenServer.cast(pid, :dec) + + def val(pid) do + GenServer.call(pid, :val) + end + + def stop(pid) do + GenServer.stop(pid) + end + + def start(initial_val) do + GenServer.start(__MODULE__, initial_val, name: CurrentRoundServer) + end + + def init(initial_val) do + {:ok, initial_val} + end + + def terminate(_reason, val) do + IO.puts("Stopping bidding round:") + IO.puts(val) + :ok + end + + def handle_cast(:inc, val) do + {:noreply, val + 1} + end + + def handle_cast(:dec, val) do + {:noreply, val - 1} + end + + def handle_call(:val, _from, val) do + {:reply, val, val} + end +end diff --git a/lib/beet_round_server_web/controllers/bidding_round_controller.ex b/lib/beet_round_server_web/controllers/bidding_round_controller.ex index 0b884bb..c228dfc 100644 --- a/lib/beet_round_server_web/controllers/bidding_round_controller.ex +++ b/lib/beet_round_server_web/controllers/bidding_round_controller.ex @@ -3,22 +3,62 @@ defmodule BeetRoundServerWeb.BiddingRoundController do alias BeetRoundServer.BiddingRounds alias BeetRoundServer.BiddingRounds.BiddingRound + alias BeetRoundServer.BiddingRounds.BiddingRoundFacade action_fallback BeetRoundServerWeb.FallbackController + def get_highest(conn, _params) do + BiddingRoundFacade.restart_if_necessary() + + last_round = BiddingRoundFacade.get_highest_bidding_round() + + conn + |> render(:show, bidding_round: last_round) + end + + def start_new(conn, _params) do + BiddingRoundFacade.start_new_round() + + current_round = BiddingRounds.get_highest_bidding_round!() + + conn + |> put_status(:created) + |> render(:show, bidding_round: current_round) + end + + def restart(conn, _params) do + BiddingRoundFacade.restart_hightest_round() + + current_round = BiddingRounds.get_highest_bidding_round!() + + conn + |> put_status(:created) + |> render(:show, bidding_round: current_round) + end + + def stop(conn, _params) do + BiddingRoundFacade.stop_current_round() + + stopped_round = BiddingRounds.get_highest_bidding_round!() + + conn + |> render(:show, bidding_round: stopped_round) + end + def index(conn, _params) do bidding_rounds = BiddingRounds.list_bidding_rounds() render(conn, :index, bidding_rounds: bidding_rounds) end - def create(conn, %{"bidding_round" => bidding_round_params}) do - with {:ok, %BiddingRound{} = bidding_round} <- BiddingRounds.create_bidding_round(bidding_round_params) do - conn - |> put_status(:created) - |> put_resp_header("location", ~p"/api/bidding_rounds/#{bidding_round}") - |> render(:show, bidding_round: bidding_round) - end - end + # def create(conn, %{"bidding_round" => bidding_round_params}) do + # with {:ok, %BiddingRound{} = bidding_round} <- + # BiddingRounds.create_bidding_round(bidding_round_params) do + # conn + # |> put_status(:created) + # |> put_resp_header("location", ~p"/api/bidding_rounds/#{bidding_round}") + # |> render(:show, bidding_round: bidding_round) + # end + # end def show(conn, %{"id" => id}) do bidding_round = BiddingRounds.get_bidding_round!(id) @@ -28,7 +68,8 @@ defmodule BeetRoundServerWeb.BiddingRoundController do def update(conn, %{"id" => id, "bidding_round" => bidding_round_params}) do bidding_round = BiddingRounds.get_bidding_round!(id) - with {:ok, %BiddingRound{} = bidding_round} <- BiddingRounds.update_bidding_round(bidding_round, bidding_round_params) do + with {:ok, %BiddingRound{} = bidding_round} <- + BiddingRounds.update_bidding_round(bidding_round, bidding_round_params) do render(conn, :show, bidding_round: bidding_round) end end diff --git a/lib/beet_round_server_web/live/bidding_live/index.ex b/lib/beet_round_server_web/live/bidding_live/index.ex index c7f1af2..16c9042 100644 --- a/lib/beet_round_server_web/live/bidding_live/index.ex +++ b/lib/beet_round_server_web/live/bidding_live/index.ex @@ -2,6 +2,7 @@ defmodule BeetRoundServerWeb.BiddingLive.Index do use BeetRoundServerWeb, :live_view alias BeetRoundServer.Biddings + alias BeetRoundServer.BiddingRounds.BiddingRoundFacade @impl true def render(assigns) do @@ -16,6 +17,12 @@ defmodule BeetRoundServerWeb.BiddingLive.Index do + <%= if @bidding_round == 0 do %> +
Keine Bietrunde aktiv.
+ <% else %> +Aktive Bietrunde: {@bidding_round}
+ <% end %> + <.table id="biddings" rows={@streams.biddings} @@ -50,9 +57,12 @@ defmodule BeetRoundServerWeb.BiddingLive.Index do Biddings.subscribe_biddings(socket.assigns.current_scope) end + current_round = BiddingRoundFacade.get_current_round() + {:ok, socket |> assign(:page_title, "Listing Biddings") + |> assign(bidding_round: current_round) |> stream(:biddings, list_biddings(socket.assigns.current_scope))} end @@ -67,7 +77,8 @@ defmodule BeetRoundServerWeb.BiddingLive.Index do @impl true def handle_info({type, %BeetRoundServer.Biddings.Bidding{}}, socket) when type in [:created, :updated, :deleted] do - {:noreply, stream(socket, :biddings, list_biddings(socket.assigns.current_scope), reset: true)} + {:noreply, + stream(socket, :biddings, list_biddings(socket.assigns.current_scope), reset: true)} end defp list_biddings(current_scope) do