From 2fe45f3bfdf5ae18c4e0f37d6d0ba6bdb655cac0 Mon Sep 17 00:00:00 2001 From: MeiK2333 Date: Tue, 12 Jan 2021 16:43:49 +0800 Subject: [PATCH] Update --- src/config.rs | 27 ++++++++++++++++++++ src/error.rs | 1 + src/judger.rs | 27 ++++++++++++++++++++ src/main.rs | 70 +++++++++++++++++++++++++++++++-------------------- src/result.rs | 15 +++++++++++ 5 files changed, 113 insertions(+), 27 deletions(-) create mode 100644 src/result.rs diff --git a/src/config.rs b/src/config.rs index 2e96fff..bb9331d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,3 +1,30 @@ +use lazy_static::lazy_static; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::fs; + pub static STDIN_FILENAME: &str = "stdin.txt"; pub static STDOUT_FILENAME: &str = "stdout.txt"; pub static STDERR_FILENAME: &str = "stderr.txt"; + +lazy_static! { + pub static ref CONFIG: Config = { + let config = fs::read_to_string("config.yaml").unwrap(); + let cg: Config = serde_yaml::from_str(&config).unwrap(); + debug!("{:?}", cg); + cg + }; +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub struct LanguageConf { + pub compile_cmd: String, + pub code_file: String, + pub run_cmd: String, +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub struct Config { + pub data_dir: String, + pub languages: HashMap, +} diff --git a/src/error.rs b/src/error.rs index b7dfdc2..672cf6c 100644 --- a/src/error.rs +++ b/src/error.rs @@ -14,6 +14,7 @@ pub enum Error { StringToCStringError(NulError), ParseIntError(std::num::ParseIntError), CreateTempDirError(io::Error), + CustomError(String), } pub type Result = result::Result; diff --git a/src/judger.rs b/src/judger.rs index 8b13789..c64cbfe 100644 --- a/src/judger.rs +++ b/src/judger.rs @@ -1 +1,28 @@ +use std::path::Path; +#[cfg(test)] +use std::println as debug; + +pub async fn compile(language: &str, code: &str, path: &Path) { + debug!("language: {}", language); + debug!("code: {}", code); + debug!("path: {:?}", path); +} + +pub async fn judge( + language: &str, + in_file: &str, + out_file: &str, + time_limit: i32, + memory_limit: i32, + judge_type: i32, + path: &Path, +) { + debug!("language: {}", language); + debug!("in_file: {}", in_file); + debug!("out_file: {}", out_file); + debug!("time_limit: {}", time_limit); + debug!("memory_limit: {}", memory_limit); + debug!("judge_type: {}", judge_type); + debug!("path: {:?}", path); +} diff --git a/src/main.rs b/src/main.rs index 644cc21..592a934 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -#![recursion_limit = "256"] +#![recursion_limit = "512"] #[macro_use] extern crate log; @@ -20,6 +20,7 @@ mod cgroup; mod exec_args; mod judger; mod process; +mod result; mod seccomp; pub mod river { @@ -40,44 +41,59 @@ impl River for RiverService { ) -> Result, Status> { let mut stream = request.into_inner(); - // 此处编译很慢 - // 为啥,是 try_stream! 这个宏导致的吗? - // 同时内部代码无法被 cargo fmt 格式化 - // why? let output = async_stream::try_stream! { + let pwd = match tempdir_in("/tmp") { + Ok(val) => val, + Err(e) => { + yield result::system_error(error::Error::IOError(e)); + return; + } + }; while let Some(req) = stream.next().await { - let req = req?; - // TODO - let pwd = tempdir_in("/tmp").unwrap(); - match &req.data { + let req = req?; + let mut language = String::from(""); + let result = match &req.data { Some(Data::CompileData(data)) => { debug!("compile request"); - let language = &data.language; + language = String::from(&data.language); + let cfg = config::CONFIG.languages.get(&language); + debug!("{:?}", cfg); let code = &data.code; - debug!("language: {}", language); - debug!("code: {}", code); - break; + judger::compile(&language, &code, &pwd.path()).await; + JudgeResponse { + state: Some(river::judge_response::State::Status(river::JudgeStatus::Pending as i32)) + } }, Some(Data::JudgeData(data)) => { debug!("judge request"); let in_file = &data.in_file; let out_file = &data.out_file; - let time_limit = &data.time_limit; - let memory_limit = &data.memory_limit; - let judge_type = &data.judge_type; - debug!("in_file: {}", in_file); - debug!("out_file: {}", out_file); - debug!("time_limit: {}", time_limit); - debug!("memory_limit: {}", memory_limit); - debug!("judge_type: {}", judge_type); - break; + let time_limit = data.time_limit; + let memory_limit = data.memory_limit; + let judge_type = data.judge_type; + if language == "" { + // error::Error::CustomError(String::from("not compiled")); + JudgeResponse { + state: Some(river::judge_response::State::Status(river::JudgeStatus::Pending as i32)) + } + } else { + judger::judge(&language, &in_file, &out_file, time_limit, memory_limit, judge_type, &pwd.path()).await; + JudgeResponse { + state: Some(river::judge_response::State::Status(river::JudgeStatus::Pending as i32)) + } + } + }, + None => JudgeResponse { + state: Some(river::judge_response::State::Status(river::JudgeStatus::Pending as i32)) + }, + _ => JudgeResponse { + state: Some(river::judge_response::State::Status(river::JudgeStatus::Pending as i32)) }, - None => break, - _ => break, }; - } - yield JudgeResponse { - state: Some(river::judge_response::State::Status(river::JudgeStatus::Pending as i32)) + // TODO + yield JudgeResponse { + state: Some(river::judge_response::State::Status(river::JudgeStatus::Pending as i32)) + }; }; }; diff --git a/src/result.rs b/src/result.rs new file mode 100644 index 0000000..de7a9c5 --- /dev/null +++ b/src/result.rs @@ -0,0 +1,15 @@ +use crate::error::Error; +use crate::river::judge_response::State; +use crate::river::{JudgeResponse, JudgeResult, JudgeResultEnum}; + +pub fn system_error(err: Error) -> JudgeResponse { + warn!("{:?}", err); + JudgeResponse { + state: Some(State::Result(JudgeResult { + time_used: 0, + memory_used: 0, + result: JudgeResultEnum::SystemError as i32, + errmsg: format!("{}", err).into(), + })), + } +}