defmodule Microwaveprop.Workers.PropagationPruneWorker do @moduledoc """ Standalone worker that prunes stale rows from `propagation_scores`. Pruning used to be tacked on to the end of `PropagationGridWorker.perform/1`, which meant it only ran after a successful grid compute. When the compute worker was being killed mid-run (OOM / SIGTERM), prune never ran and the table grew unbounded. Running prune on its own cron keeps the table healthy regardless of the compute worker's state. """ use Oban.Pro.Worker, queue: :propagation, # Lower priority than PropagationGridWorker so the hourly chain # never waits behind a pending prune on the shared :propagation # queue (2 slots). priority: 5, max_attempts: 3, unique: [period: 300, states: :incomplete] alias Microwaveprop.Buildings.MsFootprints alias Microwaveprop.Canopy alias Microwaveprop.Propagation require Logger @impl Oban.Pro.Worker def process(%Oban.Job{}) do Propagation.prune_old_scores() cutoff_30d = DateTime.add(DateTime.utc_now(), -30, :day) buildings_deleted = MsFootprints.prune_older_than(cutoff_30d) canopy_deleted = Canopy.prune_older_than(cutoff_30d) if buildings_deleted > 0 do Logger.info("MsFootprints: pruned #{buildings_deleted} cached tile files older than #{cutoff_30d}") end if canopy_deleted > 0 do Logger.info("Canopy: pruned #{canopy_deleted} cached tile/staging files older than #{cutoff_30d}") end :ok end end