mirror of
https://github.com/DMOJ/online-judge.git
synced 2024-11-25 16:32:37 +08:00
Leave a spare judge when rejudging if possible
This commit is contained in:
parent
051643342a
commit
d3b403afdf
@ -3,6 +3,8 @@ from collections import namedtuple
|
||||
from random import random
|
||||
from threading import RLock
|
||||
|
||||
from judge.judge_priority import REJUDGE_PRIORITY
|
||||
|
||||
try:
|
||||
from llist import dllist
|
||||
except ImportError:
|
||||
@ -27,8 +29,14 @@ class JudgeList(object):
|
||||
def _handle_free_judge(self, judge):
|
||||
with self.lock:
|
||||
node = self.queue.first
|
||||
priority = 0
|
||||
while node:
|
||||
if not isinstance(node.value, PriorityMarker):
|
||||
if isinstance(node.value, PriorityMarker):
|
||||
priority = node.value.priority + 1
|
||||
elif priority >= REJUDGE_PRIORITY and len(self.judges) > 1 and sum(
|
||||
not judge.working for judge in self.judges) <= 1:
|
||||
return
|
||||
else:
|
||||
id, problem, language, source, judge_id = node.value
|
||||
if judge.can_judge(problem, language, judge_id):
|
||||
self.submission_map[id] = judge
|
||||
@ -71,6 +79,13 @@ class JudgeList(object):
|
||||
pass
|
||||
self.judges.discard(judge)
|
||||
|
||||
# Since we reserve a judge for high priority submissions when there are more than one,
|
||||
# we'll need to start judging if there is exactly one judge and it's free.
|
||||
if len(self.judges) == 1:
|
||||
judge = next(iter(self.judges))
|
||||
if not judge.working:
|
||||
self._handle_free_judge(judge)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.judges)
|
||||
|
||||
@ -114,6 +129,10 @@ class JudgeList(object):
|
||||
logger.info('Specified judge %s is%savailable', judge_id, ' ' if candidates else ' not ')
|
||||
else:
|
||||
logger.info('Free judges: %d', len(candidates))
|
||||
|
||||
if len(candidates) == 1 and priority >= REJUDGE_PRIORITY:
|
||||
candidates = []
|
||||
|
||||
if candidates:
|
||||
# Schedule the submission on the judge reporting least load.
|
||||
judge = min(candidates, key=lambda judge: (judge.load, random()))
|
||||
|
4
judge/judge_priority.py
Normal file
4
judge/judge_priority.py
Normal file
@ -0,0 +1,4 @@
|
||||
CONTEST_SUBMISSION_PRIORITY = 0
|
||||
DEFAULT_PRIORITY = 1
|
||||
REJUDGE_PRIORITY = 2
|
||||
BATCH_REJUDGE_PRIORITY = 3
|
@ -8,6 +8,7 @@ from django.conf import settings
|
||||
from django.utils import timezone
|
||||
|
||||
from judge import event_poster as event
|
||||
from judge.judge_priority import BATCH_REJUDGE_PRIORITY, CONTEST_SUBMISSION_PRIORITY, DEFAULT_PRIORITY, REJUDGE_PRIORITY
|
||||
|
||||
logger = logging.getLogger('judge.judgeapi')
|
||||
size_pack = struct.Struct('!I')
|
||||
@ -52,11 +53,6 @@ def judge_request(packet, reply=True):
|
||||
def judge_submission(submission, rejudge=False, batch_rejudge=False, judge_id=None):
|
||||
from .models import ContestSubmission, Submission, SubmissionTestCase
|
||||
|
||||
CONTEST_SUBMISSION_PRIORITY = 0
|
||||
DEFAULT_PRIORITY = 1
|
||||
REJUDGE_PRIORITY = 2
|
||||
BATCH_REJUDGE_PRIORITY = 3
|
||||
|
||||
updates = {'time': None, 'memory': None, 'points': None, 'result': None, 'case_points': 0, 'case_total': 0,
|
||||
'error': None, 'rejudged_date': timezone.now() if rejudge or batch_rejudge else None, 'status': 'QU'}
|
||||
try:
|
||||
|
Loading…
Reference in New Issue
Block a user