Class: BatchImportRunner

Inherits:
JobRunner show all
Defined in:
backend/app/lib/batch_import_runner.rb

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods inherited from JobRunner

#canceled, for, inherited, #initialize, register_runner

Constructor Details

This class inherits a constructor from JobRunner

Class Method Details

+ (Object) instance_for(job)



44
45
46
47
48
49
50
# File 'backend/app/lib/batch_import_runner.rb', line 44

def self.instance_for(job)
  if job.job_type == "import_job"
    self.new(job)
  else
    nil
  end
end

Instance Method Details

- (Object) run



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'backend/app/lib/batch_import_runner.rb', line 53

def run
  ticker = Ticker.new(@job)

  last_error = nil
  batch = nil
  success = false

  filenames = @json.job['filenames'] || []

  # Wrap the import in a transaction if the DB supports MVCC
  begin
    DB.open(DB.supports_mvcc?,
            :retry_on_optimistic_locking_fail => true) do

      begin
        @job.job_files.each_with_index do |input_file, i|
          ticker.log(("=" * 50) + "\n#{filenames[i]}\n" + ("=" * 50)) if filenames[i]
          converter = Converter.for(@json.job['import_type'], input_file.file_path)
          begin
            RequestContext.open(:create_enums => true,
                                :current_username => @job.owner.username,
                                :repo_id => @job.repo_id) do

              converter.run

              File.open(converter.get_output_path, "r") do |fh|
                batch = StreamingImport.new(fh, ticker, @import_canceled)
                batch.process
                log_created_uris(batch)
                success = true
              end
            end
          ensure
            converter.remove_files
          end
        end
      rescue ImportCanceled
        raise Sequel::Rollback
      rescue JSONModel::ValidationException, ImportException, Converter::ConverterMappingError, Sequel::ValidationFailed, ReferenceError => e
        # Note: we deliberately don't catch Sequel::DatabaseError here.  The
        # outer call to DB.open will catch that exception and retry the
        # import for us.
        last_error = e

        # Roll back the transaction (if there is one)
        raise Sequel::Rollback
      end
    end
  rescue
    last_error = $!
  end

  if last_error
   
    ticker.log("\n\n" ) 
    ticker.log( "!" * 50 ) 
    ticker.log( "IMPORT ERROR" ) 
    ticker.log( "!" * 50 ) 
    ticker.log("\n\n" ) 
    
    if  last_error.respond_to?(:errors)
   
      ticker.log("#{last_error}") if last_error.errors.empty? # just spit it out if there's not explicit errors
      
      ticker.log("The following errors were found:\n") 
      
      last_error.errors.each_pair { |k,v| ticker.log("\t#{k.to_s} : #{v.join(' -- ')}" ) }
      
      if last_error.is_a?(Sequel::ValidationFailed) 
        ticker.log("\n" ) 
        ticker.log("%" * 50 ) 
        ticker.log("\n Full Error Message:\n #{last_error.to_s}\n\n") 
      end 
      
      if ( last_error.respond_to?(:invalid_object) && last_error.invalid_object ) 
        ticker.log("\n\n For #{ last_error.invalid_object.class }: \n #{ last_error.invalid_object.inspect  }")  
      end 
      
      if ( last_error.respond_to?(:import_context) && last_error.import_context )
        ticker.log("\n\nIn : \n #{ CGI.escapeHTML( last_error.import_context ) } ")
        ticker.log("\n\n") 
      end 
    else
      ticker.log("Error: #{CGI.escapeHTML(  last_error.inspect )}")
    end
    ticker.log("!" * 50 ) 
    raise last_error
  end
end