Skip to content

Commit 47c7477

Browse files
committed
Refs #38856 - address rubocop concerns.
1 parent eb5435b commit 47c7477

File tree

3 files changed

+51
-52
lines changed

3 files changed

+51
-52
lines changed

app/models/katello/content_view_version.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,10 +370,11 @@ def auto_publish_composites!(component_task_id)
370370
composite_cv.with_lock do
371371
status = composite_publish_status(composite_cv)
372372

373-
if status == :scheduled
373+
case status
374+
when :scheduled
374375
Rails.logger.info("Composite CV #{composite_cv.name} publish already scheduled, skipping duplicate")
375376
next
376-
elsif status == :running
377+
when :running
377378
# A composite publish is currently running - we need to schedule another one
378379
# after it finishes to include this new component version
379380
Rails.logger.info("Composite CV #{composite_cv.name} publish running, scheduling event for retry")

config/initializers/foreman_tasks_chaining.rb

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,43 +6,45 @@
66
#
77
# See: https://github.com/Dynflow/dynflow/pull/446
88

9-
# Defer extension until after ForemanTasks module is loaded
10-
Rails.application.config.to_prepare do
11-
module ForemanTasks
12-
# Chain execution plans so that a new plan waits until prerequisite plans finish before executing.
13-
# This is useful for coordinating dependent tasks where one task should only run after
14-
# other tasks have completed successfully.
15-
#
16-
# The chained plan will remain in 'scheduled' state until all prerequisite plans
17-
# reach 'stopped' state (regardless of success/failure).
18-
#
19-
# @param plan_uuids [String, Array<String>] UUID(s) of prerequisite execution plan(s)
20-
# @param action [Class] Action class to execute
21-
# @param args Arguments to pass to the action
22-
# @return [ForemanTasks::Task::DynflowTask] The chained task that will wait for prerequisites
23-
#
24-
# @example Chain a task to wait for another task
25-
# task1 = ForemanTasks.async_task(SomeAction)
26-
# task2 = ForemanTasks.chain(task1.external_id, AnotherAction, arg1, arg2)
27-
# # task2 will only execute after task1 completes
28-
#
29-
# @example Chain a task to wait for multiple tasks
30-
# task1 = ForemanTasks.async_task(Action1)
31-
# task2 = ForemanTasks.async_task(Action2)
32-
# task3 = ForemanTasks.chain([task1.external_id, task2.external_id], Action3)
33-
# # task3 will only execute after both task1 and task2 complete
34-
def self.chain(plan_uuids, action, *args)
35-
result = dynflow.world.chain(plan_uuids, action, *args)
36-
# The ForemanTasks record may not exist yet for delayed plans,
37-
# so we need to find or create it and properly initialize it
38-
ForemanTasks::Task.find_by(:external_id => result.id) ||
39-
begin
40-
delayed_plan = dynflow.world.persistence.load_delayed_plan(result.id)
41-
execution_plan = dynflow.world.persistence.load_execution_plan(result.id)
42-
ForemanTasks::Task::DynflowTask.new_for_execution_plan(execution_plan).tap do |task|
43-
task.update_from_dynflow(execution_plan, delayed_plan)
44-
end
9+
module ForemanTasksChaining
10+
# Chain execution plans so that a new plan waits until prerequisite plans finish before executing.
11+
# This is useful for coordinating dependent tasks where one task should only run after
12+
# other tasks have completed successfully.
13+
#
14+
# The chained plan will remain in 'scheduled' state until all prerequisite plans
15+
# reach 'stopped' state (regardless of success/failure).
16+
#
17+
# @param plan_uuids [String, Array<String>] UUID(s) of prerequisite execution plan(s)
18+
# @param action [Class] Action class to execute
19+
# @param args Arguments to pass to the action
20+
# @return [ForemanTasks::Task::DynflowTask] The chained task that will wait for prerequisites
21+
#
22+
# @example Chain a task to wait for another task
23+
# task1 = ForemanTasks.async_task(SomeAction)
24+
# task2 = ForemanTasks.chain(task1.external_id, AnotherAction, arg1, arg2)
25+
# # task2 will only execute after task1 completes
26+
#
27+
# @example Chain a task to wait for multiple tasks
28+
# task1 = ForemanTasks.async_task(Action1)
29+
# task2 = ForemanTasks.async_task(Action2)
30+
# task3 = ForemanTasks.chain([task1.external_id, task2.external_id], Action3)
31+
# # task3 will only execute after both task1 and task2 complete
32+
def chain(plan_uuids, action, *args)
33+
result = dynflow.world.chain(plan_uuids, action, *args)
34+
# The ForemanTasks record may not exist yet for delayed plans,
35+
# so we need to find or create it and properly initialize it
36+
ForemanTasks::Task.find_by(:external_id => result.id) ||
37+
begin
38+
delayed_plan = dynflow.world.persistence.load_delayed_plan(result.id)
39+
execution_plan = dynflow.world.persistence.load_execution_plan(result.id)
40+
ForemanTasks::Task::DynflowTask.new_for_execution_plan(execution_plan).tap do |task|
41+
task.update_from_dynflow(execution_plan, delayed_plan)
4542
end
46-
end
43+
end
4744
end
4845
end
46+
47+
# Defer extension until after ForemanTasks module is loaded
48+
Rails.application.config.to_prepare do
49+
ForemanTasks.singleton_class.prepend(ForemanTasksChaining)
50+
end

