From 8bb2a66f7b6da77f911c29c31c0dfc32abd9c29d Mon Sep 17 00:00:00 2001 From: virusdefender Date: Mon, 3 Oct 2016 16:13:46 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=81=A5=E5=BA=B7=E6=A3=80?= =?UTF-8?q?=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 3 +- exception.py | 6 ++- server.py | 24 +++++------- service.py | 73 +++++++++++++++++++++++++++++++++++++ tests/test_case/spj/spj-1.c | 6 --- utils.py | 19 ++++++++++ 6 files changed, 108 insertions(+), 23 deletions(-) create mode 100644 service.py delete mode 100644 tests/test_case/spj/spj-1.c create mode 100644 utils.py diff --git a/Dockerfile b/Dockerfile index 9d5b37c..652033e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,11 +11,12 @@ RUN apt-get update RUN apt-get install -y oracle-java7-installer RUN cd /tmp && git clone https://github.com/QingdaoU/Judger && cd Judger && git checkout newnew && mkdir build && cd build && cmake .. && make && make install && cd ../bindings/Python && python setup.py install RUN mkdir /var/wp -RUN pip install psutil gunicorn web.py +RUN pip install psutil gunicorn web.py requests RUN mkdir -p /judger_run /test_case /log /code COPY deploy/java_policy /etc COPY deploy/supervisord.conf /etc RUN chmod -R 777 /judger_run RUN pip install supervisor psutil gunicorn web.py EXPOSE 8080 +HEALTHCHECK --interval=5s --retries=3 CMD python /code/service.py CMD exec supervisord diff --git a/exception.py b/exception.py index add8e95..854f912 100644 --- a/exception.py +++ b/exception.py @@ -14,4 +14,8 @@ class TokenVerificationFailed(Exception): class JudgeClientError(Exception): - pass \ No newline at end of file + pass + + +class JudgeServiceError(Exception): + pass diff --git a/server.py b/server.py index b38dce3..f2a30ef 100644 --- a/server.py +++ b/server.py @@ -5,17 +5,16 @@ import hashlib import json import os import shutil -import socket import logging -import _judger -import psutil import web from compiler import Compiler from config import JUDGER_WORKSPACE_BASE, TEST_CASE_DIR from exception import TokenVerificationFailed, CompileError, SPJCompileError,JudgeClientError from judge_client import JudgeClient +from utils import server_info, get_token + DEBUG = os.environ.get("judger_debug") == "1" @@ -43,20 +42,14 @@ class InitSubmissionEnv(object): class JudgeServer(object): - def _health_check(self): - ver = _judger.VERSION - return {"hostname": socket.gethostname(), - "cpu": psutil.cpu_percent(), - "cpu_core": psutil.cpu_count(), - "memory": psutil.virtual_memory().percent, - "judger_version": ((ver >> 16) & 0xff, (ver >> 8) & 0xff, ver & 0xff)} - def pong(self): - return self._health_check() + data = server_info() + data["action"] = "pong" + return data @property def _token(self): - t = os.getenv("judger_token") + t = get_token() if not t: raise TokenVerificationFailed("token not set") return hashlib.sha256(t).hexdigest() @@ -145,12 +138,13 @@ urls = ( "/compile_spj", "JudgeServer" ) -if not os.environ.get("judger_token"): - raise TokenVerificationFailed("token not set") if DEBUG: logging.info("DEBUG=ON") +# check token +JudgeServer()._token + app = web.application(urls, globals()) wsgiapp = app.wsgifunc() diff --git a/service.py b/service.py new file mode 100644 index 0000000..4b1f5b6 --- /dev/null +++ b/service.py @@ -0,0 +1,73 @@ +# coding=utf-8 +from __future__ import unicode_literals +import os +import json +import logging +import requests + +from exception import JudgeServiceError +from utils import server_info, get_token + + +logger = logging.getLogger(__name__) +handler = logging.FileHandler("/log/service_log.log") +formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') +handler.setFormatter(formatter) +logger.addHandler(handler) +logger.setLevel(logging.WARNING) + + +class JudgeService(object): + def __init__(self): + # exists if docker link oj_web_server:oj_web_server + self.service_discovery_host = os.environ.get("OJ_WEB_SERVER_PORT_8080_TCP_ADDR") + self.service_discovery_port = os.environ.get("OJ_WEB_SERVER_PORT_8080_TCP_PORT") + self.service_discovery_url = os.environ.get("service_discovery_url", "") + + # this container's ip and port, if these are not set, web server will think it's a linked container + self.service_host = os.environ.get("service_host") + self.service_port = os.environ.get("service_port") + + if not self.service_discovery_url: + if not (self.service_discovery_host and self.service_discovery_port): + raise JudgeServiceError("service discovery host or port not found") + else: + self.service_discovery_url = "http://" + self.service_discovery_host + ":" + \ + str(self.service_discovery_port) + "/api/judge_service/" + + def _request(self, data): + try: + r = requests.post(self.service_discovery_url, data=json.dumps(data), + headers={"X-JUDGE-SERVER-TOKEN": get_token()}, timeout=5).json() + except Exception as e: + logger.exception(e) + raise JudgeServiceError(e.message) + if r["err"]: + raise JudgeServiceError(r["data"]) + + def register(self): + data = server_info() + data["action"] = "register" + data["service_host"] = self.service_host + data["service_port"] = self.service_port + self._request(data) + + def unregister(self): + data = server_info() + data["action"] = "unregister" + self._request(data) + + def heartbeat(self): + data = server_info() + data["action"] = "heartbeat" + self._request(data) + + +if __name__ == "__main__": + try: + service = JudgeService() + service.heartbeat() + exit(0) + except Exception as e: + logger.exception(e) + exit(1) \ No newline at end of file diff --git a/tests/test_case/spj/spj-1.c b/tests/test_case/spj/spj-1.c deleted file mode 100644 index 1984ee3..0000000 --- a/tests/test_case/spj/spj-1.c +++ /dev/null @@ -1,6 +0,0 @@ - - #include - int main(){ - return 1; - } - \ No newline at end of file diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..ac8a365 --- /dev/null +++ b/utils.py @@ -0,0 +1,19 @@ +# coding=utf-8 +from __future__ import unicode_literals +import _judger +import psutil +import socket +import os + + +def server_info(): + ver = _judger.VERSION + return {"hostname": socket.gethostname(), + "cpu": psutil.cpu_percent(), + "cpu_core": psutil.cpu_count(), + "memory": psutil.virtual_memory().percent, + "judger_version": ((ver >> 16) & 0xff, (ver >> 8) & 0xff, ver & 0xff)} + + +def get_token(): + return os.environ.get("OJ_WEB_SERVER_ENV_judger_token") or os.environ.get("judger_token") \ No newline at end of file