Packages

Amazon Kinesis Data Firehose configurable queue supporting arbitrary adapters

Current section

Files

Jump to
firefighter lib execution.ex
Raw

lib/execution.ex

defmodule Firefighter.Execution do
require Logger
@type execution :: %__MODULE__{}
@callback start(data :: map) :: execution
@callback record(exec :: execution, data :: map) :: execution
@callback record_many(exec :: execution, name :: binary, data :: list | map) :: execution
@callback push(exec :: execution, pid :: any) :: execution
@callback hose(pid :: any, data :: map) :: execution
defstruct [
:event_uuid,
:event_time,
:elapsed,
data: %{}
]
def start(ids) do
%__MODULE__{
event_uuid: uuid(),
event_time: current_time(),
data: ids
}
end
def record(%__MODULE__{data: data} = execution, ids) do
%{execution | data: Map.merge(data, ids)}
end
def record_many(%__MODULE__{} = execution, name, list_of_ids) when is_list(list_of_ids) do
list_of_ids
|> Enum.reduce(execution, fn ids, end_execution ->
record_many(end_execution, name, ids)
end)
end
def record_many(%__MODULE__{data: data} = execution, name, ids) when is_map(ids) do
many = data[name] || []
data = Map.put(data, name, [ids | many])
%{execution | data: data}
end
def push(%__MODULE__{} = execution, id) when not is_pid(id) do
case Process.whereis(id) do
nil -> raise ArgumentError, "No process found for id #{id}"
pid -> push(execution, pid)
end
end
def push(execution, pid) when is_pid(pid) do
record = to_record(execution)
firefighter().push(pid, record)
execution
end
def hose(id, ids) do
start(ids) |> push(id)
end
defp to_record(%__MODULE__{event_uuid: event_uuid, event_time: event_time, data: data}) do
record =
%{
event_uuid: event_uuid,
event_time: event_time |> DateTime.to_iso8601(),
elapsed: DateTime.diff(current_time(), event_time)
}
|> Map.merge(data)
|> json().encode()
case record do
{:ok, json_string} ->
json_string
{:error, error} ->
Logger.error("Failed to JSON encode", error: error, record: inspect(record))
nil
end
end
defp uuid, do: UUID.uuid4()
defp current_time, do: DateTime.utc_now()
defp firefighter, do: Application.get_env(:firefighter, :firefighter, Firefighter)
defp json, do: Application.get_env(:firefighter, :json, Jason)
end