defmodule ResultsServer do require Logger use GenServer @moduledoc """ Genserver with data: %{results => %{filename->FileResult, filename2->FileResult}, good => [filename1, filename2], bad => [badfiles]} """ # Client # def start_link(initial_values) do GenServer.start_link(__MODULE__, initial_values, name: ResultsServer) end @impl true def init(initial_values) do {:ok, initial_values} end def put_result(file_result) do GenServer.cast(ResultsServer, {:put_result, file_result}) end def print_results() do GenServer.cast(ResultsServer, :print_results) end def reset() do GenServer.cast(ResultsServer, :reset) end # Server @impl true def handle_cast({:put_result, file_result}, current_state) do filename = file_result.filename chunks = file_result.chunks Logger.debug("Got result: #{inspect(filename)}") {new_state, status} = case chunks do [] -> {Map.put(current_state, :bad, current_state.bad ++ [filename]), :bad} _ -> new_state = Map.put(current_state, :good, current_state.good ++ [filename]) results = new_state.results new_results = Map.put(results, filename, file_result) {Map.put(new_state, :results, new_results), :good} end done_files = new_state.bad ++ new_state.good {:ok, all_files} = FileProcessor.get_files() remaining = all_files -- done_files p = length(done_files)/length(all_files) Phoenix.PubSub.broadcast(TrustedEdgeServer.PubSub, "the_topic", {:new_result, {filename, status}}) Phoenix.PubSub.broadcast(TrustedEdgeServer.PubSub, "the_topic", {:new_percent_done, p}) Logger.info("Percent done: #{p}") Logger.info("Remaining: #{inspect(remaining)}") {:noreply, new_state} end @impl true def handle_cast(:print_results, current_state) do good = current_state.good bad = current_state.bad results = current_state.results Logger.debug("Good: #{inspect(good)}") Logger.debug("Bad: #{inspect(bad)}") Enum.each(results, fn {key, value} -> Logger.debug("File: #{key}") Logger.debug("Chunks: #{inspect(value.chunks)}") end) {:noreply, current_state} end @impl true def handle_cast(:reset, current_state) do {:noreply, %{:results=>%{}, :good=>[], :bad=>[]}} end end