Raxol.Core.Utils.TimerManager (Raxol v2.0.1)

View Source

Centralized timer management utilities for consistent timer handling across the codebase.

This module provides a unified interface for working with timers, including:

  • Periodic timers (intervals)
  • One-time delayed timers
  • Timer cancellation
  • Timer reference tracking

All timer intervals are in milliseconds.

Summary

Functions

Adds jitter to a timer interval to prevent thundering herd.

Manages multiple timers in a map, useful for GenServer state.

Cancels all timers in a map, useful for GenServer terminate.

Cancels a timer and returns whether it was successfully cancelled.

Calculates next timer interval for exponential backoff.

Common timer intervals as constants for consistency.

Safely cancels a timer if it exists, ignoring errors.

Starts a one-time delayed timer that sends a message after a delay.

Starts a periodic timer that sends a message at regular intervals.

Types

timer_msg()

@type timer_msg() :: atom() | tuple()

timer_ref()

@type timer_ref() :: reference() | {atom(), reference()} | nil

timer_type()

@type timer_type() :: :interval | :once

Functions

add_jitter(interval_ms, jitter_factor \\ 0.1)

@spec add_jitter(non_neg_integer(), float()) :: non_neg_integer()

Adds jitter to a timer interval to prevent thundering herd.

Examples

# Add +/- 10% jitter to 5 second interval
interval = TimerManager.add_jitter(5000, 0.1)

add_timer(timers, name, atom, interval_ms)

@spec add_timer(map(), atom(), timer_type(), non_neg_integer()) :: map()

Manages multiple timers in a map, useful for GenServer state.

Examples

# Start a new timer in the timers map
timers = TimerManager.add_timer(state.timers, :heartbeat, :interval, 5000)

# Cancel and remove a timer
timers = TimerManager.remove_timer(state.timers, :heartbeat)

cancel_all_timers(timers)

@spec cancel_all_timers(map()) :: :ok

Cancels all timers in a map, useful for GenServer terminate.

Examples

TimerManager.cancel_all_timers(state.timers)

cancel_timer(ref)

@spec cancel_timer(timer_ref()) :: {:ok, boolean() | :ok}

Cancels a timer and returns whether it was successfully cancelled.

Examples

{:ok, cancelled} = TimerManager.cancel_timer(timer_ref)

exponential_backoff(attempt, base_ms, max_ms)

@spec exponential_backoff(
  non_neg_integer(),
  non_neg_integer(),
  non_neg_integer()
) :: non_neg_integer()

Calculates next timer interval for exponential backoff.

Examples

# First retry after 1 second, then 2, 4, 8, up to max 30 seconds
delay = TimerManager.exponential_backoff(attempt, 1000, 30_000)

intervals()

Common timer intervals as constants for consistency.

remove_timer(timers, name)

@spec remove_timer(map(), atom()) :: map()

safe_cancel(ref)

@spec safe_cancel(timer_ref()) :: :ok

Safely cancels a timer if it exists, ignoring errors.

Examples

TimerManager.safe_cancel(timer_ref)

send_after(message, delay_ms)

@spec send_after(timer_msg(), non_neg_integer()) :: timer_ref()

Starts a one-time delayed timer that sends a message after a delay.

Examples

# Send :timeout message after 30 seconds
ref = TimerManager.send_after(:timeout, 30_000)

# Send {:retry, attempt_num} after 1 second
ref = TimerManager.send_after({:retry, 1}, 1000)

start_interval(message, interval_ms)

@spec start_interval(timer_msg(), non_neg_integer()) ::
  {:ok, timer_ref()} | {:error, term()}

Starts a periodic timer that sends a message at regular intervals.

Examples

# Send :cleanup message every hour
{:ok, ref} = TimerManager.start_interval(:cleanup, 3_600_000)

# Send {:check_status, :database} every 5 seconds
{:ok, ref} = TimerManager.start_interval({:check_status, :database}, 5000)