From c0e2c9ccb0cc6e06eec1df35038226e9da3fb7c4 Mon Sep 17 00:00:00 2001 From: MeiK Date: Thu, 22 Oct 2020 19:28:34 +0800 Subject: [PATCH] Update --- src/judger.rs | 35 ++++++++++++++++++++++++++--------- src/main.rs | 22 +++++++++++++++++++--- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/judger.rs b/src/judger.rs index 41c2a8b..2979680 100644 --- a/src/judger.rs +++ b/src/judger.rs @@ -55,11 +55,30 @@ pub async fn judger( let runner = process.runner.clone(); let status = runner.await?; - // TODO: 根据返回值等判断 tle、mle、re 等状态 - // TODO: 对比答案,检查结果 - if status.exit_code != 0 { - resp.set_process_status(&status); - resp.state = Some(State::Result(JudgeResult::WrongAnswer as i32)); + resp.set_process_status(&status); + // 先判断 tle 和 mle,一是因为 tle 和 mle 也会导致信号中断,二是优先程序复杂度判断 + if status.time_used > data.time_limit.into() { + // TLE + resp.state = Some(State::Result(JudgeResult::TimeLimitExceeded as i32)); + } else if status.memory_used > data.memory_limit.into() { + // MLE + resp.state = Some(State::Result(JudgeResult::MemoryLimitExceeded as i32)); + } else if status.signal != 0 { + // 被信号中断的程序,RE + resp.stderr = match fs::read_to_string(path.join(STDERR_FILENAME)).await { + Ok(val) => val, + Err(e) => return Err(Error::FileReadError(e)), + }; + resp.errmsg = format!("Program was interrupted by signal: {}", status.signal); + resp.state = Some(State::Result(JudgeResult::RuntimeError as i32)); + } else if status.exit_code != 0 { + // 返回值不为 0 的程序,RE(虽然有可能是用户自己返回的) + resp.errmsg = format!("Exceptional program return code: {}", status.exit_code); + resp.state = Some(State::Result(JudgeResult::RuntimeError as i32)); + } else { + // TODO: AC\WA\PE + // 没有 ole 这种操作,之前 ole 就是错的 + resp.state = Some(State::Result(JudgeResult::Accepted as i32)); } Ok(resp) } @@ -114,16 +133,14 @@ pub async fn compile( if status.exit_code != 0 { debug!("compile exit code: {}", status.exit_code); // 从 stdout 和 stderr 中获取错误信息 - let stdout = match fs::read_to_string(path.join(STDOUT_FILENAME)).await { + resp.stdout = match fs::read_to_string(path.join(STDOUT_FILENAME)).await { Ok(val) => val, Err(e) => return Err(Error::FileReadError(e)), }; - let stderr = match fs::read_to_string(path.join(STDERR_FILENAME)).await { + resp.stderr = match fs::read_to_string(path.join(STDERR_FILENAME)).await { Ok(val) => val, Err(e) => return Err(Error::FileReadError(e)), }; - resp.stdout = stdout; - resp.stderr = stderr; resp.state = Some(State::Result(JudgeResult::CompileError as i32)); } else { resp.state = Some(State::Result(JudgeResult::Accepted as i32)); diff --git a/src/main.rs b/src/main.rs index 68b3135..13be79b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -#![recursion_limit = "256"] +#![recursion_limit = "512"] #[macro_use] extern crate log; @@ -6,8 +6,9 @@ use env_logger::Env; use futures::StreamExt; use futures_core::Stream; use river::judge_request::Data; +use river::judge_response::State; use river::river_server::{River, RiverServer}; -use river::{JudgeRequest, JudgeResponse}; +use river::{JudgeRequest, JudgeResponse, JudgeResult}; use std::pin::Pin; use tempfile::tempdir_in; use tonic::transport::Server; @@ -48,6 +49,8 @@ impl River for RiverService { return }, }; + // 是否通过编译 + let mut compile_success = false; debug!("create tempdir: {:?}", pwd); while let Some(req) = stream.next().await { @@ -64,7 +67,12 @@ impl River for RiverService { }, Some(Data::JudgeData(data)) => { debug!("judge request"); - judger::judger(&req, &data, &pwd.path()).await + // 必须通过编译才能运行 + if !compile_success { + Ok(error::system_error(error::Error::CustomError("Please compile first".to_string()))) + } else { + judger::judger(&req, &data, &pwd.path()).await + } }, None => Err(error::Error::RequestDataNotFound), _ => Err(error::Error::UnknownRequestData), @@ -73,6 +81,14 @@ impl River for RiverService { Ok(res) => res, Err(e) => error::system_error(e) }; + // 如果通过了编译,则标记为成功 + if let Some(Data::CompileData(_)) = &req.data { + if let Some(State::Result(rst)) = result.state { + if rst == JudgeResult::Accepted as i32 { + compile_success = true; + } + } + } yield result; } while let Some(_) = stream.next().await {}