Skip to content

Commit bd9d89a

Browse files
authored
block on thumbnailing process instead of having it be weirdly fire-and-forget (#782)
Fixes: #584
1 parent 40e1586 commit bd9d89a

File tree

4 files changed

+79
-72
lines changed

4 files changed

+79
-72
lines changed

config/test.exs

+3-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ end
3838

3939
config :banchan, Banchan.Mailer, adapter: Bamboo.TestAdapter
4040

41-
config :banchan, Oban, testing: :inline
41+
config :banchan, Oban,
42+
testing: :inline,
43+
notifier: Oban.Notifiers.PG
4244

4345
# We don't run a server during test. If one is required,
4446
# you can enable the server option below.

lib/banchan/commissions/commissions.ex

+4-12
Original file line numberDiff line numberDiff line change
@@ -1111,12 +1111,7 @@ defmodule Banchan.Commissions do
11111111
Thumbnailer.thumbnail(
11121112
upload,
11131113
target_size: "5kb",
1114-
dimensions: "128x128",
1115-
callback: [
1116-
Notifications,
1117-
:commission_event_updated,
1118-
[event.commission_id, event.id]
1119-
]
1114+
dimensions: "128x128"
11201115
)
11211116
else
11221117
{:ok, nil}
@@ -1127,12 +1122,7 @@ defmodule Banchan.Commissions do
11271122
Thumbnailer.thumbnail(
11281123
upload,
11291124
dimensions: "1200",
1130-
name: "preview.jpg",
1131-
callback: [
1132-
Notifications,
1133-
:commission_event_updated,
1134-
[event.commission_id, event.id]
1135-
]
1125+
name: "preview.jpg"
11361126
)
11371127
else
11381128
{:ok, nil}
@@ -1148,6 +1138,8 @@ defmodule Banchan.Commissions do
11481138
end)
11491139
end)
11501140

1141+
Notifications.commission_event_updated(event.commission_id, event.id)
1142+
11511143
:ok
11521144
end
11531145

lib/banchan/offerings/offerings.ex

+11-6
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,15 @@ defmodule Banchan.Offerings do
162162
end
163163
end)
164164
|> case do
165-
{:ok, ret} -> ret
166-
{:error, error} -> {:error, error}
165+
{:ok, {:ok, offering}} ->
166+
__MODULE__.Notifications.notify_images_updated(offering)
167+
{:ok, offering}
168+
169+
{:ok, {:error, error}} ->
170+
{:error, error}
171+
172+
{:error, error} ->
173+
{:error, error}
167174
end
168175
end
169176

@@ -282,8 +289,7 @@ defmodule Banchan.Offerings do
282289
Thumbnailer.thumbnail(
283290
upload,
284291
dimensions: "1200",
285-
name: "card_image.jpg",
286-
callback: [__MODULE__.Notifications, :notify_images_updated]
292+
name: "card_image.jpg"
287293
)
288294

289295
card
@@ -298,8 +304,7 @@ defmodule Banchan.Offerings do
298304
Thumbnailer.thumbnail(
299305
upload,
300306
dimensions: "1200",
301-
name: "gallery_image.jpg",
302-
callback: [__MODULE__.Notifications, :notify_images_updated]
307+
name: "gallery_image.jpg"
303308
)
304309

305310
image

lib/banchan/workers/thumbnailer.ex

+61-53
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ defmodule Banchan.Workers.Thumbnailer do
1818

1919
@impl Oban.Worker
2020
def perform(%_{
21+
id: job_id,
2122
args: %{
2223
"src" => src_id,
2324
"dest" => dest_id,
2425
"opts" => opts
2526
}
2627
}) do
27-
process(src_id, dest_id, opts)
28+
process(job_id, src_id, dest_id, opts)
2829
end
2930

3031
def thumbnail(upload, opts \\ [])
@@ -35,43 +36,60 @@ defmodule Banchan.Workers.Thumbnailer do
3536
end
3637

