defmodule SyntropyWeb.TasksLive do use SyntropyWeb, :live_view import SyntropyWeb.RuntimeViewHelpers alias Syntropy.{HistoryStore, RecommendationStore, TaskScheduler} @history_limit 20 @impl true def mount(_params, _session, socket) do if connected?(socket) do Phoenix.PubSub.subscribe(Syntropy.PubSub, "lattice:events") end {:ok, assign(socket, task_entries: build_task_entries(), active_runs: build_active_runs(), cancel_error: nil )} end @impl true def handle_info({:lattice_event, _event}, socket) do {:noreply, assign(socket, task_entries: build_task_entries(), active_runs: build_active_runs())} end @impl true def handle_event("cancel_run", %{"id" => run_id}, socket) do case TaskScheduler.cancel_run(run_id) do {:ok, _cancelled_run} -> {:noreply, assign(socket, cancel_error: nil, task_entries: build_task_entries(), active_runs: build_active_runs() )} {:error, reason} -> {:noreply, assign(socket, cancel_error: format_cancel_error(run_id, reason), active_runs: build_active_runs() )} end end @impl true def render(assigns) do ~H"""

Task history

Active and retained runs with selection evidence.

<%= if @active_runs != [] or @cancel_error do %>

Active runs

<%= if @cancel_error do %>

<%= @cancel_error %>

<% end %>
<% end %>

Task runs

<%= if @task_entries == [] do %>

No completed tasks yet.

<% else %> <% end %>
""" end defp build_active_runs do TaskScheduler.recent_runs(@history_limit) |> Enum.filter(&(&1.status in ["queued", "running"])) end defp format_cancel_error(run_id, :not_found), do: "Run #{run_id} was not found." defp format_cancel_error(run_id, :not_cancellable), do: "Run #{run_id} already reached a terminal state." defp build_task_entries do snapshots = HistoryStore.recent(@history_limit) snapshots_by_task_id = Map.new(snapshots, fn snapshot -> {snapshot.task_id, snapshot} end) recommendations = RecommendationStore.recent(@history_limit) recommendations_by_id = Map.new(recommendations, &{&1.id, &1}) Enum.map(TaskScheduler.recent(@history_limit), fn task -> %{ task: task, snapshot: Map.get(snapshots_by_task_id, task.task_id), recommendations: task.recommendation_ids |> Enum.map(&Map.get(recommendations_by_id, &1)) |> Enum.reject(&is_nil/1) } end) end defp graph_path(snapshot_id, agent_id) do params = %{} |> maybe_put("snapshot", snapshot_id) |> maybe_put("agent", agent_id) ~p"/?#{params}" end defp maybe_put(params, _key, nil), do: params defp maybe_put(params, key, value), do: Map.put(params, key, value) end