Description:
locks dir based on temp file, does not copy dir when copying scripts, added proper rescue for ln_s
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r103:933325ce824a - - 4 files changed: 4 inserted, 3 deleted

@@ -4,49 +4,49
4 # there are many concurrent processes that wants to modify the
4 # there are many concurrent processes that wants to modify the
5 # directory in the same way.
5 # directory in the same way.
6 #
6 #
7 # An example usage is when each process wants to copy some temporary
7 # An example usage is when each process wants to copy some temporary
8 # files to the directory and delete these files after finishing its
8 # files to the directory and delete these files after finishing its
9 # job. Problems may occur when the first process delete the files
9 # job. Problems may occur when the first process delete the files
10 # while the second process is still using the files.
10 # while the second process is still using the files.
11 #
11 #
12 # This library maintain a reference counter on the processes using the
12 # This library maintain a reference counter on the processes using the
13 # directory. It locks the dir to manage critical section when
13 # directory. It locks the dir to manage critical section when
14 # updating the reference counter.
14 # updating the reference counter.
15
15
16 module DirInit
16 module DirInit
17
17
18 class Manager
18 class Manager
19
19
20 def initialize(dir_name, usage_filename='.usage_counter')
20 def initialize(dir_name, usage_filename='.usage_counter')
21 @dir_name = dir_name
21 @dir_name = dir_name
22 @usage_filename = usage_filename
22 @usage_filename = usage_filename
23 end
23 end
24
24
25 # Check if someone has initialized the dir. If not, call block.
25 # Check if someone has initialized the dir. If not, call block.
26
26
27 def setup # :yields: block
27 def setup # :yields: block
28 - dir = File.new(@dir_name)
28 + dir = File.new(@dir_name + '/lockfile',"w+")
29 dir.flock(File::LOCK_EX)
29 dir.flock(File::LOCK_EX)
30 begin
30 begin
31 counter_filename = get_counter_filename
31 counter_filename = get_counter_filename
32 if File.exist? counter_filename
32 if File.exist? counter_filename
33 # someone is here
33 # someone is here
34 f = File.new(counter_filename,"r+")
34 f = File.new(counter_filename,"r+")
35 counter = f.read.to_i
35 counter = f.read.to_i
36 f.seek(0)
36 f.seek(0)
37 f.write("#{counter+1}\n")
37 f.write("#{counter+1}\n")
38 f.close
38 f.close
39 else
39 else
40 # i'm the first, create the counter file
40 # i'm the first, create the counter file
41 counter = 0
41 counter = 0
42 f = File.new(counter_filename,"w")
42 f = File.new(counter_filename,"w")
43 f.write("1\n")
43 f.write("1\n")
44 f.close
44 f.close
45 end
45 end
46
46
47 # if no one is here
47 # if no one is here
48 if counter == 0
48 if counter == 0
49 if block_given?
49 if block_given?
50 yield
50 yield
51 end
51 end
52 end
52 end
@@ -115,48 +115,49
115
115
116 talk grading_dir
116 talk grading_dir
117 Dir.chdir grading_dir
117 Dir.chdir grading_dir
118 cmd = "#{problem_home}/script/judge #{language} #{fname}"
118 cmd = "#{problem_home}/script/judge #{language} #{fname}"
119 talk "CMD: #{cmd}"
119 talk "CMD: #{cmd}"
120 system(cmd)
120 system(cmd)
121 end
121 end
122
122
123 def get_std_script_dir
123 def get_std_script_dir
124 GRADER_ROOT + '/std-script'
124 GRADER_ROOT + '/std-script'
125 end
125 end
126
126
127 def copy_script(problem_home)
127 def copy_script(problem_home)
128 script_dir = "#{problem_home}/script"
128 script_dir = "#{problem_home}/script"
129 std_script_dir = get_std_script_dir
129 std_script_dir = get_std_script_dir
130
130
131 raise "std-script directory not found" if !FileTest.exist?(std_script_dir)
131 raise "std-script directory not found" if !FileTest.exist?(std_script_dir)
132
132
133 scripts = Dir[std_script_dir + '/*']
133 scripts = Dir[std_script_dir + '/*']
134
134
135 copied = []
135 copied = []
136
136
137 scripts.each do |s|
137 scripts.each do |s|
138 fname = File.basename(s)
138 fname = File.basename(s)
139 + next if FileTest.directory?(s)
139 if !FileTest.exist?("#{script_dir}/#{fname}")
140 if !FileTest.exist?("#{script_dir}/#{fname}")
140 copied << fname
141 copied << fname
141 FileUtils.cp(s, "#{script_dir}")
142 FileUtils.cp(s, "#{script_dir}")
142 end
143 end
143 end
144 end
144
145
145 return copied
146 return copied
146 end
147 end
147
148
148 def copy_log_filename(problem_home)
149 def copy_log_filename(problem_home)
149 return File.join(problem_home, '.scripts_copied')
150 return File.join(problem_home, '.scripts_copied')
150 end
151 end
151
152
152 def save_copy_log(problem_home, log)
153 def save_copy_log(problem_home, log)
153 f = File.new(copy_log_filename(problem_home),"w")
154 f = File.new(copy_log_filename(problem_home),"w")
154 log.each do |fname|
155 log.each do |fname|
155 f.write("#{fname}\n")
156 f.write("#{fname}\n")
156 end
157 end
157 f.close
158 f.close
158 end
159 end
159
160
160 def load_copy_log(problem_home)
161 def load_copy_log(problem_home)
161 f = File.new(copy_log_filename(problem_home),"r")
162 f = File.new(copy_log_filename(problem_home),"r")
162 log = []
163 log = []
@@ -1,35 +1,35
1 #
1 #
2 # This part contains various test_request helpers for interfacing
2 # This part contains various test_request helpers for interfacing
3 # with Grader::Engine. There are TestRequestRoomMaker and
3 # with Grader::Engine. There are TestRequestRoomMaker and
4 # TestRequestReporter.
4 # TestRequestReporter.
5
5
6 module Grader
6 module Grader
7
7
8 def self.link_or_copy(src, des)
8 def self.link_or_copy(src, des)
9 begin
9 begin
10 FileUtils.ln_s(src, des)
10 FileUtils.ln_s(src, des)
11 - rescue
11 + rescue NotImplementedError
12 FileUtils.cp(src,des)
12 FileUtils.cp(src,des)
13 end
13 end
14 end
14 end
15
15
16 def self.call_and_log(error_message)
16 def self.call_and_log(error_message)
17 begin
17 begin
18 yield
18 yield
19 rescue
19 rescue
20 msg = "ERROR: #{error_message}"
20 msg = "ERROR: #{error_message}"
21 raise msg
21 raise msg
22 end
22 end
23 end
23 end
24
24
25 #
25 #
26 # A TestRequestRoomMaker is a helper object for Engine
26 # A TestRequestRoomMaker is a helper object for Engine
27 # - finds grading room: in user_result_dir/(user)/test_request/ ...
27 # - finds grading room: in user_result_dir/(user)/test_request/ ...
28 # - prepare problem configuration for grading --- basically it copy
28 # - prepare problem configuration for grading --- basically it copy
29 # all config files, and copy user's input into the testcase
29 # all config files, and copy user's input into the testcase
30 # directory. First, it finds the template from problem template
30 # directory. First, it finds the template from problem template
31 # directory; if it can't find a template, it'll use the template
31 # directory; if it can't find a template, it'll use the template
32 # from default template.
32 # from default template.
33 class TestRequestRoomMaker
33 class TestRequestRoomMaker
34 def initialize
34 def initialize
35 @config = Grader::Configuration.get_instance
35 @config = Grader::Configuration.get_instance
You need to be logged in to leave comments. Login now