<s> import json <EOL> import logging <EOL> import time <EOL> from django . db import transaction <EOL> from rpc_client import TimeoutServerProxy <EOL> from judge . result import result <EOL> from contest . models import ContestProblem , ContestRank , Contest , CONTEST_UNDERWAY <EOL> from problem . models import Problem <EOL> from submission . models import Submission <EOL> from account . models import User <EOL> from utils . cache import get_cache_redis <EOL> from . models import JudgeServer , JudgeWaitingQueue <EOL> logger = logging . getLogger ( "<STR_LIT>" ) <EOL> class JudgeDispatcher ( object ) : <EOL> def _none_to_false ( self , value ) : <EOL> if value is None : <EOL> return False <EOL> else : <EOL> return value <EOL> def __init__ ( self , submission_id , time_limit , memory_limit , test_case_id , spj , spj_language , spj_code , spj_version ) : <EOL> self . submission = Submission . objects . get ( id = submission_id ) <EOL> self . time_limit = time_limit <EOL> self . memory_limit = memory_limit <EOL> self . test_case_id = test_case_id <EOL> self . spj = spj <EOL> self . spj_language = spj_language <EOL> self . spj_code = spj_code <EOL> self . spj_version = spj_version <EOL> def choose_judge_server ( self ) : <EOL> with transaction . atomic ( ) : <EOL> servers = JudgeServer . objects . select_for_update ( ) . filter ( workload__lt = <NUM_LIT:100> , lock = False , status = True ) . order_by ( "<STR_LIT>" ) <EOL> if servers . exists ( ) : <EOL> server = servers . first ( ) <EOL> server . left_instance_number -= <NUM_LIT:1> <EOL> server . workload = <NUM_LIT:100> - int ( float ( server . left_instance_number ) / server . max_instance_number * <NUM_LIT:100> ) <EOL> server . save ( ) <EOL> return server <EOL> def release_judge_instance ( self , judge_server_id ) : <EOL> with transaction . atomic ( ) : <EOL> server = JudgeServer . objects . select_for_update ( ) . get ( id = judge_server_id ) <EOL> server . left_instance_number += <NUM_LIT:1> <EOL> server . workload = <NUM_LIT:100> - int ( float ( server . left_instance_number ) / server . max_instance_number * <NUM_LIT:100> ) <EOL> server . save ( ) <EOL> def judge ( self ) : <EOL> self . submission . judge_start_time = int ( time . time ( ) * <NUM_LIT:1000> ) <EOL> judge_server = self . choose_judge_server ( ) <EOL> if not judge_server : <EOL> JudgeWaitingQueue . objects . create ( submission_id = self . submission . id , time_limit = self . time_limit , <EOL> memory_limit = self . memory_limit , test_case_id = self . test_case_id , <EOL> spj = self . spj , spj_language = self . spj_language , spj_code = self . spj_code , <EOL> spj_version = self . spj_version ) <EOL> return <EOL> try : <EOL> s = TimeoutServerProxy ( "<STR_LIT>" + judge_server . ip + "<STR_LIT::>" + str ( judge_server . port ) , <EOL> timeout = <NUM_LIT:30> ) <EOL> data = s . run ( judge_server . token , self . submission . id , self . submission . language , <EOL> self . submission . code , self . time_limit , self . memory_limit , self . test_case_id , <EOL> self . spj , self . _none_to_false ( self . spj_language ) , <EOL> self . _none_to_false ( self . spj_code ) , self . _none_to_false ( self . spj_version ) ) <EOL> if data [ "<STR_LIT:code>" ] == <NUM_LIT:1> : <EOL> self . submission . result = result [ "<STR_LIT>" ] <EOL> self . submission . info = data [ "<STR_LIT:data>" ] [ "<STR_LIT:error>" ] <EOL> elif data [ "<STR_LIT:code>" ] == <NUM_LIT:2> : <EOL> self . submission . result = result [ "<STR_LIT>" ] <EOL> self . submission . info = data [ "<STR_LIT:data>" ] [ "<STR_LIT:error>" ] <EOL> elif data [ "<STR_LIT:code>" ] == <NUM_LIT:0> : <EOL> self . submission . result = data [ "<STR_LIT:data>" ] [ "<STR_LIT:result>" ] <EOL> self . submission . info = json . dumps ( data [ "<STR_LIT:data>" ] [ "<STR_LIT:info>" ] ) <EOL> self . submission . accepted_answer_time = data [ "<STR_LIT:data>" ] [ "<STR_LIT>" ] <EOL> except Exception as e : <EOL> self . submission . result = result [ "<STR_LIT>" ] <EOL> self . submission . info = str ( e ) <EOL> finally : <EOL> self . release_judge_instance ( judge_server . id ) <EOL> self . submission . judge_end_time = int ( time . time ( ) * <NUM_LIT:1000> ) <EOL> self . submission . save ( update_fields = [ "<STR_LIT>" , "<STR_LIT:result>" , "<STR_LIT:info>" , "<STR_LIT>" , "<STR_LIT>" ] ) <EOL> if self . submission . contest_id : <EOL> self . update_contest_problem_status ( ) <EOL> else : <EOL> self . update_problem_status ( ) <EOL> with transaction . atomic ( ) : <EOL> waiting_submissions = JudgeWaitingQueue . objects . select_for_update ( ) . all ( ) <EOL> if waiting_submissions . exists ( ) : <EOL> from submission . tasks import _judge <EOL> waiting_submission = waiting_submissions . first ( ) <EOL> waiting_submission . delete ( ) <EOL> _judge . delay ( submission_id = waiting_submission . submission_id , <EOL> time_limit = waiting_submission . time_limit , <EOL> memory_limit = waiting_submission . memory_limit , <EOL> test_case_id = waiting_submission . test_case_id , <EOL> spj = waiting_submission . spj , <EOL> spj_language = waiting_submission . spj_language , <EOL> spj_code = waiting_submission . spj_code , <EOL> spj_version = waiting_submission . spj_version ) <EOL> def update_problem_status ( self ) : <EOL> with transaction . atomic ( ) : <EOL> problem = Problem . objects . select_for_update ( ) . get ( id = self . submission . problem_id ) <EOL> problem . add_submission_number ( ) <EOL> user = User . objects . select_for_update ( ) . get ( id = self . submission . user_id ) <EOL> problems_status = user . problems_status <EOL> if "<STR_LIT>" not in problems_status : <EOL> problems_status [ "<STR_LIT>" ] = { } <EOL> user . userprofile . add_submission_number ( ) <EOL> if problems_status [ "<STR_LIT>" ] . get ( str ( problem . id ) , - <NUM_LIT:1> ) != <NUM_LIT:1> and self . submission . result == result [ "<STR_LIT>" ] : <EOL> user . userprofile . add_accepted_problem_number ( ) <EOL> if self . submission . result == result [ "<STR_LIT>" ] : <EOL> problem . add_ac_number ( ) <EOL> problems_status [ "<STR_LIT>" ] [ str ( problem . id ) ] = <NUM_LIT:1> <EOL> else : <EOL> problems_status [ "<STR_LIT>" ] [ str ( problem . id ) ] = <NUM_LIT:2> <EOL> user . problems_status = problems_status <EOL> user . save ( update_fields = [ "<STR_LIT>" ] ) <EOL> def update_contest_problem_status ( self ) : <EOL> contest = Contest . objects . get ( id = self . submission . contest_id ) <EOL> if contest . status != CONTEST_UNDERWAY : <EOL> logger . info ( "<STR_LIT>" + str ( contest . id ) + "<STR_LIT>" + self . submission . id ) <EOL> return <EOL> with transaction . atomic ( ) : <EOL> contest_problem = ContestProblem . objects . select_for_update ( ) . get ( contest = contest , id = self . submission . problem_id ) <EOL> contest_problem . add_submission_number ( ) <EOL> user = User . objects . select_for_update ( ) . get ( id = self . submission . user_id ) <EOL> problems_status = user . problems_status <EOL> if "<STR_LIT>" not in problems_status : <EOL> problems_status [ "<STR_LIT>" ] = { } <EOL> user . userprofile . add_submission_number ( ) <EOL> if problems_status [ "<STR_LIT>" ] . get ( str ( contest_problem . id ) , - <NUM_LIT:1> ) != <NUM_LIT:1> and self . submission . result == result [ "<STR_LIT>" ] : <EOL> user . userprofile . add_accepted_problem_number ( ) <EOL> if self . submission . result == result [ "<STR_LIT>" ] : <EOL> contest_problem . add_ac_number ( ) <EOL> problems_status [ "<STR_LIT>" ] [ str ( contest_problem . id ) ] = <NUM_LIT:1> <EOL> else : <EOL> problems_status [ "<STR_LIT>" ] [ str ( contest_problem . id ) ] = <NUM_LIT:2> <EOL> user . problems_status = problems_status <EOL> user . save ( update_fields = [ "<STR_LIT>" ] ) <EOL> self . update_contest_rank ( contest ) <EOL> def update_contest_rank ( self , contest ) : <EOL> if contest . real_time_rank : <EOL> get_cache_redis ( ) . delete ( str ( contest . id ) + "<STR_LIT>" ) <EOL> with transaction . atomic ( ) : <EOL> try : <EOL> contest_rank = ContestRank . objects . select_for_update ( ) . get ( contest = contest , user_id = self . submission . user_id ) <EOL> contest_rank . update_rank ( self . submission ) <EOL> except ContestRank . DoesNotExist : <EOL> ContestRank . objects . create ( contest = contest , user_id = self . submission . user_id ) . update_rank ( self . submission ) </s>
