Description:
copy working trunk (r383, before major changes to combine judge and to support grader message queue) to trunk git-svn-id: http://theory.cpe.ku.ac.th/grader/web/trunk@396 6386c4cd-e34a-4fa8-8920-d93eb39b512e
Commit status:
[Not Reviewed]
References:
merge default
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r188:0b607f9b89c1 - - 12 files changed: 14 inserted, 400 deleted

@@ -0,0 +1,10
1 + # Rails app directory
2 + RAILS_ROOT = "/home/jittat/web_grader"
3 +
4 + GRADER_ROOT = "/home/jittat/grader/scripts"
5 +
6 + # This load all required codes
7 + require File.join(File.dirname(__FILE__),'../lib/boot')
8 +
9 + # load the required environment file
10 + require File.dirname(__FILE__) + "/env_#{GRADER_ENV}.rb"
@@ -1,103 +1,92
1 # This file is auto-generated from the current state of the database. Instead of editing this file,
1 # This file is auto-generated from the current state of the database. Instead of editing this file,
2 # please use the migrations feature of Active Record to incrementally modify your database, and
2 # please use the migrations feature of Active Record to incrementally modify your database, and
3 # then regenerate this schema definition.
3 # then regenerate this schema definition.
4 #
4 #
5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
5 # Note that this schema.rb definition is the authoritative source for your database schema. If you need
6 # to create the application database on another system, you should be using db:schema:load, not running
6 # to create the application database on another system, you should be using db:schema:load, not running
7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
7 # all the migrations from scratch. The latter is a flawed and unsustainable approach (the more migrations
8 # you'll amass, the slower it'll run and the greater likelihood for issues).
8 # you'll amass, the slower it'll run and the greater likelihood for issues).
9 #
9 #
10 # It's strongly recommended to check this file into your version control system.
10 # It's strongly recommended to check this file into your version control system.
11
11
12 - ActiveRecord::Schema.define(:version => 20090429014554) do
12 + ActiveRecord::Schema.define(:version => 20090426131044) do
13
13
14 create_table "announcements", :force => true do |t|
14 create_table "announcements", :force => true do |t|
15 t.string "author"
15 t.string "author"
16 t.text "body"
16 t.text "body"
17 t.boolean "published"
17 t.boolean "published"
18 t.datetime "created_at"
18 t.datetime "created_at"
19 t.datetime "updated_at"
19 t.datetime "updated_at"
20 t.boolean "frontpage", :default => false
20 t.boolean "frontpage", :default => false
21 t.boolean "contest_only", :default => false
21 t.boolean "contest_only", :default => false
22 end
22 end
23
23
24 create_table "configurations", :force => true do |t|
24 create_table "configurations", :force => true do |t|
25 t.string "key"
25 t.string "key"
26 t.string "value_type"
26 t.string "value_type"
27 t.string "value"
27 t.string "value"
28 t.datetime "created_at"
28 t.datetime "created_at"
29 t.datetime "updated_at"
29 t.datetime "updated_at"
30 end
30 end
31
31
32 create_table "countries", :force => true do |t|
32 create_table "countries", :force => true do |t|
33 t.string "name"
33 t.string "name"
34 t.datetime "created_at"
34 t.datetime "created_at"
35 t.datetime "updated_at"
35 t.datetime "updated_at"
36 end
36 end
37
37
38 create_table "descriptions", :force => true do |t|
38 create_table "descriptions", :force => true do |t|
39 t.text "body"
39 t.text "body"
40 t.boolean "markdowned"
40 t.boolean "markdowned"
41 t.datetime "created_at"
41 t.datetime "created_at"
42 t.datetime "updated_at"
42 t.datetime "updated_at"
43 end
43 end
44
44
45 - create_table "grader_messages", :force => true do |t|
46 - t.integer "grader_process_id"
47 - t.integer "command"
48 - t.string "options"
49 - t.integer "target_id"
50 - t.boolean "taken"
51 - t.integer "taken_grader_process_id"
52 - t.datetime "created_at"
53 - t.datetime "updated_at"
54 - end
55 -
56 create_table "grader_processes", :force => true do |t|
45 create_table "grader_processes", :force => true do |t|
57 t.string "host", :limit => 20
46 t.string "host", :limit => 20
58 t.integer "pid"
47 t.integer "pid"
59 t.string "mode"
48 t.string "mode"
60 t.boolean "active"
49 t.boolean "active"
61 t.datetime "created_at"
50 t.datetime "created_at"
62 t.datetime "updated_at"
51 t.datetime "updated_at"
63 t.integer "task_id"
52 t.integer "task_id"
64 t.string "task_type"
53 t.string "task_type"
65 t.boolean "terminated"
54 t.boolean "terminated"
66 end
55 end
67
56
68 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
57 add_index "grader_processes", ["host", "pid"], :name => "index_grader_processes_on_ip_and_pid"
69
58
70 create_table "languages", :force => true do |t|
59 create_table "languages", :force => true do |t|
71 t.string "name", :limit => 10
60 t.string "name", :limit => 10
72 t.string "pretty_name"
61 t.string "pretty_name"
73 t.string "ext", :limit => 10
62 t.string "ext", :limit => 10
74 t.string "common_ext"
63 t.string "common_ext"
75 end
64 end
76
65
77 create_table "messages", :force => true do |t|
66 create_table "messages", :force => true do |t|
78 t.integer "sender_id"
67 t.integer "sender_id"
79 t.integer "receiver_id"
68 t.integer "receiver_id"
80 t.integer "replying_message_id"
69 t.integer "replying_message_id"
81 t.text "body"
70 t.text "body"
82 t.boolean "replied"
71 t.boolean "replied"
83 t.datetime "created_at"
72 t.datetime "created_at"
84 t.datetime "updated_at"
73 t.datetime "updated_at"
85 end
74 end
86
75
87 create_table "problems", :force => true do |t|
76 create_table "problems", :force => true do |t|
88 t.string "name", :limit => 30
77 t.string "name", :limit => 30
89 t.string "full_name"
78 t.string "full_name"
90 t.integer "full_score"
79 t.integer "full_score"
91 t.date "date_added"
80 t.date "date_added"
92 t.boolean "available"
81 t.boolean "available"
93 t.string "url"
82 t.string "url"
94 t.integer "description_id"
83 t.integer "description_id"
95 t.boolean "test_allowed"
84 t.boolean "test_allowed"
96 t.boolean "output_only"
85 t.boolean "output_only"
97 end
86 end
98
87
99 create_table "rights", :force => true do |t|
88 create_table "rights", :force => true do |t|
100 t.string "name"
89 t.string "name"
101 t.string "controller"
90 t.string "controller"
102 t.string "action"
91 t.string "action"
103 end
92 end
@@ -1,79 +1,79
1 #!/usr/bin/ruby
1 #!/usr/bin/ruby
2
2
3 def stop_grader(id)
3 def stop_grader(id)
4 if id==:all
4 if id==:all
5 File.open(File.dirname(__FILE__) + "/stop.all",'w').close
5 File.open(File.dirname(__FILE__) + "/stop.all",'w').close
6 else
6 else
7 File.open(File.dirname(__FILE__) + "/stop.#{id}",'w').close
7 File.open(File.dirname(__FILE__) + "/stop.#{id}",'w').close
8 end
8 end
9 end
9 end
10
10
11 def check_stopfile
11 def check_stopfile
12 FileTest.exist?(File.dirname(__FILE__) + "/stop.all") or
12 FileTest.exist?(File.dirname(__FILE__) + "/stop.all") or
13 FileTest.exist?(File.dirname(__FILE__) + "/stop.#{Process.pid}")
13 FileTest.exist?(File.dirname(__FILE__) + "/stop.#{Process.pid}")
14 end
14 end
15
15
16 def clear_stopfile
16 def clear_stopfile
17 if FileTest.exist?(File.dirname(__FILE__) + "/stop.#{Process.pid}")
17 if FileTest.exist?(File.dirname(__FILE__) + "/stop.#{Process.pid}")
18 system("rm " + File.dirname(__FILE__) + "/stop.#{Process.pid}")
18 system("rm " + File.dirname(__FILE__) + "/stop.#{Process.pid}")
19 end
19 end
20 end
20 end
21
21
22 def config
22 def config
23 Grader::Configuration.get_instance
23 Grader::Configuration.get_instance
24 end
24 end
25
25
26 def log_file_name
26 def log_file_name
27 if !File.exists?(config.log_dir)
27 if !File.exists?(config.log_dir)
28 raise "Log directory does not exist: #{config.log_dir}"
28 raise "Log directory does not exist: #{config.log_dir}"
29 end
29 end
30 config.log_dir +
30 config.log_dir +
31 - "/#{GRADER_ENV}.#{Process.pid}"
31 + "/#{GRADER_ENV}_#{config.grader_mode}.#{Process.pid}"
32 end
32 end
33
33
34 def log(str)
34 def log(str)
35 if config.talkative
35 if config.talkative
36 puts str
36 puts str
37 end
37 end
38 if config.logging
38 if config.logging
39 fp = File.open(log_file_name,"a")
39 fp = File.open(log_file_name,"a")
40 fp.puts("GRADER: #{Time.new.strftime("%H:%M")} #{str}")
40 fp.puts("GRADER: #{Time.new.strftime("%H:%M")} #{str}")
41 fp.close
41 fp.close
42 end
42 end
43 end
43 end
44
44
45 def display_manual
45 def display_manual
46 puts <<USAGE
46 puts <<USAGE
47 Grader.
47 Grader.
48 using: (1) grader
48 using: (1) grader
49 (2) grader environment [mode]
49 (2) grader environment [mode]
50 (3) grader stop [all|pids-list]
50 (3) grader stop [all|pids-list]
51 (4) grader --help
51 (4) grader --help
52 (1) call grader with environment = 'exam', mode = 'queue'
52 (1) call grader with environment = 'exam', mode = 'queue'
53 (2) possible modes are: 'queue', 'prob', 'test_request'
53 (2) possible modes are: 'queue', 'prob', 'test_request'
54 (3) create stop-file to stop running grader in queue mode
54 (3) create stop-file to stop running grader in queue mode
55 (4) You are here.
55 (4) You are here.
56 USAGE
56 USAGE
57 end
57 end
58
58
59 #########################################
59 #########################################
60 # main program
60 # main program
61 #########################################
61 #########################################
62
62
63 # with --help
63 # with --help
64 if (ARGV.length==1) and (/help/.match(ARGV[0]))
64 if (ARGV.length==1) and (/help/.match(ARGV[0]))
65 display_manual
65 display_manual
66 exit(0)
66 exit(0)
67 end
67 end
68
68
69 # reading environment and options
69 # reading environment and options
70 if (ARGV.length >= 1) and (ARGV[0]=='stop')
70 if (ARGV.length >= 1) and (ARGV[0]=='stop')
71 if ARGV.length==1
71 if ARGV.length==1
72 puts "you should specify pid-list or 'all'"
72 puts "you should specify pid-list or 'all'"
73 display_manual
73 display_manual
74 elsif (ARGV.length==2) and (ARGV[1]=='all')
74 elsif (ARGV.length==2) and (ARGV[1]=='all')
75 stop_grader(:all)
75 stop_grader(:all)
76 puts "A global stop file ('stop.all') created."
76 puts "A global stop file ('stop.all') created."
77 puts "You should remove it manually later."
77 puts "You should remove it manually later."
78 else
78 else
79 (1..ARGV.length-1).each do |i|
79 (1..ARGV.length-1).each do |i|
@@ -57,97 +57,97
57 source_name = "source.#{lang_ext}"
57 source_name = "source.#{lang_ext}"
58 end
58 end
59
59
60 begin
60 begin
61 grading_dir = @room_maker.produce_grading_room(submission)
61 grading_dir = @room_maker.produce_grading_room(submission)
62 @room_maker.save_source(submission,source_name)
62 @room_maker.save_source(submission,source_name)
63 problem_home = @room_maker.find_problem_home(submission)
63 problem_home = @room_maker.find_problem_home(submission)
64
64
65 # puts "GRADING DIR: #{grading_dir}"
65 # puts "GRADING DIR: #{grading_dir}"
66 # puts "PROBLEM DIR: #{problem_home}"
66 # puts "PROBLEM DIR: #{problem_home}"
67
67
68 dinit = DirInit::Manager.new(problem_home)
68 dinit = DirInit::Manager.new(problem_home)
69
69
70 dinit.setup do
70 dinit.setup do
71 copy_log = copy_script(problem_home)
71 copy_log = copy_script(problem_home)
72 save_copy_log(problem_home,copy_log)
72 save_copy_log(problem_home,copy_log)
73 end
73 end
74
74
75 call_judge(problem_home,language,grading_dir,source_name)
75 call_judge(problem_home,language,grading_dir,source_name)
76
76
77 @reporter.report(submission,"#{grading_dir}/test-result")
77 @reporter.report(submission,"#{grading_dir}/test-result")
78
78
79 dinit.teardown do
79 dinit.teardown do
80 copy_log = load_copy_log(problem_home)
80 copy_log = load_copy_log(problem_home)
81 clear_copy_log(problem_home)
81 clear_copy_log(problem_home)
82 clear_script(copy_log,problem_home)
82 clear_script(copy_log,problem_home)
83 end
83 end
84
84
85 rescue RuntimeError => msg
85 rescue RuntimeError => msg
86 @reporter.report_error(submission,"Grading error: #{msg}")
86 @reporter.report_error(submission,"Grading error: #{msg}")
87
87
88 ensure
88 ensure
89 @room_maker.clean_up(submission)
89 @room_maker.clean_up(submission)
90 Dir.chdir(current_dir) # this is really important
90 Dir.chdir(current_dir) # this is really important
91 end
91 end
92 end
92 end
93
93
94 protected
94 protected
95
95
96 def talk(str)
96 def talk(str)
97 if @config.talkative
97 if @config.talkative
98 puts str
98 puts str
99 end
99 end
100 end
100 end
101
101
102 def call_judge(problem_home,language,grading_dir,fname)
102 def call_judge(problem_home,language,grading_dir,fname)
103 ENV['PROBLEM_HOME'] = problem_home
103 ENV['PROBLEM_HOME'] = problem_home
104
104
105 - talk "Grading in #{grading_dir}"
105 + talk grading_dir
106 Dir.chdir grading_dir
106 Dir.chdir grading_dir
107 cmd = "#{problem_home}/script/judge #{language} #{fname}"
107 cmd = "#{problem_home}/script/judge #{language} #{fname}"
108 talk "CMD: #{cmd}"
108 talk "CMD: #{cmd}"
109 system(cmd)
109 system(cmd)
110 end
110 end
111
111
112 def get_std_script_dir
112 def get_std_script_dir
113 GRADER_ROOT + '/std-script'
113 GRADER_ROOT + '/std-script'
114 end
114 end
115
115
116 def copy_script(problem_home)
116 def copy_script(problem_home)
117 script_dir = "#{problem_home}/script"
117 script_dir = "#{problem_home}/script"
118 std_script_dir = get_std_script_dir
118 std_script_dir = get_std_script_dir
119
119
120 raise "std-script directory not found" if !FileTest.exist?(std_script_dir)
120 raise "std-script directory not found" if !FileTest.exist?(std_script_dir)
121
121
122 scripts = Dir[std_script_dir + '/*']
122 scripts = Dir[std_script_dir + '/*']
123
123
124 copied = []
124 copied = []
125
125
126 scripts.each do |s|
126 scripts.each do |s|
127 fname = File.basename(s)
127 fname = File.basename(s)
128 if !FileTest.exist?("#{script_dir}/#{fname}")
128 if !FileTest.exist?("#{script_dir}/#{fname}")
129 copied << fname
129 copied << fname
130 system("cp #{s} #{script_dir}")
130 system("cp #{s} #{script_dir}")
131 end
131 end
132 end
132 end
133
133
134 return copied
134 return copied
135 end
135 end
136
136
137 def copy_log_filename(problem_home)
137 def copy_log_filename(problem_home)
138 return File.join(problem_home, '.scripts_copied')
138 return File.join(problem_home, '.scripts_copied')
139 end
139 end
140
140
141 def save_copy_log(problem_home, log)
141 def save_copy_log(problem_home, log)
142 f = File.new(copy_log_filename(problem_home),"w")
142 f = File.new(copy_log_filename(problem_home),"w")
143 log.each do |fname|
143 log.each do |fname|
144 f.write("#{fname}\n")
144 f.write("#{fname}\n")
145 end
145 end
146 f.close
146 f.close
147 end
147 end
148
148
149 def load_copy_log(problem_home)
149 def load_copy_log(problem_home)
150 f = File.new(copy_log_filename(problem_home),"r")
150 f = File.new(copy_log_filename(problem_home),"r")
151 log = []
151 log = []
152 f.readlines.each do |line|
152 f.readlines.each do |line|
153 log << line.strip
153 log << line.strip
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
You need to be logged in to leave comments. Login now