Packages
phoenix_kit
1.7.199
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
Current section
Files
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
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, _} ->
# Both outcomes (fresh bake, variant removed) change what grids
# should show — let open UIs swap the thumbnail without a reload.
Storage.broadcast_file_thumbnail_updated(file_uuid)
:ok
{:error, reason} ->
{:error, reason}
end
end
end