towerops/lib/towerops/workers/backup_timeout_worker.ex
mayor 0c77dd84e7
Add strict typespecs to all Oban worker perform/1 functions
Adds @spec annotations to all Oban worker perform/1 functions to improve
static analysis and documentation. Return types are specific to each worker's
actual behavior:

Workers returning 🆗
- BackupSummaryWorker
- BackupTimeoutWorker
- DeviceMonitorWorker
- DevicePollerWorker
- JobHealthCheckWorker
- NeighborCleanupWorker

Workers with complex returns:
- DiscoveryWorker: :ok | :discard
- FirmwareVersionFetcherWorker: :ok | {:error, term()}
- LoginHistoryCleanupWorker: {:ok, %{deleted: non_neg_integer(), anonymized_deleted: non_neg_integer()}}
- MikrotikBackupWorker: :ok | {:error, String.t()}
- SessionCleanupWorker: {:ok, %{sessions_deleted: non_neg_integer()}}

Analysis found that none of these workers have complex job parameters that
would benefit from embedded schemas - all use either no parameters or simple
device_id strings passed in job args.

StaleAgentWorker already had a typespec on find_stale_agents/0 from previous work.

All 98 worker tests passing after changes.
2026-02-06 09:50:51 -06:00

30 lines
830 B
Elixir

defmodule Towerops.Workers.BackupTimeoutWorker do
@moduledoc """
Oban worker that marks stale backup requests as timed out.
Runs every 10 minutes via cron schedule. Marks any backup requests that have
been pending for more than 5 minutes as "timeout" to prevent tracking table
from accumulating stale entries.
"""
use Oban.Worker, queue: :maintenance, max_attempts: 1
alias Towerops.Devices.BackupRequests
require Logger
@timeout_minutes 5
@impl Oban.Worker
@spec perform(Oban.Job.t()) :: :ok
def perform(%Oban.Job{}) do
cutoff = DateTime.add(DateTime.utc_now(), -@timeout_minutes * 60, :second)
timeout_count = BackupRequests.mark_timed_out_requests(cutoff)
if timeout_count > 0 do
Logger.warning("Marked #{timeout_count} backup requests as timeout")
end
:ok
end
end