@@ -18,13 +18,14 @@ defmodule Banchan.Workers.Thumbnailer do
18
18
19
19
@ impl Oban.Worker
20
20
def perform ( % _ {
21
+ id: job_id ,
21
22
args: % {
22
23
"src" => src_id ,
23
24
"dest" => dest_id ,
24
25
"opts" => opts
25
26
}
26
27
} ) do
27
- process ( src_id , dest_id , opts )
28
+ process ( job_id , src_id , dest_id , opts )
28
29
end
29
30
30
31
def thumbnail ( upload , opts \\ [ ] )
@@ -35,43 +36,60 @@ defmodule Banchan.Workers.Thumbnailer do
35
36
end
36
37
37
38
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
+ )
49
54
)
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
69
86
end
70
- end
87
+ end )
88
+ |> Task . await ( Keyword . get ( opts , :timeout ) || 300_000 )
71
89
end
72
90
73
91
# 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
75
93
Repo . transaction ( fn ->
76
94
src = Uploads . get_by_id! ( src_id )
77
95
dest = Uploads . get_by_id! ( dest_id )
@@ -166,26 +184,7 @@ defmodule Banchan.Workers.Thumbnailer do
166
184
{ :ok , dest }
167
185
end )
168
186
|> 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 , _ } } ->
189
188
{ :ok , dest_id }
190
189
191
190
{ :ok , { :error , error } } ->
@@ -194,5 +193,14 @@ defmodule Banchan.Workers.Thumbnailer do
194
193
{ :error , _ } ->
195
194
{ :error , :processing_failed }
196
195
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
197
205
end
198
206
end
0 commit comments