testmycode/tmc-server

View on GitHub
app/background_tasks/refresh_course_task.rb

Summary

Maintainability
A
2 hrs
Test Coverage
# frozen_string_literal: true

require 'rust_langs_cli_executor'
require 'fileutils'
require 'course_refresh_database_updater'

class RefreshCourseTask
  def initialize
  end

  def run
    CourseTemplateRefresh.where(status: :not_started).each do |task|
      channel_id = task.course_template_id
      task.status = :in_progress
      task.save!
      ActionCable.server.broadcast("CourseTemplateRefreshChannel-#{channel_id}", { refresh_initialized: true })

      courses = Course.where(course_template_id: task.course_template_id)
      Rails.logger.info("Refreshing courses created from template #{task.course_template_id}")

      rust_output = RustLangsCliExecutor.refresh(task)
      task.langs_refresh_output = rust_output

      broadcast_to_channel(channel_id, 'Updating database', 0.95, '-')
      # Should we do this loop in CourseRefreshDatabaseUpdater?
      courses.each do |course|
        @refresh = CourseRefreshDatabaseUpdater.new.refresh_course(course, rust_output)
      end

      broadcast_to_channel(channel_id, 'Generating refresh report', 0.98, '-')
      CourseTemplateRefreshReport.create(course_template_refresh_id: task.id, refresh_errors: @refresh.errors, refresh_warnings: @refresh.warnings, refresh_notices: @refresh.notices, refresh_timings: @refresh.timings)

      broadcast_to_channel(channel_id, 'Cleaning up cache', 0.99, '-')
      if File.directory?(task.langs_refresh_output['output-data']['new-cache-path'])
        old_cache_path = task.course_template.cache_path
        task.course_template.increment_cached_version
        task.course_template.save!
        task.course_template.reload
        courses.each(&:save!)
        FileUtils.rm_rf(old_cache_path)
      end

      broadcast_to_channel(channel_id, 'Refresh completed', 1, '-', task.id)
      task.status = :complete
      task.percent_done = 1
      task.save!
    rescue => e
      Rails.logger.error("Course Refresh task #{task.id} failed:#{e}")
      Rails.logger.error(e.backtrace.join("\n"))
      CourseTemplateRefreshReport.create(course_template_refresh_id: task.id, refresh_errors: [e.backtrace.join("\n")], refresh_warnings: [], refresh_notices: [], refresh_timings: {})
      broadcast_to_channel(channel_id, 'Refresh crashed', 0, '-', task.id)

      task.status = :crashed
      task.percent_done = 0
      task.create_phase(e, 0)
      task.save!
    end
  end

  def wait_delay
    5
  end

  private
    def broadcast_to_channel(id, msg, percent, time, refresh_id = nil)
      Rails.logger.info("Broadcasting message: #{msg} to channel CourseTemplateRefreshChannel-#{id}, Percent done: #{percent}, Time: #{time}, Course Template Refresh ID: #{refresh_id}")
      ActionCable.server.broadcast("CourseTemplateRefreshChannel-#{id}", {
        message: msg,
        percent_done: percent,
        time: time,
        course_template_refresh_id: refresh_id,
      })
    end
end