@@ -21,7 +21,8 @@ def self.create_uploads!(
2121 moderation : "low" ,
2222 output_compression : nil ,
2323 output_format : nil ,
24- title : nil
24+ title : nil ,
25+ cancel_manager : nil
2526 )
2627 # Get the API responses in parallel threads
2728 api_responses =
@@ -38,6 +39,7 @@ def self.create_uploads!(
3839 moderation : moderation ,
3940 output_compression : output_compression ,
4041 output_format : output_format ,
42+ cancel_manager : cancel_manager ,
4143 )
4244
4345 raise api_responses [ 0 ] if api_responses . all? { |resp | resp . is_a? ( StandardError ) }
@@ -58,7 +60,8 @@ def self.create_edited_upload!(
5860 user_id :,
5961 for_private_message : false ,
6062 n : 1 ,
61- quality : nil
63+ quality : nil ,
64+ cancel_manager : nil
6265 )
6366 api_response =
6467 edit_images (
@@ -70,6 +73,7 @@ def self.create_edited_upload!(
7073 api_url : api_url ,
7174 n : n ,
7275 quality : quality ,
76+ cancel_manager : cancel_manager ,
7377 )
7478
7579 create_uploads_from_responses ( [ api_response ] , user_id , for_private_message ) . first
@@ -124,7 +128,8 @@ def self.generate_images_in_threads(
124128 background :,
125129 moderation :,
126130 output_compression :,
127- output_format :
131+ output_format :,
132+ cancel_manager :
128133 )
129134 prompts = [ prompts ] unless prompts . is_a? ( Array )
130135 prompts = prompts . take ( 4 ) # Limit to 4 prompts max
@@ -152,18 +157,21 @@ def self.generate_images_in_threads(
152157 moderation : moderation ,
153158 output_compression : output_compression ,
154159 output_format : output_format ,
160+ cancel_manager : cancel_manager ,
155161 )
156162 rescue => e
157163 attempts += 1
158164 # to keep tests speedy
159- if !Rails . env . test?
165+ if !Rails . env . test? && ! cancel_manager &. canceled?
160166 retry if attempts < 3
161167 end
162- Discourse . warn_exception (
163- e ,
164- message : "Failed to generate image for prompt #{ prompt } \n " ,
165- )
166- puts "Error generating image for prompt: #{ prompt } #{ e } " if Rails . env . development?
168+ if !cancel_manager &.canceled?
169+ Discourse . warn_exception (
170+ e ,
171+ message : "Failed to generate image for prompt #{ prompt } \n " ,
172+ )
173+ puts "Error generating image for prompt: #{ prompt } #{ e } " if Rails . env . development?
174+ end
167175 e
168176 end
169177 end
@@ -181,7 +189,8 @@ def self.edit_images(
181189 api_key : nil ,
182190 api_url : nil ,
183191 n : 1 ,
184- quality : nil
192+ quality : nil ,
193+ cancel_manager : nil
185194 )
186195 images = [ images ] if !images . is_a? ( Array )
187196
@@ -209,8 +218,10 @@ def self.edit_images(
209218 api_url : api_url ,
210219 n : n ,
211220 quality : quality ,
221+ cancel_manager : cancel_manager ,
212222 )
213223 rescue => e
224+ raise e if cancel_manager &.canceled?
214225 attempts += 1
215226 if !Rails . env . test?
216227 sleep 2
@@ -238,7 +249,8 @@ def self.perform_generation_api_call!(
238249 background : nil ,
239250 moderation : nil ,
240251 output_compression : nil ,
241- output_format : nil
252+ output_format : nil ,
253+ cancel_manager : nil
242254 )
243255 api_key ||= SiteSetting . ai_openai_api_key
244256 api_url ||= SiteSetting . ai_openai_image_generation_url
@@ -276,6 +288,7 @@ def self.perform_generation_api_call!(
276288
277289 # Store original prompt for upload metadata
278290 original_prompt = prompt
291+ cancel_manager_callback = nil
279292
280293 FinalDestination ::HTTP . start (
281294 uri . host ,
@@ -288,6 +301,11 @@ def self.perform_generation_api_call!(
288301 request = Net ::HTTP ::Post . new ( uri , headers )
289302 request . body = payload . to_json
290303
304+ if cancel_manager
305+ cancel_manager_callback = lambda { http . finish }
306+ cancel_manager . add_callback ( cancel_manager_callback )
307+ end
308+
291309 json = nil
292310 http . request ( request ) do |response |
293311 if response . code . to_i != 200
@@ -300,6 +318,10 @@ def self.perform_generation_api_call!(
300318 end
301319 json
302320 end
321+ ensure
322+ if cancel_manager && cancel_manager_callback
323+ cancel_manager . remove_callback ( cancel_manager_callback )
324+ end
303325 end
304326
305327 def self . perform_edit_api_call! (
@@ -310,7 +332,8 @@ def self.perform_edit_api_call!(
310332 api_key :,
311333 api_url :,
312334 n : 1 ,
313- quality : nil
335+ quality : nil ,
336+ cancel_manager : nil
314337 )
315338 uri = URI ( api_url )
316339
@@ -403,6 +426,7 @@ def self.perform_edit_api_call!(
403426
404427 # Store original prompt for upload metadata
405428 original_prompt = prompt
429+ cancel_manager_callback = nil
406430
407431 FinalDestination ::HTTP . start (
408432 uri . host ,
@@ -415,6 +439,11 @@ def self.perform_edit_api_call!(
415439 request = Net ::HTTP ::Post . new ( uri . path , headers )
416440 request . body = body . join
417441
442+ if cancel_manager
443+ cancel_manager_callback = lambda { http . finish }
444+ cancel_manager . add_callback ( cancel_manager_callback )
445+ end
446+
418447 json = nil
419448 http . request ( request ) do |response |
420449 if response . code . to_i != 200
@@ -428,6 +457,9 @@ def self.perform_edit_api_call!(
428457 json
429458 end
430459 ensure
460+ if cancel_manager && cancel_manager_callback
461+ cancel_manager . remove_callback ( cancel_manager_callback )
462+ end
431463 if files_to_delete . present?
432464 files_to_delete . each { |file | File . delete ( file ) if File . exist? ( file ) }
433465 end
0 commit comments