@@ -34,8 +34,8 @@ def submission_result(data)
3434 update_hash [ :total_time ] = tasks . map { |i | i . time } . sum . round ( 0 )
3535 update_hash [ :total_memory ] = tasks . map { |i | i . rss } . max || 0
3636 end
37- submission . reload
38- retry_lock do
37+ retry_op do | is_first |
38+ submission . reload if not is_first
3939 submission . with_lock do
4040 submission . update ( **update_hash )
4141 end
@@ -48,7 +48,9 @@ def report_queued(data)
4848 # judge client will report every 10 seconds if has submission queued; 30 seconds otherwise
4949 Submission . where ( id : data [ :submission_ids ] ) . update_all ( updated_at : Time . now )
5050 # requeue dead submissions
51- Submission . where ( result : [ "received" , "Validating" ] , updated_at : ..40 . second . ago ) . update_all ( result : "queued" )
51+ retry_op do |is_first |
52+ Submission . where ( result : [ "received" , "Validating" ] , updated_at : ..40 . second . ago ) . update_all ( result : "queued" )
53+ end
5254 end
5355
5456 def fetch_submission ( data )
@@ -63,7 +65,8 @@ def fetch_submission(data)
6365 end
6466 flag = false
6567 if submission
66- retry_lock ( 3 ) do
68+ retry_op ( 3 ) do |is_first |
69+ submission . reload if not is_first
6770 submission . with_lock do
6871 if submission . result == "received"
6972 if i != n_retry
@@ -158,7 +161,8 @@ def update_task_results(data, submission)
158161 score = td_set_scores . sum { |x | x [ :score ] }
159162 max_score = BigDecimal ( '1e+12' ) - 1
160163 score = score . clamp ( -max_score , max_score ) . round ( 6 )
161- retry_lock do
164+ retry_op do |is_first |
165+ submission . reload if not is_first
162166 submission . with_lock do
163167 return if submission . new_rejudged and not [ 'Validating' , 'received' ] . include? ( submission . result )
164168 submission . update ( :score => score )
@@ -168,12 +172,14 @@ def update_task_results(data, submission)
168172 ActionCable . server . broadcast ( "submission_#{ submission . id } _overall" , { score : score , result : submission . result , id : submission . id } )
169173 end
170174
171- def retry_lock ( retry_times = 4 , interval = 0.3 )
175+ def retry_op ( retry_times = 4 , interval = 0.3 )
176+ is_first = true
172177 begin
173178 raise ActiveRecord ::Deadlocked if retry_times == 4
174- yield
179+ yield ( is_first )
175180 rescue ActiveRecord ::Deadlocked => e
176181 retry_times -= 1
182+ is_first = false
177183 if retry_times > 0
178184 sleep interval
179185 retry
0 commit comments