From 124a402ade3fd37e1e3218c1bce6c463c48e5886 Mon Sep 17 00:00:00 2001 From: virusdefender <1670873886@qq.com> Date: Tue, 8 Dec 2015 14:51:50 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=AB=9E=E6=80=81=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E5=AF=BC=E8=87=B4=E7=9A=84=E8=AE=A1=E6=95=B0=E5=99=A8?= =?UTF-8?q?=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- judge_dispatcher/models.py | 20 ++++++++++++-------- judge_dispatcher/tasks.py | 27 +++++++++++++++------------ 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/judge_dispatcher/models.py b/judge_dispatcher/models.py index 4e75bca9..6b2a4dee 100644 --- a/judge_dispatcher/models.py +++ b/judge_dispatcher/models.py @@ -16,16 +16,20 @@ class JudgeServer(models.Model): status = models.BooleanField(default=True) def use_judge_instance(self): - self.left_instance_number -= 1 - self.workload = 100 - int(float(self.left_instance_number) / self.max_instance_number * 100) - print self.left_instance_number, self.workload - self.save() + # 因为use 和 release 中间是判题时间,可能这个 model 的数据已经被修改了,所以不能直接使用self.xxx,否则取到的是旧数据 + server = JudgeServer.objects.select_for_update().get(id=self.id) + server.left_instance_number -= 1 + server.workload = 100 - int(float(server.left_instance_number) / server.max_instance_number * 100) + print "\n ---- use", server.left_instance_number, server.workload + server.save() def release_judge_instance(self): - self.left_instance_number += 1 - self.workload = 100 - int(float(self.left_instance_number) / self.max_instance_number * 100) - print self.left_instance_number, self.workload - self.save() + # 使用原子操作 + server = JudgeServer.objects.select_for_update().get(id=self.id) + server.left_instance_number += 1 + server.workload = 100 - int(float(server.left_instance_number) / server.max_instance_number * 100) + print "\n ---- release", server.left_instance_number, server.workload + server.save() class Meta: db_table = "judge_server" diff --git a/judge_dispatcher/tasks.py b/judge_dispatcher/tasks.py index 38d9ef1f..c487eefa 100644 --- a/judge_dispatcher/tasks.py +++ b/judge_dispatcher/tasks.py @@ -26,31 +26,32 @@ class JudgeDispatcher(object): self.memory_limit = memory_limit self.test_case_id = test_case_id self.user = User.objects.get(id=submission.user_id) + print "init init" def choose_judge_server(self): servers = JudgeServer.objects.filter(workload__lt=100, lock=False, status=True).order_by("-workload") if servers.exists(): - server = servers[0] - server.use_judge_instance() - return server + return servers.first() def judge(self, is_waiting_task=False): self.submission.judge_start_time = int(time.time() * 1000) - try: - judge_server = self.choose_judge_server() - # 如果没有合适的判题服务器,就放入等待队列中等待判题 - if not judge_server: - if not is_waiting_task: - JudgeWaitingQueue.objects.create(submission_id=self.submission.id, time_limit=self.time_limit, - memory_limit=self.memory_limit, test_case_id=self.test_case_id) - return + judge_server = self.choose_judge_server() + # 如果没有合适的判题服务器,就放入等待队列中等待判题 + if not judge_server: + if not is_waiting_task: + JudgeWaitingQueue.objects.create(submission_id=self.submission.id, time_limit=self.time_limit, + memory_limit=self.memory_limit, test_case_id=self.test_case_id) + return + + judge_server.use_judge_instance() + + try: s = TimeoutServerProxy("http://" + judge_server.ip + ":" + str(judge_server.port), timeout=20) data = s.run(judge_server.token, self.submission.id, self.submission.language, self.submission.code, self.time_limit, self.memory_limit, self.test_case_id) - judge_server.release_judge_instance() # 编译错误 if data["code"] == 1: self.submission.result = result["compile_error"] @@ -67,6 +68,8 @@ class JudgeDispatcher(object): self.submission.result = result["system_error"] self.submission.info = str(e) finally: + judge_server.release_judge_instance() + self.submission.judge_end_time = int(time.time() * 1000) self.submission.save()