mark stuck pre_processing content migrations as failed

test plan:
* create a broken content migration by starting to
upload a file (it will be easier if it is somewhat large),
and then stopping or navigating away mid-upload.
* refresh the content migrations page to confirm that
the migration is in the 'Pre-processing' state
* assuming that you would rather not wait an hour for
the time out to trigger, manually trigger it by
opening the console:

ContentMigration.where(:id => ContentMigration.last
).update_all(:updated_at => Time.now.utc - 2.hour)

* refresh the content migrations page
* should mark as failed

fixes #CNVS-7483

Change-Id: If938aec626dd3685b7d634da09ccbc55dbbaca63
Reviewed-on: https://gerrit.instructure.com/23269
Reviewed-by: Bracken Mosbacker <bracken@instructure.com>
Product-Review: Bracken Mosbacker <bracken@instructure.com>
Tested-by: Jenkins <jenkins@instructure.com>
QA-Review: Hannah Bottalla <hannah@instructure.com>
This commit is contained in:
James Williams 2013-08-13 11:12:36 -06:00
parent ed051cf9b1
commit 0e98e6e248
4 changed files with 30 additions and 3 deletions
app
coffeescripts/views/content_migrations/subviews
controllers
models
spec/apis/v1

View File

@ -1,7 +1,8 @@
define [
'Backbone'
'jst/content_migrations/subviews/ChooseMigrationFile'
], (Backbone, template) ->
'i18n!content_migrations'
], (Backbone, template, I18n) ->
class ChooseMigrationFile extends Backbone.View
template: template
@ -43,12 +44,12 @@ define [
unless preAttachment?.name && fileElement
fileErrors.push
type: "required"
message: "You must select a file to import content from"
message: I18n.t("file_required", "You must select a file to import content from")
if @fileSize(fileElement) > @fileSizeLimit
fileErrors.push
type: "upload_limit_exceeded"
message: "You're migration cannot exceed #{@humanReadableSize(@fileSizeLimit)}"
message: I18n.t("file_too_large", "Your migration cannot exceed %{file_size}", file_size: @humanReadableSize(@fileSizeLimit))
errors.file = fileErrors if fileErrors.length
errors

View File

@ -95,6 +95,7 @@ class ContentMigrationsController < ApplicationController
Folder.root_folders(@context) # ensure course root folder exists so file imports can run
@migrations = Api.paginate(@context.content_migrations.order("id DESC"), self, api_v1_course_content_migration_list_url(@context))
@migrations.each{|mig| mig.check_for_pre_processing_timeout }
content_migration_json_hash = content_migrations_json(@migrations, @current_user, session)
if api_request?
@ -126,6 +127,7 @@ class ContentMigrationsController < ApplicationController
# @returns ContentMigration
def show
@content_migration = @context.content_migrations.find(params[:id])
@content_migration.check_for_pre_processing_timeout
render :json => content_migration_json(@content_migration, @current_user, session)
end
@ -229,6 +231,7 @@ class ContentMigrationsController < ApplicationController
# @returns ContentMigration
def update
@content_migration = @context.content_migrations.find(params[:id])
@content_migration.check_for_pre_processing_timeout
@plugin = Canvas::Plugin.find(@content_migration.migration_type)
update_migration

View File

@ -297,6 +297,7 @@ class ContentMigration < ActiveRecord::Base
def file_upload_success_callback(att)
if att.file_state == "available"
self.attachment = att
self.migration_issues.delete_all if self.migration_issues.any?
self.workflow_state = :pre_processed
self.save
self.queue_migration
@ -587,4 +588,13 @@ class ContentMigration < ActiveRecord::Base
Canvas::Migration::Helpers::SelectiveContentFormatter.new(self, base_url).get_content_list(type)
end
UPLOAD_TIMEOUT = 1.hour
def check_for_pre_processing_timeout
if self.pre_processing? && (self.updated_at.utc + UPLOAD_TIMEOUT) < Time.now.utc
add_error(t(:upload_timeout_error, "The file upload process timed out."))
self.workflow_state = :failed
job_progress.fail if job_progress && !skip_job_progress
self.save
end
end
end

View File

@ -131,6 +131,19 @@ describe ContentMigrationsController, :type => :integration do
json['settings']['source_course_id'].should == @course.id
json['settings']['source_course_name'].should == @course.name
end
it "should mark as failed if stuck in pre_processing" do
@migration.workflow_state = 'pre_processing'
@migration.save!
ContentMigration.where(:id => @migration.id).update_all(:updated_at => Time.now.utc - 2.hours)
json = api_call(:get, @migration_url, @params)
json['workflow_state'].should == 'failed'
json['migration_issues_count'].should == 1
@migration.reload
@migration.should be_failed
@migration.migration_issues.first.description.should == "The file upload process timed out."
end
end
describe 'create' do