Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.

Commit 06040d2

Browse files
committed
implement cancel manager for slow ops
1 parent b0e6971 commit 06040d2

File tree

6 files changed

+65
-16
lines changed

6 files changed

+65
-16
lines changed

lib/inference/open_ai_image_generator.rb

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

lib/personas/artifact_update_strategies/base.rb

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,24 @@ module ArtifactUpdateStrategies
55
class InvalidFormatError < StandardError
66
end
77
class Base
8-
attr_reader :post, :user, :artifact, :artifact_version, :instructions, :llm
8+
attr_reader :post, :user, :artifact, :artifact_version, :instructions, :llm, :cancel_manager
99

10-
def initialize(llm:, post:, user:, artifact:, artifact_version:, instructions:)
10+
def initialize(
11+
llm:,
12+
post:,
13+
user:,
14+
artifact:,
15+
artifact_version:,
16+
instructions:,
17+
cancel_manager:
18+
)
1119
@llm = llm
1220
@post = post
1321
@user = user
1422
@artifact = artifact
1523
@artifact_version = artifact_version
1624
@instructions = instructions
25+
@cancel_manager = cancel_manager
1726
end
1827

1928
def apply(&progress)
@@ -26,7 +35,7 @@ def apply(&progress)
2635

2736
def generate_changes(&progress)
2837
response = +""
29-
llm.generate(build_prompt, user: user) do |partial|
38+
llm.generate(build_prompt, user: user, cancel_manager: cancel_manager) do |partial|
3039
progress.call(partial) if progress
3140
response << partial
3241
end

lib/personas/tools/create_artifact.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,12 @@ def generate_artifact_code(post:, user:)
151151
LlmModel.find_by(id: options[:creator_llm].to_i)&.to_llm
152152
) || self.llm
153153

154-
llm.generate(prompt, user: user, feature_name: "create_artifact") do |partial_response|
154+
llm.generate(
155+
prompt,
156+
user: user,
157+
feature_name: "create_artifact",
158+
cancel_manager: context.cancel_manager,
159+
) do |partial_response|
155160
response << partial_response
156161
yield partial_response
157162
end

lib/personas/tools/create_image.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def invoke
4848
max_prompts,
4949
model: "gpt-image-1",
5050
user_id: bot_user.id,
51+
cancel_manager: context.cancel_manager,
5152
)
5253
rescue => e
5354
@error = e

lib/personas/tools/edit_image.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ def invoke
6060
uploads,
6161
prompt,
6262
user_id: bot_user.id,
63+
cancel_manager: context.cancel_manager,
6364
)
6465
rescue => e
6566
@error = e

lib/personas/tools/update_artifact.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ def invoke
159159
artifact: artifact,
160160
artifact_version: artifact_version,
161161
instructions: instructions,
162+
cancel_manager: context.cancel_manager,
162163
)
163164
.apply do |progress|
164165
partial_response << progress

0 commit comments

Comments
 (0)