Packages

Librería base para ejecución de comandos del sistema y gestión de tareas asíncronas con resultados estructurados.

Retired package: Release invalid - Versión publicada por error

Current section

Files

Jump to
argos lib parallel worker_state.ex
Raw

lib/parallel/worker_state.ex

defmodule Argos.Parallel.WorkerState do
@moduledoc """
Estructura de datos que representa el estado de un worker paralelo.
Contiene identificador, estado, progreso, tiempos, resultados y errores.
"""
@type status :: :started | :running | :finished | :error | :failed_to_start
@type result :: %{task_index: integer(), result: any(), timestamp: DateTime.t()}
@type t :: %__MODULE__{
id: any(),
status: status(),
progress: number() | nil,
total: integer() | nil,
current_task: integer() | nil,
started_at: DateTime.t() | nil,
finished_at: DateTime.t() | nil,
results: [result()],
error: any() | nil,
error_task: integer() | nil,
last_update: DateTime.t() | nil
}
defstruct [
:id,
:status,
:progress,
:total,
:current_task,
:started_at,
:finished_at,
:error,
:error_task,
:last_update,
results: []
]
@doc """
Crea un nuevo WorkerState con estado :started
"""
def new(id) do
%__MODULE__{
id: id,
status: :started,
started_at: DateTime.utc_now(),
last_update: DateTime.utc_now()
}
end
@doc """
Actualiza el estado a :running con información de progreso
"""
def running(%__MODULE__{} = state, progress, total, task_index) do
%__MODULE__{
state
| status: :running,
progress: progress,
total: total,
current_task: task_index,
last_update: DateTime.utc_now()
}
end
@doc """
Agrega un resultado al worker state
"""
def add_result(%__MODULE__{} = state, task_index, result) do
result_entry = %{
task_index: task_index,
result: result,
timestamp: DateTime.utc_now()
}
updated_results = [result_entry | state.results]
%__MODULE__{state | results: updated_results, last_update: DateTime.utc_now()}
end
@doc """
Marca el worker como finished
"""
def finished(%__MODULE__{} = state) do
%__MODULE__{
state
| status: :finished,
progress: 100,
finished_at: DateTime.utc_now(),
last_update: DateTime.utc_now()
}
end
@doc """
Marca el worker como error
"""
def error(%__MODULE__{} = state, reason, task_index) do
%__MODULE__{
state
| status: :error,
error: reason,
error_task: task_index,
finished_at: DateTime.utc_now(),
last_update: DateTime.utc_now()
}
end
@doc """
Actualiza el progreso sin cambiar el estado
"""
def update_progress(%__MODULE__{} = state, progress, task_index) do
%__MODULE__{
state
| progress: progress,
current_task: task_index,
last_update: DateTime.utc_now()
}
end
@doc """
Verifica si el worker ha terminado (exitosa o erroneamente)
"""
def finished?(%__MODULE__{status: status}) do
status in [:finished, :error, :failed_to_start]
end
@doc """
Obtiene el tiempo transcurrido desde que empezó el worker
"""
def elapsed_time(%__MODULE__{started_at: nil}), do: 0
def elapsed_time(%__MODULE__{started_at: started_at, finished_at: nil}) do
DateTime.diff(DateTime.utc_now(), started_at, :millisecond)
end
def elapsed_time(%__MODULE__{started_at: started_at, finished_at: finished_at}) do
DateTime.diff(finished_at, started_at, :millisecond)
end
@doc """
Obtiene el porcentaje de progreso basado en tareas completadas
"""
def calculate_progress(%__MODULE__{total: total, current_task: current_task})
when is_integer(total) and total > 0 and is_integer(current_task) do
(current_task / total * 100) |> Float.round(1)
end
def calculate_progress(_), do: 0
end