test/models/content_view_version_auto_publish_test.rb

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def test_auto_publish_with_no_sibling_tasks_triggers_immediately
4444

4545
# Stub to return no scheduled, no running composite, no sibling tasks
4646
ForemanTasks::Task::DynflowTask.stubs(:for_action)
47-
.returns(stub(where: stub(any?: false))) # Scheduled check: no scheduled tasks
47+
.returns(stub(where: stub(any?: false))) # Scheduled check: no scheduled tasks
4848
.then.returns(stub(where: stub(select: []))) # Running composite check: none
4949
.then.returns(stub(where: stub(select: []))) # Sibling check: none
5050

@@ -65,9 +65,9 @@ def test_auto_publish_with_sibling_tasks_uses_chaining
6565
sibling_task = stub(external_id: task_id2, input: { 'content_view' => { 'id' => @component_cv2.id } })
6666

6767
ForemanTasks::Task::DynflowTask.stubs(:for_action)
68-
.returns(stub(where: stub(any?: false))) # Scheduled check: no scheduled tasks
69-
.then.returns(stub(where: stub(select: []))) # Running composite check: none
70-
.then.returns(stub(where: stub(select: [sibling_task]))) # Sibling check: found sibling
68+
.returns(stub(where: stub(any?: false))) # Scheduled check: no scheduled tasks
69+
.then.returns(stub(where: stub(select: []))) # Running composite check: none
70+
.then.returns(stub(where: stub(select: [sibling_task]))) # Sibling check: found sibling
7171

7272
ForemanTasks.expects(:chain).with(
7373
[task_id2],
@@ -113,8 +113,8 @@ def test_auto_publish_schedules_event_when_composite_running
113113
running_task = stub(external_id: SecureRandom.uuid, input: { 'content_view' => { 'id' => @composite_cv.id } })
114114

115115
ForemanTasks::Task::DynflowTask.stubs(:for_action)
116-
.returns(stub(where: stub(any?: false))) # Scheduled check: none
117-
.then.returns(stub(where: stub(select: [running_task]))) # Running check: found running task
116+
.returns(stub(where: stub(any?: false))) # Scheduled check: none
117+
.then.returns(stub(where: stub(select: [running_task]))) # Running check: found running task
118118

119119
# Should schedule event instead of creating task
120120
event_attrs = {}
@@ -133,7 +133,7 @@ def test_auto_publish_handles_lock_conflict_gracefully
133133
task_id = SecureRandom.uuid
134134

135135
ForemanTasks::Task::DynflowTask.stubs(:for_action)
136-
.returns(stub(where: stub(any?: false))) # Scheduled check: none
136+
.returns(stub(where: stub(any?: false))) # Scheduled check: none
137137
.then.returns(stub(where: stub(select: []))) # Running composite check: none
138138
.then.returns(stub(where: stub(select: []))) # Sibling check: none
139139

@@ -172,17 +172,13 @@ def test_find_sibling_component_publish_tasks_finds_running_tasks
172172
def test_find_sibling_tasks_excludes_non_component_tasks
173173
task_id = SecureRandom.uuid
174174

175-
# Create mock task for a different CV (not a component)
176-
other_cv = FactoryBot.create(:katello_content_view, :organization => @org)
177-
other_task = stub(external_id: SecureRandom.uuid, input: { 'content_view' => { 'id' => other_cv.id } })
178-
179-
# The select block will filter out other_task
175+
# The select block will filter out tasks for CVs that aren't components
180176
ForemanTasks::Task::DynflowTask.stubs(:for_action).returns(stub(where: stub(select: [])))
181177

182178
result = @component1_version.send(:find_sibling_component_publish_tasks, @composite_cv, task_id)
183179

184180
# Should exclude current task and other CV's task
185-
assert_equal [], result
181+
assert_empty result
186182
end
187183
end
188184
end

0 commit comments

Comments
 (0)