3738
def thumbnail(%Upload{} = upload, opts) do
38-
if !Uploads.image?(upload) && !Uploads.video?(upload) do
39-
{:error, :unsupported_input}
40-
else
41-
Ecto.Multi.new()
42-
|> Ecto.Multi.insert(
43-
:pending,
44-
Uploads.gen_pending(
45-
%User{id: upload.uploader_id},
46-
upload,
47-
"image/jpeg",
48-
Keyword.get(opts, :name, "thumbnail.jpg")
39+
Task.async(fn ->
40+
if !Uploads.image?(upload) && !Uploads.video?(upload) do
41+
{:error, :unsupported_input}
42+
else
43+
:ok = Oban.Notifier.listen([:thumbnail_jobs])
44+
45+
Ecto.Multi.new()
46+
|> Ecto.Multi.insert(
47+
:pending,
48+
Uploads.gen_pending(
49+
%User{id: upload.uploader_id},
50+
upload,
51+
"image/jpeg",
52+
Keyword.get(opts, :name, "thumbnail.jpg")
53+
)
4954
)
50-
)
51-
|> Ecto.Multi.run(:job, fn _repo, %{pending: pending} ->
52-
Oban.insert(
53-
__MODULE__.new(%{
54-
src: upload.id,
55-
dest: pending.id,
56-
opts: %{
57-
target_size: Keyword.get(opts, :target_size),
58-
format: Keyword.get(opts, :format, "jpeg"),
59-
dimensions: Keyword.get(opts, :dimensions),
60-
callback: Keyword.get(opts, :callback)
61-
}
62-
})
63-
)
64-
end)
65-
|> Repo.transaction()
66-
|> case do
67-
{:ok, %{pending: pending}} -> {:ok, pending}
68-
{:error, _, error, _} -> {:error, error}
55+
|> Ecto.Multi.run(:job, fn _repo, %{pending: pending} ->
56+
Oban.insert(
57+
__MODULE__.new(%{
58+
src: upload.id,
59+
dest: pending.id,
60+
opts: %{
61+
target_size: Keyword.get(opts, :target_size),
62+
format: Keyword.get(opts, :format, "jpeg"),
63+
dimensions: Keyword.get(opts, :dimensions)
64+
}
65+
})
66+
)
67+
end)
68+
|> Repo.transaction()
69+
|> case do
70+
{:ok, %{pending: pending, job: %{id: job_id}}} ->
71+
receive do
72+
{:notification, :thumbnail_jobs, %{"complete" => ^job_id, "result" => "ok"}} ->
73+
{:ok, Uploads.get_by_id!(pending.id)}
74+
75+
{:notification, :thumbnail_jobs,
76+
%{"complete" => ^job_id, "result" => {"error", err}}} ->
77+
{:error, String.to_existing_atom(err)}
78+
after
79+
Keyword.get(opts, :timeout) || 300_000 ->
80+
{:error, :timeout}
81+
end
82+
83+
{:error, _, error, _} ->
84+
{:error, error}
85+
end
6986
end
70-
end
87+
end)
88+
|> Task.await(Keyword.get(opts, :timeout) || 300_000)
7189
end
7290

7391
# credo:disable-for-next-line Credo.Check.Refactor.CyclomaticComplexity
74-
defp process(src_id, dest_id, opts) do
92+
defp process(job_id, src_id, dest_id, opts) do
7593
Repo.transaction(fn ->
7694
src = Uploads.get_by_id!(src_id)
7795
dest = Uploads.get_by_id!(dest_id)
@@ -166,26 +184,7 @@ defmodule Banchan.Workers.Thumbnailer do
166184
{:ok, dest}
167185
end)
168186
|> case do
169-
{:ok, {:ok, dest}} ->
170-
case opts["callback"] do
171-
[module, name, args] ->
172-
apply(
173-
String.to_existing_atom(module),
174-
String.to_existing_atom(name),
175-
args
176-
)
177-
178-
[module, name] ->
179-
apply(
180-
String.to_existing_atom(module),
181-
String.to_existing_atom(name),
182-
[dest]
183-
)
184-
185-
_ ->
186-
nil
187-
end
188-
187+
{:ok, {:ok, _}} ->
189188
{:ok, dest_id}
190189

191190
{:ok, {:error, error}} ->
@@ -194,5 +193,14 @@ defmodule Banchan.Workers.Thumbnailer do
194193
{:error, _} ->
195194
{:error, :processing_failed}
196195
end
196+
|> case do
197+
{:ok, dest_id} ->
198+
Oban.Notifier.notify(:thumbnail_jobs, %{complete: job_id, result: :ok})
199+
{:ok, dest_id}
200+
201+
{:error, err} ->
202+
Oban.Notifier.notify(:thumbnail_jobs, %{complete: job_id, result: {:error, err}})
203+
{:error, err}
204+
end
197205
end
198206
end

0 commit comments

Comments
 (0)