lib/canvas_sync/jobs/canvas_process_waiter.rb
module CanvasSync::Jobs class CanvasProcessWaiter < ActiveJob::Base # rubocop:disable Metrics/PerceivedComplexity def perform(progress_url, next_job, kwargs = {}) kwargs = kwargs.symbolize_keys response = canvas_sync_client.get(progress_url) status = kwargs[:status_key].present? ? response[kwargs[:status_key]] : response['workflow_state'] || response['status'] if %w[completed complete].include? status InvokeCallbackWorker.perform_later(build_next_job(next_job, kwargs, response)) if next_job elsif %w[failed error].include? status if kwargs[:on_failure].is_a?(Hash) InvokeCallbackWorker.perform_later(build_next_job(kwargs[:on_failure], kwargs, response)) else Rails.logger.error("Progress #{progress_url} failed") end else # if status == 'queued' || status == 'running' interval = kwargs[:interval] || (Rails.env.development? ? 3 : 60) CanvasProcessWaiter.set(wait: interval).perform_later(progress_url, next_job, kwargs) end end # rubocop:enable Metrics/PerceivedComplexity def build_next_job(job, kwargs, response) job = job.symbolize_keys if kwargs[:progress_as].present? job[:kwargs] ||= {} job[:kwargs][kwargs[:progress_as].to_sym] = response end job end # This is a separate job so that, if it fails and a retry is triggered, it doesn't query the API needlessly class InvokeCallbackWorker < ActiveJob::Base # rubocop:disable Metrics/PerceivedComplexity def perform(job) job = job.symbolize_keys params = job[:args] || [] params << job[:kwargs].symbolize_keys if job[:kwargs] # params[-1] = params[-1].symbolize_keys if params[-1].is_a?(Hash) if job[:model] model_class = load_constant(job[:model]) find_by = job[:find_by] target = find_by.is_a?(Hash) ? model_class.find_by(find_by) : model_class.find_by(id: find_by) target.send(job[:method], *params) elsif job[:class] target = load_constant(job[:class]) target.send(job[:method], *params) elsif job[:instance_of] target = load_constant(job[:instance_of]).new target.send(job[:method], *params) elsif job[:job] job_class = load_constant(job[:job]) job_class = job_class.set(job[:options]) if job[:options].present? if job_class < ActiveJob::Base job_class.perform_later(*params) else job_class.perform_async(*params) end end end # rubocop:enable Metrics/PerceivedComplexity def load_constant(const) const = const.constantize if const.is_a?(String) const end end end end