diff --git a/conf/views.py b/conf/views.py index 3b5f4cf..875832d 100644 --- a/conf/views.py +++ b/conf/views.py @@ -123,7 +123,10 @@ class JudgeServerAPI(APIView): @validate_serializer(EditJudgeServerSerializer) @super_admin_required def put(self, request): - JudgeServer.objects.filter(id=request.data["id"]).update(is_disabled=request.data["is_disabled"]) + is_disabled = request.data.get("is_disabled", False) + JudgeServer.objects.filter(id=request.data["id"]).update(is_disabled=is_disabled) + if not is_disabled: + process_pending_task() return self.success() diff --git a/deploy/entrypoint.sh b/deploy/entrypoint.sh index ee7e46d..fdc589e 100755 --- a/deploy/entrypoint.sh +++ b/deploy/entrypoint.sh @@ -52,6 +52,7 @@ do python manage.py migrate --no-input && python manage.py inituser --username=root --password=rootroot --action=create_super_admin && echo "from options.options import SysOptions; SysOptions.judge_server_token='$JUDGE_SERVER_TOKEN'" | python manage.py shell && + echo "from conf.models import JudgeServer; JudgeServer.objects.update(task_number=0)" | python manage.py shell && break n=$(($n+1)) echo "Failed to migrate, going to retry..." diff --git a/deploy/nginx/locations.conf b/deploy/nginx/locations.conf index a096ffa..da7fa38 100644 --- a/deploy/nginx/locations.conf +++ b/deploy/nginx/locations.conf @@ -6,11 +6,6 @@ location /api { include api_proxy.conf; } -location /data/ { - internal; - alias /data/; # note that trailing slash -} - location /admin { root /app/dist/admin; try_files $uri $uri/ /index.html =404; diff --git a/judge/dispatcher.py b/judge/dispatcher.py index 0e14a19..c448095 100644 --- a/judge/dispatcher.py +++ b/judge/dispatcher.py @@ -48,18 +48,18 @@ class DispatcherBase(object): with transaction.atomic(): servers = JudgeServer.objects.select_for_update().filter(is_disabled=False).order_by("task_number") servers = [s for s in servers if s.status == "normal"] - if servers: - server = servers[0] - server.used_instance_number = F("task_number") + 1 - server.save() - return server + for server in servers: + if server.task_number <= server.cpu_core * 2: + server.task_number = F("task_number") + 1 + server.save() + return server @staticmethod def release_judge_server(judge_server_id): with transaction.atomic(): # 使用原子操作, 同时因为use和release中间间隔了判题过程,需要重新查询一下 server = JudgeServer.objects.get(id=judge_server_id) - server.used_instance_number = F("task_number") - 1 + server.task_number = F("task_number") - 1 server.save() diff --git a/problem/views/admin.py b/problem/views/admin.py index 7a71920..549f068 100644 --- a/problem/views/admin.py +++ b/problem/views/admin.py @@ -2,26 +2,24 @@ import hashlib import json import os import shutil -import zipfile import tempfile +import zipfile from wsgiref.util import FileWrapper from django.conf import settings -from django.http import StreamingHttpResponse, HttpResponse, FileResponse from django.db import transaction +from django.http import StreamingHttpResponse, FileResponse from account.decorators import problem_permission_required, ensure_created_by +from contest.models import Contest, ContestStatus +from fps.parser import FPSHelper, FPSParser from judge.dispatcher import SPJCompiler from judge.languages import language_names -from contest.models import Contest, ContestStatus from submission.models import Submission, JudgeStatus -from fps.parser import FPSHelper, FPSParser from utils.api import APIView, CSRFExemptAPIView, validate_serializer, APIError +from utils.constants import Difficulty from utils.shortcuts import rand_str, natural_sort_key from utils.tasks import delete_files -from utils.constants import Difficulty - -from ..utils import TEMPLATE_BASE, build_problem_template from ..models import Problem, ProblemRuleType, ProblemTag from ..serializers import (CreateContestProblemSerializer, CompileSPJSerializer, CreateProblemSerializer, EditProblemSerializer, EditContestProblemSerializer, @@ -29,6 +27,7 @@ from ..serializers import (CreateContestProblemSerializer, CompileSPJSerializer, AddContestProblemSerializer, ExportProblemSerializer, ExportProblemRequestSerialzier, UploadProblemForm, ImportProblemSerializer, FPSProblemSerializer) +from ..utils import TEMPLATE_BASE, build_problem_template class TestCaseZipProcessor(object): @@ -137,12 +136,8 @@ class TestCaseAPI(CSRFExemptAPIView, TestCaseZipProcessor): with zipfile.ZipFile(file_name, "w") as file: for test_case in name_list: file.write(f"{test_case_dir}/{test_case}", test_case) - if os.environ.get("OJ_ENV") == "production": - response = HttpResponse() - response["X-Accel-Redirect"] = file_name - else: - response = StreamingHttpResponse(FileWrapper(open(file_name, "rb")), - content_type="application/octet-stream") + response = StreamingHttpResponse(FileWrapper(open(file_name, "rb")), + content_type="application/octet-stream") response["Content-Disposition"] = f"attachment; filename=problem_{problem.id}_test_cases.zip" response["Content-Length"] = os.path.getsize(file_name)