def get_context_data(self, **kwargs): # pylint: disable=arguments-differ data = super(ServerList, self).get_context_data(**kwargs) redis_server = get_redis_connection("judge") sem = Semaphore(redis_server) sem.exists_or_init() try: data['semaphore_available_count'] = sem.available_count data['semaphore_available_keys'] = redis_server.lrange( sem.available_key, 0, sem.available_count) # 1 more actually data['semaphore_available_keys'] = list( map(lambda s: s.decode(), data['semaphore_available_keys'])) data['semaphore_grabbed_keys'] = {} for key, tt in redis_server.hgetall(sem.grabbed_key).items(): data['semaphore_grabbed_keys'][ key.decode()] = sem.current_time - float(tt.decode()) data['server_synchronize_status_detail'] = cache.get( 'server_synchronize_status_detail', '') data['server_synchronize_status'] = cache.get( 'server_synchronize_status', 0) data['semaphore_ok'] = True except: pass data['crashed_submission_count'] = Submission.objects.filter( status=SubmissionStatus.SYSTEM_ERROR).count() return data
def post(self, request, pk): server = Server.objects.get(pk=pk) server.enabled = not server.enabled server.save(update_fields=['enabled']) try: Semaphore(get_redis_connection("judge")).reset() except: pass return HttpResponseRedirect(reverse('backstage:server'))
def send_judge_through_watch(code, lang, max_time, max_memory, run_until_complete, cases, checker, interactor, group_config, callback, timeout=900, report_instance=None): """ :param interactor: None or '' if there is no interactor :param callback: function, to call when something is returned (possibly preliminary results) callback should return True when it thinks the result is final result, return False otherwise callback will receive exactly one param, which is the data returned by judge server as a dict :param timeout: will fail if it has not heard from judge server for `timeout` seconds """ redis_server = get_redis_connection("judge") with Semaphore(redis_server, stale_client_timeout=60) as (sem, token): try: server = Server.objects.get(pk=int(token.decode().split(":")[0])) data = _prepare_judge_json_data(server, code, lang, max_time, max_memory, run_until_complete, cases, checker, interactor, group_config) data.update(hold=False) judge_url = server.http_address + '/judge' watch_url = server.http_address + '/query' watch_report = server.http_address + '/query/report' timeout_count = 0 response = add_timestamp_to_reply(requests.post(judge_url, json=data, auth=(DEFAULT_USERNAME, server.token), timeout=timeout).json()) process_runtime(server, response) if response.get('status') != 'received': callback(response) while timeout_count < timeout: interval = 0.5 time.sleep(interval) response = add_timestamp_to_reply(requests.get(watch_url, json={'fingerprint': data['fingerprint']}, auth=(DEFAULT_USERNAME, server.token), timeout=timeout).json()) process_runtime(server, response) if callback(response): report_instance.content = requests.get(watch_report, json={'fingerprint': data['fingerprint']}, auth=(DEFAULT_USERNAME, server.token), timeout=timeout).text report_instance.save() break timeout_count += interval interval += 0.1 if timeout_count >= timeout: raise RuntimeError("Send judge through socketio timed out.") except: msg = "Time: %s\n%s" % (datetime.now(), traceback.format_exc()) logger.error(msg) send_mail(subject="Submit fail notice", message=msg, from_email=None, recipient_list=settings.ADMIN_EMAIL_LIST, fail_silently=True) callback({"status": "reject", "message": msg})
def post(self, request, *args, **kwargs): try: Semaphore(get_redis_connection("judge")).reset() except: pass return HttpResponseRedirect(reverse('backstage:server'))