Skip to content

Commit e7933d3

Browse files
committed
wait_for_task stores async parameters in task.context_data
We were storing in session[:async][:params], but that ended up with a race condition and didn't allow multiple tabs
1 parent 6b17d66 commit e7933d3

File tree

2 files changed

+25
-20
lines changed

2 files changed

+25
-20
lines changed

app/controllers/application_controller/wait_for_task.rb

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ def wait_for_task
1111
@edit = session[:edit] # If in edit, need to preserve @edit object
1212
raise Forbidden, _('Invalid input for "wait_for_task".') unless params[:task_id]
1313

14-
session[:async] ||= {}
1514
async_interval = params[:async_interval] || 1000 # Default interval to 1 second
16-
session[:async][:params] ||= {}
1715

18-
if MiqTask.find(params[:task_id].to_i).state != "Finished" # Task not done --> retry
16+
task = MiqTask.find(params[:task_id].to_i)
17+
if task.state != "Finished" # Task not done --> retry
1918
browser_refresh_task(params[:task_id], async_interval)
2019
else # Task done
21-
session[:async][:params].each { |k, v| @_params[k] = v } # Merge in the original params and
22-
send(session.fetch_path(:async, :params, :action)) # call the orig. method
20+
async_params = task.context_data[:async_params]
21+
async_params.each { |k, v| @_params[k] = v } # Merge in the original params and
22+
send(async_params[:action]) # call the orig. method
2323
end
2424
end
2525

@@ -37,41 +37,45 @@ def browser_refresh_task(task_id, async_interval, should_flash: false)
3737
private :browser_refresh_task
3838

3939
#
40-
# :task_id => id of task to wait for
41-
# :action => 'action_to_call' -- action to be called when the task finishes
42-
# :rx_action => 'method_to_call' -- a method to create a RxJs message
43-
# :flash => true|false -- output queued flash messages *while waiting*
40+
# @option options :task_id [Numeric] id of task to wait for
41+
# @option options :action [String] action to be called when the task finishes
42+
# @option options :rx_action [String] a method to create a RxJs message
43+
# @option options :flash [Boolean] output queued flash messages *while waiting*
44+
# @option options :extra_params [Hash] asynchronous
4445
#
4546
def initiate_wait_for_task(options = {})
4647
task_id = options[:task_id]
47-
session[:async] ||= {}
4848
async_interval = 1000 # Default interval to 1 second
49-
session[:async][:params] ||= {}
5049

51-
# save the incoming parms + extra_params
52-
session[:async][:params] = params.to_unsafe_h.merge(options[:extra_params] || {})
53-
session[:async][:params][:task_id] = task_id
50+
# save the incoming params + extra_params
51+
async_params = params.to_unsafe_h.merge(options[:extra_params] || {})
52+
async_params[:task_id] = task_id
5453

5554
# override method to be called, when the task is done
56-
session[:async][:params][:action] = options[:action] if options.key?(:action)
55+
async_params[:action] = options[:action] if options.key?(:action)
5756

5857
if options.key?(:rx_action)
5958
raise "Unsupported combination" if options.key?(:action)
6059

61-
session[:async][:params][:action] = 'wait_for_task_rx'
62-
session[:async][:params][:rx_action] = options[:rx_action]
60+
async_params[:action] = 'wait_for_task_rx'
61+
async_params[:rx_action] = options[:rx_action]
6362
end
6463

64+
task = MiqTask.find(task_id)
65+
task.context_data = (task.context_data || {}).merge(:async_params => async_params)
66+
task.save!
67+
6568
browser_refresh_task(task_id, async_interval, :should_flash => !!options[:flash])
6669
end
6770
private :initiate_wait_for_task
6871

6972
# used for any task with rx_action
7073
def wait_for_task_rx
7174
task_id = params[:task_id]
72-
rx_action = session[:async][:params][:rx_action]
73-
7475
task = MiqTask.find(task_id)
76+
async_params = task.context_data[:async_params]
77+
rx_action = async_params[:rx_action]
78+
7579
result = send(rx_action, task)
7680
raise "Non-hash rx_action return" unless result.kind_of?(Hash)
7781

spec/controllers/application_controller/buttons_spec.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@
5151
end
5252

5353
it "Vm button" do
54+
task = MiqTask.create
5455
controller.params = {:id => vm.id, :button_id => button.id}
55-
expect_any_instance_of(CustomButton).to receive(:invoke_async).with(vm, 'UI')
56+
expect_any_instance_of(CustomButton).to receive(:invoke_async).with(vm, 'UI').and_return(task.id)
5657

5758
controller.send(:custom_buttons)
5859
expect(assigns(:right_cell_text)).to include(vm.name)

0 commit comments

Comments
 (0)