diff --git a/judge_dispatcher/models.py b/judge_dispatcher/models.py index 20fbc1b3..68ef60dc 100644 --- a/judge_dispatcher/models.py +++ b/judge_dispatcher/models.py @@ -8,12 +8,18 @@ class JudgeServer(models.Model): # 这个服务器最大可能运行的判题实例数量 max_instance_number = models.IntegerField() left_instance_number = models.IntegerField() + workload = models.IntegerField(default=0) token = models.CharField(max_length=30) # 进行测试用例同步的时候加锁 lock = models.BooleanField(default=False) # status 为 false 的时候代表不使用这个服务器 status = models.BooleanField(default=True) + def use_judge_instance(self): + self.left_instance_number -= 1 + self.workload = 100 - int(self.left_instance_number / self.max_instance_number) + self.save() + class Meta: db_table = "judge_server" diff --git a/judge_dispatcher/tasks.py b/judge_dispatcher/tasks.py index 4ad333d3..68e26ce2 100644 --- a/judge_dispatcher/tasks.py +++ b/judge_dispatcher/tasks.py @@ -5,7 +5,6 @@ import time from django.db import transaction -from celery import shared_task from rpc_client import TimeoutServerProxy from judge.result import result @@ -14,6 +13,7 @@ from problem.models import Problem from submission.models import Submission from account.models import User from utils.cache import get_cache_redis +from .models import JudgeServer,JudgeWaitingQueue logger = logging.getLogger("app_info") @@ -27,12 +27,18 @@ class JudgeDispatcher(object): self.user = User.objects.get(id=submission.user_id) def choose_judge_server(self): - pass + servers = JudgeServer.objects.filter(workload__lt=100, lock=False, status=True).order_by("-workload") + if servers.exists(): + return servers[0] def judge(self): self.submission.judge_start_time = int(time.time() * 1000) try: judge_server = self.choose_judge_server() + # 如果没有合适的判题服务器,就放入等待队列中等待判题 + if not judge_server: + JudgeWaitingQueue.objects.create(submission_id=self.submission.id) + return s = TimeoutServerProxy(judge_server.ip + ":" + judge_server.port, timeout=20) data = s.run(self.submission.id, self.submission.language_code, diff --git a/submission/views.py b/submission/views.py index 94043cf4..3a54bc92 100644 --- a/submission/views.py +++ b/submission/views.py @@ -7,7 +7,7 @@ from django.shortcuts import render from django.core.paginator import Paginator from rest_framework.views import APIView -from judge_dispatcher.tasks import create_judge_task +from judge_dispatcher.tasks import JudgeDispatcher from account.decorators import login_required, super_admin_required from account.models import SUPER_ADMIN, User from problem.models import Problem @@ -23,9 +23,8 @@ from .serializers import (CreateSubmissionSerializer, SubmissionSerializer, logger = logging.getLogger("app_info") -def _judge(submission_id, code, language_code, time_limit, memory_limit, test_case_id): - create_judge_task.delay(submission_id, code, language_code, time_limit, memory_limit, test_case_id) - get_cache_redis().incr("judge_queue_length") +def _judge(submission, time_limit, memory_limit, test_case_id): + JudgeDispatcher(submission, time_limit, memory_limit, test_case_id).judge() class SubmissionAPIView(APIView): @@ -49,7 +48,7 @@ class SubmissionAPIView(APIView): problem_id=problem.id) try: - _judge(submission.id, submission.code, submission.language, problem.time_limit, problem.memory_limit, problem.test_case_id) + _judge(submission, problem.time_limit, problem.memory_limit, problem.test_case_id) except Exception as e: logger.error(e) return error_response(u"提交判题任务失败") @@ -94,7 +93,7 @@ class ContestSubmissionAPIView(APIView): code=data["code"], problem_id=problem.id) try: - _judge(submission.id, submission.code, submission.language, problem.time_limit, problem.memory_limit, problem.test_case_id) + _judge(submission, problem.time_limit, problem.memory_limit, problem.test_case_id) except Exception as e: logger.error(e) return error_response(u"提交判题任务失败") @@ -279,7 +278,7 @@ class SubmissionRejudgeAdminAPIView(APIView): except Problem.DoesNotExist: return error_response(u"题目不存在") try: - _judge(submission.id, submission.code, submission.language, problem.time_limit, problem.memory_limit, problem.test_case_id) + _judge(submission, problem.time_limit, problem.memory_limit, problem.test_case_id) except Exception as e: logger.error(e) return error_response(u"提交判题任务失败")