Files
bDS2/lib/bds/scripting/job_store.ex
2026-06-21 14:25:32 +02:00

66 lines
1.8 KiB
Elixir

defmodule BDS.Scripting.JobStore do
@moduledoc false
use Agent
@spec start_link(term()) :: Agent.on_start()
def start_link(_opts) do
Agent.start_link(fn -> %{jobs: %{}, runners: %{}} end, name: __MODULE__)
end
@spec put_job(map()) :: :ok
def put_job(job) when is_map(job) do
update_state(fn %{jobs: jobs} = state ->
%{state | jobs: Map.put(jobs, job.id, job)}
end)
end
@spec update_job(String.t(), map()) :: :ok
def update_job(job_id, attrs) when is_binary(job_id) and is_map(attrs) do
update_state(fn %{jobs: jobs} = state ->
next_jobs =
Map.update(jobs, job_id, nil, fn
nil -> nil
job -> Map.merge(job, attrs)
end)
%{state | jobs: next_jobs}
end)
end
@spec attach_runner(String.t(), pid()) :: :ok
def attach_runner(job_id, pid) when is_binary(job_id) and is_pid(pid) do
update_state(fn %{runners: runners} = state ->
%{state | runners: Map.put(runners, job_id, pid)}
end)
end
@spec detach_runner(String.t()) :: :ok
def detach_runner(job_id) when is_binary(job_id) do
update_state(fn %{runners: runners} = state ->
%{state | runners: Map.delete(runners, job_id)}
end)
end
@spec fetch_job(String.t()) :: map() | nil
def fetch_job(job_id) when is_binary(job_id) do
get_state(&Map.get(&1.jobs, job_id))
end
@spec fetch_job!(String.t()) :: map()
def fetch_job!(job_id) when is_binary(job_id) do
case fetch_job(job_id) do
nil -> raise KeyError, key: job_id, term: :jobs
job -> job
end
end
@spec runner_for(String.t()) :: pid() | nil
def runner_for(job_id) when is_binary(job_id) do
get_state(&Map.get(&1.runners, job_id))
end
defp get_state(fun), do: Agent.get(__MODULE__, fun)
defp update_state(fun), do: Agent.update(__MODULE__, fun)
end