mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2024-09-21 00:13:18 +00:00
add problem_statistic_info
This commit is contained in:
parent
df185a233f
commit
1587192ff9
@ -14,7 +14,7 @@ from contest.models import ContestRuleType, ACMContestRank, OIContestRank
|
|||||||
from judge.languages import languages
|
from judge.languages import languages
|
||||||
from problem.models import Problem, ProblemRuleType, ContestProblem
|
from problem.models import Problem, ProblemRuleType, ContestProblem
|
||||||
from submission.models import JudgeStatus, Submission
|
from submission.models import JudgeStatus, Submission
|
||||||
from utils.cache import judge_queue_cache
|
from utils.cache import judge_cache
|
||||||
from utils.constants import CacheKey
|
from utils.constants import CacheKey
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -22,10 +22,10 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
# 继续处理在队列中的问题
|
# 继续处理在队列中的问题
|
||||||
def process_pending_task():
|
def process_pending_task():
|
||||||
if judge_queue_cache.llen(CacheKey.waiting_queue):
|
if judge_cache.llen(CacheKey.waiting_queue):
|
||||||
# 防止循环引入
|
# 防止循环引入
|
||||||
from judge.tasks import judge_task
|
from judge.tasks import judge_task
|
||||||
data = json.loads(judge_queue_cache.rpop(CacheKey.waiting_queue))
|
data = json.loads(judge_cache.rpop(CacheKey.waiting_queue))
|
||||||
judge_task.delay(**data)
|
judge_task.delay(**data)
|
||||||
|
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ class JudgeDispatcher(object):
|
|||||||
def __init__(self, submission_id, problem_id):
|
def __init__(self, submission_id, problem_id):
|
||||||
token = JudgeServerToken.objects.first().token
|
token = JudgeServerToken.objects.first().token
|
||||||
self.token = hashlib.sha256(token.encode("utf-8")).hexdigest()
|
self.token = hashlib.sha256(token.encode("utf-8")).hexdigest()
|
||||||
self.redis_conn = judge_queue_cache
|
self.redis_conn = judge_cache
|
||||||
self.submission = Submission.objects.get(pk=submission_id)
|
self.submission = Submission.objects.get(pk=submission_id)
|
||||||
if self.submission.contest_id:
|
if self.submission.contest_id:
|
||||||
self.problem = ContestProblem.objects.select_related("contest")\
|
self.problem = ContestProblem.objects.select_related("contest")\
|
||||||
@ -98,8 +98,8 @@ class JudgeDispatcher(object):
|
|||||||
"spj_compile_config": spj_config.get("compile"),
|
"spj_compile_config": spj_config.get("compile"),
|
||||||
"spj_src": self.problem.spj_code
|
"spj_src": self.problem.spj_code
|
||||||
}
|
}
|
||||||
self.submission.result = JudgeStatus.JUDGING
|
|
||||||
self.submission.save()
|
Submission.objects.filter(id=self.submission.id).update(result=JudgeStatus.JUDGING)
|
||||||
|
|
||||||
# TODO: try catch
|
# TODO: try catch
|
||||||
resp = self._request(urljoin(server.service_url, "/judge"), data=data)
|
resp = self._request(urljoin(server.service_url, "/judge"), data=data)
|
||||||
@ -123,11 +123,12 @@ class JudgeDispatcher(object):
|
|||||||
self.submission.save()
|
self.submission.save()
|
||||||
self.release_judge_res(server.id)
|
self.release_judge_res(server.id)
|
||||||
|
|
||||||
|
self.update_problem_status()
|
||||||
|
|
||||||
if self.submission.contest_id:
|
if self.submission.contest_id:
|
||||||
self.update_contest_problem_status()
|
|
||||||
self.update_contest_rank()
|
self.update_contest_rank()
|
||||||
else:
|
else:
|
||||||
self.update_problem_status()
|
self.update_user_profile()
|
||||||
# 至此判题结束,尝试处理任务队列中剩余的任务
|
# 至此判题结束,尝试处理任务队列中剩余的任务
|
||||||
process_pending_task()
|
process_pending_task()
|
||||||
|
|
||||||
@ -138,13 +139,21 @@ class JudgeDispatcher(object):
|
|||||||
return self._request(urljoin(service_url, "compile_spj"), data=data)
|
return self._request(urljoin(service_url, "compile_spj"), data=data)
|
||||||
|
|
||||||
def update_problem_status(self):
|
def update_problem_status(self):
|
||||||
with transaction.atomic():
|
|
||||||
# 更新problem计数器
|
|
||||||
self.problem = Problem.objects.select_for_update().get(id=self.problem.id)
|
|
||||||
self.problem.add_submission_number()
|
self.problem.add_submission_number()
|
||||||
if self.submission.result == JudgeStatus.ACCEPTED:
|
if self.submission.result == JudgeStatus.ACCEPTED:
|
||||||
self.problem.add_ac_number()
|
self.problem.add_ac_number()
|
||||||
|
with transaction.atomic():
|
||||||
|
if self.submission.contest_id:
|
||||||
|
problem = ContestProblem.objects.select_for_update().get(_id=self.problem.id, contest_id=self.contest.id)
|
||||||
|
else:
|
||||||
|
problem = Problem.objects.select_related().get(_id=self.problem.id)
|
||||||
|
info = problem.statistic_info
|
||||||
|
info[self.submission.result] = info.get(self.submission.result, 0) + 1
|
||||||
|
problem.statistic_info = info
|
||||||
|
problem.save(update_fields=["statistic_info"])
|
||||||
|
|
||||||
|
def update_user_profile(self):
|
||||||
|
with transaction.atomic():
|
||||||
# 更新user profile
|
# 更新user profile
|
||||||
user = User.objects.select_for_update().get(id=self.submission.user_id)
|
user = User.objects.select_for_update().get(id=self.submission.user_id)
|
||||||
user_profile = user.userprofile
|
user_profile = user.userprofile
|
||||||
@ -163,13 +172,6 @@ class JudgeDispatcher(object):
|
|||||||
user_profile.problems_status = problems_status
|
user_profile.problems_status = problems_status
|
||||||
user_profile.save(update_fields=["problems_status"])
|
user_profile.save(update_fields=["problems_status"])
|
||||||
|
|
||||||
def update_contest_problem_status(self):
|
|
||||||
with transaction.atomic():
|
|
||||||
problem = ContestProblem.objects.select_for_update().get(id=self.problem.id)
|
|
||||||
problem.add_submission_number()
|
|
||||||
if self.submission.result == JudgeStatus.ACCEPTED:
|
|
||||||
problem.add_ac_number()
|
|
||||||
|
|
||||||
def update_contest_rank(self):
|
def update_contest_rank(self):
|
||||||
if self.contest.real_time_rank:
|
if self.contest.real_time_rank:
|
||||||
cache.delete(str(self.contest.id) + "_rank_cache")
|
cache.delete(str(self.contest.id) + "_rank_cache")
|
||||||
|
26
problem/migrations/0005_auto_20170815_1258.py
Normal file
26
problem/migrations/0005_auto_20170815_1258.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.9.6 on 2017-08-15 12:58
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
import jsonfield.fields
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('problem', '0004_auto_20170501_0637'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='contestproblem',
|
||||||
|
name='statistic_info',
|
||||||
|
field=jsonfield.fields.JSONField(default={}),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='problem',
|
||||||
|
name='statistic_info',
|
||||||
|
field=jsonfield.fields.JSONField(default={}),
|
||||||
|
),
|
||||||
|
]
|
@ -57,6 +57,9 @@ class AbstractProblem(models.Model):
|
|||||||
source = models.CharField(max_length=200, blank=True, null=True)
|
source = models.CharField(max_length=200, blank=True, null=True)
|
||||||
total_submit_number = models.BigIntegerField(default=0)
|
total_submit_number = models.BigIntegerField(default=0)
|
||||||
total_accepted_number = models.BigIntegerField(default=0)
|
total_accepted_number = models.BigIntegerField(default=0)
|
||||||
|
# {0: 0, 1: 0, 2: 0, 3: 0 ...}
|
||||||
|
# the first number means JudgeStatus, the second number present count
|
||||||
|
statistic_info = JSONField(default={})
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = "problem"
|
db_table = "problem"
|
||||||
|
@ -95,21 +95,21 @@ class SubmissionListAPI(APIView):
|
|||||||
if request.GET.get("contest_id"):
|
if request.GET.get("contest_id"):
|
||||||
return self._get_contest_submission_list(request)
|
return self._get_contest_submission_list(request)
|
||||||
|
|
||||||
subs = Submission.objects.filter(contest_id__isnull=True)
|
submissions = Submission.objects.filter(contest_id__isnull=True)
|
||||||
return self.process_submissions(request, subs)
|
return self.process_submissions(request, submissions)
|
||||||
|
|
||||||
@check_contest_permission
|
@check_contest_permission
|
||||||
def _get_contest_submission_list(self, request):
|
def _get_contest_submission_list(self, request):
|
||||||
subs = Submission.objects.filter(contest_id=self.contest.id)
|
subs = Submission.objects.filter(contest_id=self.contest.id)
|
||||||
return self.process_submissions(request, subs)
|
return self.process_submissions(request, subs)
|
||||||
|
|
||||||
def process_submissions(self, request, subs):
|
def process_submissions(self, request, submissions):
|
||||||
problem_id = request.GET.get("problem_id")
|
problem_id = request.GET.get("problem_id")
|
||||||
if problem_id:
|
if problem_id:
|
||||||
subs = subs.filter(problem_id=problem_id)
|
submissions = submissions.filter(problem_id=problem_id)
|
||||||
|
|
||||||
if request.GET.get("myself") and request.GET["myself"] == "1":
|
if request.GET.get("myself") and request.GET["myself"] == "1":
|
||||||
subs = subs.filter(user_id=request.user.id)
|
submissions = submissions.filter(user_id=request.user.id)
|
||||||
data = self.paginate_data(request, subs)
|
data = self.paginate_data(request, submissions)
|
||||||
data["results"] = SubmissionListSerializer(data["results"], many=True, user=request.user).data
|
data["results"] = SubmissionListSerializer(data["results"], many=True, user=request.user).data
|
||||||
return self.success(data)
|
return self.success(data)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django_redis import get_redis_connection
|
from django_redis import get_redis_connection
|
||||||
|
|
||||||
judge_queue_cache = get_redis_connection(settings.CACHE_JUDGE_QUEUE)
|
judge_cache = get_redis_connection(settings.CACHE_JUDGE_QUEUE)
|
||||||
throttling_cache = get_redis_connection(settings.CACHE_THROTTLING)
|
throttling_cache = get_redis_connection(settings.CACHE_THROTTLING)
|
||||||
default_cache = get_redis_connection("default")
|
default_cache = get_redis_connection("default")
|
||||||
|
Loading…
Reference in New Issue
Block a user