moduleCanvasSyncmoduleJobs# ActiveJob class used to check the status of a pending Canvas report.# Re-enqueues itself if the report is still processing on Canvas.# Enqueues the ReportProcessor when the report has completed.classReportChecker<CanvasSync::JobREPORT_TIMEOUT=24.hoursCOMPILATION_TIMEOUT=1.hourMAX_TRIES=3classFatalReportError<::RuntimeError;enddiscard_onFatalReportError# @param report_name [Hash] e.g., 'provisioning_csv'# @param report_id [Integer]# @param processor [String] a stringified report processor class name# @param options [Hash] hash of options that will be passed to the job processor# @return [nil]defperform(report_name,report_id,processor,options,checker_context={})# rubocop:disable Metrics/AbcSizemax_tries=options[:report_max_tries]||batch_context[:report_max_tries]||MAX_TRIESaccount_id=options[:account_id]||batch_context[:account_id]||"self"report_status=CanvasSync.get_canvas_sync_client(batch_context).report_status(account_id,report_name,report_id)casereport_status["status"].downcasewhen"complete"CanvasSync::Jobs::ReportProcessorJob.perform_later(report_name,report_status["attachment"]["url"],processor,options,report_id,)when"error","deleted"checker_context[:failed_attempts]||=0checker_context[:failed_attempts]+=1failed_attempts=checker_context[:failed_attempts]message="Report failed to process; status was #{report_status} for report_name: #{report_name}, report_id: #{report_id}, #{current_organization.name}. This report has now failed #{checker_context[:failed_attempts]} time."# rubocop:disable Metrics/LineLengthRails.logger.error(message)iffailed_attempts>=max_triesRails.logger.error("This report has failed #{failed_attempts} times. Giving up.")raiseFatalReportError,messageelserestart_report(options,report_name,processor,checker_context)endelsereport_timeout=parse_timeout(options[:report_timeout]||batch_context[:report_timeout]||REPORT_TIMEOUT)iftimeout_met?(options[:sync_start_time],report_timeout)raiseFatalReportError,"Report appears to be stuck #{report_name}##{report_id}"endifreport_status["status"].downcase=='compiling'checker_context['compiling_since']||=DateTime.now.iso8601compilation_timeout=parse_timeout(options[:report_compilation_timeout]||batch_context[:report_compilation_timeout]||COMPILATION_TIMEOUT)iftimeout_met?(checker_context['compiling_since'],compilation_timeout)raiseFatalReportError,"Report appears to be stuck #{report_name}##{report_id}"endendCanvasSync::Jobs::ReportChecker.set(wait: report_checker_wait_time).perform_later(report_name,report_id,processor,options,checker_context)endendprotecteddeftimeout_met?(base_time,timeout_length)returnfalseunlessbase_time.present?&&timeout_length.present?DateTime.now>(DateTime.parse(base_time)+timeout_length)enddefparse_timeout(val)valenddefrestart_report(options,report_name,processor,checker_context)account_id=options[:account_id]||batch_context[:account_id]||"self"options[:sync_start_time]=DateTime.now.utc.iso8601new_context={}new_context[:failed_attempts]=checker_context[:failed_attempts]report_id=start_report(account_id,report_name,options[:report_params])CanvasSync::Jobs::ReportChecker.set(wait: report_checker_wait_time).perform_later(report_name,report_id,processor,options,new_context)enddefstart_report(account_id,report_name,report_params)report=CanvasSync.get_canvas_sync_client(batch_context).start_report(account_id,report_name,report_params)report["id"]endendendend