Packages

phoenix_kit

1.7.170
1.7.208 1.7.207 1.7.206 1.7.205 1.7.204 1.7.203 1.7.202 1.7.201 1.7.200 1.7.199 1.7.198 1.7.197 1.7.196 1.7.194 1.7.193 1.7.192 1.7.191 1.7.190 1.7.189 1.7.187 1.7.186 1.7.185 1.7.184 1.7.183 1.7.182 1.7.181 1.7.180 1.7.179 1.7.178 1.7.177 1.7.176 1.7.175 1.7.174 1.7.173 1.7.172 1.7.171 1.7.170 1.7.169 1.7.168 1.7.167 1.7.166 1.7.165 1.7.164 1.7.162 1.7.161 1.7.160 1.7.159 1.7.157 1.7.156 1.7.155 1.7.154 1.7.153 1.7.152 1.7.151 1.7.150 1.7.149 1.7.146 1.7.145 1.7.144 1.7.143 1.7.138 1.7.133 1.7.132 1.7.131 1.7.130 1.7.128 1.7.126 1.7.125 1.7.121 1.7.120 1.7.119 1.7.118 1.7.117 1.7.116 1.7.115 1.7.114 1.7.113 1.7.112 1.7.111 1.7.110 1.7.109 1.7.108 1.7.107 1.7.106 1.7.105 1.7.104 1.7.103 1.7.102 1.7.101 1.7.100 1.7.99 1.7.98 1.7.97 1.7.96 1.7.95 1.7.94 1.7.93 1.7.92 1.7.91 1.7.90 1.7.89 1.7.88 1.7.87 1.7.86 1.7.85 1.7.84 1.7.83 1.7.82 1.7.81 1.7.80 1.7.79 1.7.78 1.7.77 1.7.76 1.7.75 1.7.74 1.7.71 1.7.70 1.7.69 1.7.66 1.7.65 1.7.64 1.7.63 1.7.62 1.7.61 1.7.59 1.7.58 1.7.57 1.7.56 1.7.55 1.7.54 1.7.53 1.7.52 1.7.51 1.7.49 1.7.44 1.7.43 1.7.42 1.7.41 1.7.39 1.7.38 1.7.37 1.7.36 1.7.34 1.7.33 1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.7.23 1.7.22 1.7.21 1.7.20 1.7.19 1.7.18 1.7.17 1.7.16 1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 1.7.9 1.7.8 1.7.7 1.7.6 1.7.5 1.7.4 1.7.3 1.7.2 1.7.1 1.7.0 1.6.20 1.6.19 1.6.18 1.6.17 1.6.16 1.6.15 1.6.14 1.6.13 1.6.12 1.6.11 1.6.10 1.6.9 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.10 1.2.9 1.2.8 1.2.7 1.2.5 1.2.4 1.2.2 1.2.1 1.2.0 1.1.0 1.0.0

A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more

Current section

Files

Jump to
phoenix_kit lib modules storage workers annotation_thumbnail_job.ex
Raw

lib/modules/storage/workers/annotation_thumbnail_job.ex

defmodule PhoenixKit.Modules.Storage.AnnotationThumbnailJob do
@moduledoc """
Background (re)generation of a file's baked annotated thumbnail.
Debounced: jobs are unique per `file_uuid` *while still pending or running*
(scheduled / available / executing / retryable) and enqueued with a short
delay, so a burst of annotation edits collapses into a single render. The job
reads the *current* annotations at run time, so it always reflects the latest
state.
Crucially, `:completed` is **not** a unique state: once a regen finishes, the
next edit enqueues a fresh one. (Oban's default unique states include
`:completed`, which would throttle regens to one per `period` per file and
silently drop edits made inside that window — the symptom being "my new shape
didn't show up until I drew another one.")
"""
# The "incomplete" (not-yet-finished) states, computed from the *installed*
# Oban so the list stays valid across versions — `:suspended` exists in some
# Oban releases (2.23) but not others (2.20), and naming the wrong set is a
# hard compile error in the host app. Excluding the terminal states (above
# all `:completed`) is the whole point: a finished regen must never dedup the
# next edit's enqueue.
@unique_states Oban.Job.states() -- [:completed, :cancelled, :discarded]
use Oban.Worker,
queue: :file_processing,
max_attempts: 3,
unique: [period: 120, keys: [:file_uuid], states: @unique_states]
alias PhoenixKit.Modules.Storage.AnnotationThumbnail
# Seconds to wait before rendering, letting a flurry of edits settle.
@debounce_seconds 8
@doc """
Enqueue a debounced annotated-thumbnail refresh for `file_uuid`.
Best-effort: never raises (so it can't break the annotation-save path even if
Oban isn't running). Returns `:ok` regardless.
"""
def enqueue(file_uuid) when is_binary(file_uuid) do
if AnnotationThumbnail.enabled?() do
%{file_uuid: file_uuid}
|> new(schedule_in: @debounce_seconds)
|> Oban.insert()
end
:ok
rescue
_ -> :ok
end
@impl Oban.Worker
def perform(%Oban.Job{args: %{"file_uuid" => file_uuid}}) do
case AnnotationThumbnail.refresh(file_uuid) do
{:ok, _} -> :ok
{:error, reason} -> {:error, reason}
end
end
end