Skip to content

Commit

Permalink
Merge pull request #9352 from kbrock/wait_for_task
Browse files Browse the repository at this point in the history
Wait for task no longer

(cherry picked from commit f42d416)
  • Loading branch information
Fryguy committed Feb 28, 2025
1 parent 88ae2f3 commit fefd271
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 29 deletions.
60 changes: 32 additions & 28 deletions app/controllers/application_controller/wait_for_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,67 +11,71 @@ def wait_for_task
@edit = session[:edit] # If in edit, need to preserve @edit object
raise Forbidden, _('Invalid input for "wait_for_task".') unless params[:task_id]

@edit = session[:edit] # If in edit, need to preserve @edit object
session[:async] ||= {}
session[:async][:interval] ||= 1000 # Default interval to 1 second
session[:async][:params] ||= {}
async_interval = params[:async_interval] || 1000 # Default interval to 1 second

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

def browser_refresh_task(task_id, should_flash = false)
session[:async][:interval] += 250 if session[:async][:interval] < 5000 # Slowly move up to 5 second retries
def browser_refresh_task(task_id, async_interval, should_flash: false)
async_interval = 1000 if async_interval.to_i < 1000 # if it is not an integer, assign to 1 second
async_interval += 250 if async_interval < 5000 # Slowly move up to 5 second retries
render :update do |page|
page << javascript_prologue
ajax_call = remote_function(:url => {:action => 'wait_for_task', :task_id => task_id})
page << "setTimeout(\"#{ajax_call}\", #{session[:async][:interval]});"
ajax_call = remote_function(:url => {:action => 'wait_for_task', :task_id => task_id, :async_interval => async_interval})
page << "setTimeout(\"#{ajax_call}\", #{async_interval});"
page.replace("flash_msg_div", :partial => "layouts/flash_msg") if should_flash
page << "miqScrollTop();" if @flash_array.present?
end
end
private :browser_refresh_task

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

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

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

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

session[:async][:params][:action] = 'wait_for_task_rx'
session[:async][:params][:rx_action] = options[:rx_action]
async_params[:action] = 'wait_for_task_rx'
async_params[:rx_action] = options[:rx_action]
end

browser_refresh_task(task_id, !!options[:flash])
task = MiqTask.find(task_id)
task.context_data = (task.context_data || {}).merge(:async_params => async_params)
task.save!

browser_refresh_task(task_id, async_interval, :should_flash => !!options[:flash])
end
private :initiate_wait_for_task

# used for any task with rx_action
def wait_for_task_rx
task_id = params[:task_id]
rx_action = session[:async][:params][:rx_action]

task = MiqTask.find(task_id)
async_params = task.context_data[:async_params]
rx_action = async_params[:rx_action]

result = send(rx_action, task)
raise "Non-hash rx_action return" unless result.kind_of?(Hash)

Expand Down
3 changes: 2 additions & 1 deletion spec/controllers/application_controller/buttons_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@
end

it "Vm button" do
task = MiqTask.create
controller.params = {:id => vm.id, :button_id => button.id}
expect_any_instance_of(CustomButton).to receive(:invoke_async).with(vm, 'UI')
expect_any_instance_of(CustomButton).to receive(:invoke_async).with(vm, 'UI').and_return(task.id)

controller.send(:custom_buttons)
expect(assigns(:right_cell_text)).to include(vm.name)
Expand Down

0 comments on commit fefd271

Please sign in to comment.