Packages

Adaptive backfill library with health checks for Elixir. Supports both single operations and batch processing with sync/async health monitoring.

Current section

Files

Jump to
adaptive_backfill lib batch_operation_options.ex
Raw

lib/batch_operation_options.ex

defmodule AdaptiveBackfill.BatchOperationOptions do
@moduledoc """
Struct that holds config for batch operations, used for pagination or chunked behaviour.
"""
alias AdaptiveBackfill.Types
@type t :: %__MODULE__{
initial_state: any(),
handle_batch: (any() -> {:ok, any()} | {:error, any()} | :done),
on_complete: (any() -> any()),
on_success: (any() -> any()),
on_error: (any(), any() -> any()),
mode: Types.operation_mode(),
health_checkers: [Types.health_checker()],
delay_between_batches: non_neg_integer() | nil,
timeout: non_neg_integer() | nil,
batch_size: pos_integer() | nil,
telemetry_prefix: [atom()] | nil,
checkpoint: Checkpoint.t() | nil
}
defstruct [
:initial_state,
:handle_batch,
:on_complete,
:on_success,
:on_error,
:mode,
:health_checkers,
:delay_between_batches,
:timeout,
:batch_size,
:telemetry_prefix,
:checkpoint
]
##
## PUBLIC
##
def new(initial_state, handle_batch, on_complete, mode, health_checkers, opts \\ []) do
on_success = Keyword.get(opts, :on_success)
on_error = Keyword.get(opts, :on_error)
delay_between_batches = Keyword.get(opts, :delay_between_batches)
timeout = Keyword.get(opts, :timeout)
batch_size = Keyword.get(opts, :batch_size)
telemetry_prefix = Keyword.get(opts, :telemetry_prefix)
checkpoint = Keyword.get(opts, :checkpoint)
cond do
is_nil(handle_batch) or not is_function(handle_batch, 1) ->
{:error, :invalid_handle_batch}
not is_nil(on_complete) and not is_function(on_complete, 1) ->
{:error, :invalid_on_complete}
invalid_mode?(mode) ->
{:error, :invalid_mode}
invalid_health_checkers?(health_checkers) ->
{:error, :invalid_health_checkers}
not is_nil(on_success) and not is_function(on_success, 1) ->
{:error, :invalid_on_success}
not is_nil(on_error) and not is_function(on_error, 2) ->
{:error, :invalid_on_error}
not is_nil(telemetry_prefix) and not is_list(telemetry_prefix) ->
{:error, :invalid_telemetry_prefix}
not is_nil(delay_between_batches) and not is_integer(delay_between_batches) ->
{:error, :invalid_delay}
not is_nil(timeout) and not is_integer(timeout) ->
{:error, :invalid_timeout}
not is_nil(batch_size) and (not is_integer(batch_size) or batch_size < 1) ->
{:error, :invalid_batch_size}
true ->
{:ok,
%__MODULE__{
initial_state: initial_state,
handle_batch: handle_batch,
on_complete: on_complete,
on_success: on_success,
on_error: on_error,
mode: mode,
health_checkers: health_checkers,
delay_between_batches: delay_between_batches,
timeout: timeout,
batch_size: batch_size,
telemetry_prefix: telemetry_prefix,
checkpoint: checkpoint
}}
end
end
defp invalid_mode?(:sync), do: false
defp invalid_mode?(:async), do: false
defp invalid_mode?(_), do: true
defp invalid_health_checkers?(nil), do: true
defp invalid_health_checkers?([]), do: true
defp invalid_health_checkers?(checks),
do: not Enum.all?(checks, &is_function(&1, 0))
end