moreover's picture
first commit
acd4009
raw
history blame
3.11 kB
import logging
import os
import sys
import time
import traceback
from pathlib import Path
from config import load_config, load_limits_by_lang
from exec_outcome import ExecOutcome
from flask import Flask, request
from flask_cors import CORS
from job import JobData
sys.path.extend([str(Path(__file__).parent)])
from execution_engine import ExecutionEngine
app = Flask(__name__)
CORS(app)
config_path = Path("config.yaml")
cfg = load_config(config_path)
limits_by_lang_path = Path("limits_by_lang.yaml")
limits_by_lang = load_limits_by_lang(limits_by_lang_path)
gunicorn_logger = logging.getLogger("gunicorn.error")
app.logger.handlers = gunicorn_logger.handlers
app.logger.setLevel(gunicorn_logger.level)
worker_cfg_db = os.environ["WORKER_CFG_DB"]
cfg_db_lines = []
run_ids = None
with open(worker_cfg_db) as db_rp:
assigned = False
for line in db_rp:
pid, idx, gid, uid = map(int, line.strip().split(","))
if not assigned and pid == -1:
pid = os.getpid()
assigned = True
cfg_db_lines.append(",".join(map(str, (pid, idx, gid, uid))))
run_ids = (gid, uid)
app.logger.info(f"Assigned {gid=}, {uid=} to {pid=}")
else:
cfg_db_lines.append(line.strip())
with open(worker_cfg_db, "w") as db_wp:
for line in cfg_db_lines:
db_wp.write(line + "\n")
execution_engine = ExecutionEngine(cfg, limits_by_lang, run_ids, app.logger)
app.config["execution_engine"] = execution_engine
execution_engine.start()
@app.route("/api/execute_code", methods=["POST"])
def run_job():
log, ret, st = "", None, time.perf_counter_ns()
try:
job = JobData.json_parser(request.json)
log = f"api/execute_code: lang={job.language}"
result = execution_engine.check_output_match(job)
ret = {"data": [r.json() for r in result]}
exec_outcomes = [
r.exec_outcome
for r in result
if not (r.exec_outcome is None or r.exec_outcome is ExecOutcome.PASSED)
] + [ExecOutcome.PASSED]
peak_mem = max([int(r.peak_memory_consumed.split()[0]) for r in result if r.peak_memory_consumed] + [-1])
peak_time = max([r.time_consumed for r in result if r.time_consumed] + [-1])
log = f"{log} time: {(time.perf_counter_ns()-st)/(1000_000_000)}s, |uts|={len(job.unittests)}, exec_outcome={exec_outcomes[0].value}, peak_mem={peak_mem}kB, peak_time={peak_time}s"
except Exception as e:
ret = {"error": str(e) + f"\n{traceback.print_exc()}"}, 400
log = f"{log} time: {(time.perf_counter_ns()-st)/(1000_000_000)}s, {ret}"
app.logger.info(log)
return ret
@app.route("/api/all_runtimes", methods=["GET"])
def all_runtimes():
log, st = "", time.perf_counter_ns()
runtimes = []
for runtime in execution_engine.supported_languages.values():
runtimes.append(runtime.get_info())
ret = runtimes, 200
log = f"api/all_runtimes: {log} time: {(time.perf_counter_ns()-st)/(1000_000_000)}s"
app.logger.info(log)
return ret
if __name__ == "__main__":
app.run(host="0.0.0.0")