feat: tasks hooked up to UI

This commit is contained in:
2026-04-25 10:42:07 +02:00
parent 26d4954724
commit 59be6c213e
6 changed files with 437 additions and 107 deletions

View File

@@ -5,6 +5,7 @@ defmodule BDS.Tasks do
@default_max_concurrent 3
@default_progress_throttle_ms 250
@default_recent_finished_limit 10
def start_link(_opts) do
GenServer.start_link(__MODULE__, %{}, name: __MODULE__)
@@ -35,6 +36,10 @@ defmodule BDS.Tasks do
GenServer.call(__MODULE__, :clear_completed)
end
def clear_finished do
GenServer.call(__MODULE__, :clear_finished)
end
def cancel_task(task_id) when is_binary(task_id) do
GenServer.call(__MODULE__, {:cancel_task, task_id})
end
@@ -104,6 +109,15 @@ defmodule BDS.Tasks do
{:reply, :ok, %{state | tasks: next_tasks}}
end
def handle_call(:clear_finished, _from, state) do
next_tasks =
state.tasks
|> Enum.reject(fn {_task_id, task} -> task.status in [:completed, :failed, :cancelled] end)
|> Map.new()
{:reply, :ok, %{state | tasks: next_tasks}}
end
def handle_call({:cancel_task, task_id}, _from, state) do
cond do
Map.has_key?(state.running, task_id) ->
@@ -340,14 +354,15 @@ defmodule BDS.Tasks do
end
defp build_status_snapshot(state) do
tasks = active_tasks(state)
active = active_tasks(state)
tasks = active ++ recent_finished_tasks(state)
%{
active_count: length(tasks),
running_count: Enum.count(tasks, &(&1.status == :running)),
pending_count: Enum.count(tasks, &(&1.status == :pending)),
running_task_message: running_task_message(tasks),
running_task_overflow: running_task_overflow(tasks),
active_count: length(active),
running_count: Enum.count(active, &(&1.status == :running)),
pending_count: Enum.count(active, &(&1.status == :pending)),
running_task_message: running_task_message(active),
running_task_overflow: running_task_overflow(active),
tasks: Enum.map(tasks, &public_task/1)
}
end
@@ -359,6 +374,14 @@ defmodule BDS.Tasks do
|> Enum.sort_by(&task_sort_key/1)
end
defp recent_finished_tasks(state) do
state.tasks
|> Map.values()
|> Enum.filter(&(&1.status in [:completed, :failed, :cancelled]))
|> Enum.sort_by(&DateTime.to_unix(&1.finished_at || &1.created_at, :microsecond), :desc)
|> Enum.take(recent_finished_limit())
end
defp all_tasks(state) do
state.tasks
|> Map.values()
@@ -406,6 +429,11 @@ defmodule BDS.Tasks do
|> Keyword.get(:progress_throttle_ms, @default_progress_throttle_ms)
end
defp recent_finished_limit do
Application.get_env(:bds, :tasks, [])
|> Keyword.get(:recent_finished_limit, @default_recent_finished_limit)
end
defp attr(attrs, key) do
cond do
Map.has_key?(attrs, key) -> Map.get(attrs, key)