#!/usr/bin/ruby def stop_grader(id) if id==:all File.open(File.dirname(__FILE__) + "/stop.all",'w').close else File.open(File.dirname(__FILE__) + "/stop.#{id}",'w').close end end def check_stopfile FileTest.exist?(File.dirname(__FILE__) + "/stop.all") or FileTest.exist?(File.dirname(__FILE__) + "/stop.#{Process.pid}") end def clear_stopfile if FileTest.exist?(File.dirname(__FILE__) + "/stop.#{Process.pid}") system("rm " + File.dirname(__FILE__) + "/stop.#{Process.pid}") end end def config Grader::Configuration.get_instance end def log_file_name if !File.exists?(config.log_dir) raise "Log directory does not exist: #{config.log_dir}" end config.log_dir + "/#{GRADER_ENV}_#{config.grader_mode}.#{Process.pid}" end def log(str) if config.talkative puts str end if config.logging fp = File.open(log_file_name,"a") fp.puts("GRADER: #{Time.new.strftime("%H:%M")} #{str}") fp.close end end def display_manual puts <= 1) and (ARGV[0]=='stop') if ARGV.length==1 puts "you should specify pid-list or 'all'" display_manual elsif (ARGV.length==2) and (ARGV[1]=='all') stop_grader(:all) puts "A global stop file ('stop.all') created." puts "You should remove it manually later." else (1..ARGV.length-1).each do |i| stop_grader(ARGV[i]) end puts "stop file(s) created" end exit(0) end if check_stopfile puts "Stop file exists. Terminated." clear_stopfile exit(0) end grader_mode = 'queue' if ARGV.length >= 1 GRADER_ENV = ARGV[0] if ARGV.length >=2 grader_mode = ARGV[1] end else GRADER_ENV = 'exam' end puts "environment: #{GRADER_ENV}" require File.join(File.dirname(__FILE__),'config/environment') # add grader_mode to config # this is needed because method log needs it. TODO: clean this up class << config attr_accessor :grader_mode end config.grader_mode = grader_mode # reading rails environment log 'Reading rails environment' RAILS_ENV = config.rails_env require RAILS_ROOT + '/config/environment' # register grader process if config.report_grader grader_proc = GraderProcess.register(config.grader_hostname, Process.pid, grader_mode) else grader_proc = nil end #set loggin environment ENV['GRADER_LOGGING'] = log_file_name # # MAIN LOOP # case grader_mode when "queue", "test_request" log "Grader: #{grader_mode}" if grader_mode=="queue" engine = Grader::Engine.new else engine = Grader::Engine.new(Grader::TestRequestRoomMaker.new, Grader::TestRequestReporter.new) end runner = Grader::Runner.new(engine, grader_proc) while true if check_stopfile # created by calling grader stop clear_stopfile log "stopped (with stop file)" break end if grader_mode=="queue" task = runner.grade_oldest_task else task = runner.grade_oldest_test_request end if task==nil sleep(1) end end when "prob" engine = Grader::Engine.new runner = Grader::Runner.new(engine, grader_proc) grader_proc.report_active if grader_proc!=nil ARGV.shift ARGV.shift ARGV.each do |prob_name| prob = Problem.find_by_name(prob_name) if prob==nil puts "cannot find problem: #{prob_name}" else runner.grade_problem(prob) end end when "sub" engine = Grader::Engine.new runner = Grader::Runner.new(engine, grader_proc) grader_proc.report_active if grader_proc!=nil ARGV.shift ARGV.shift ARGV.each do |sub_id| puts "Grading #{sub_id}" begin submission = Submission.find(sub_id.to_i) rescue ActiveRecord::RecordNotFound puts "Record not found" submission = nil end if submission!=nil runner.grade_submission(submission) end end else display_manual exit(0) end # report inactive grader_proc.report_inactive if grader_proc!=nil