mirror of
https://github.com/MeiK2333/river.git
synced 2025-11-04 14:49:40 +08:00
Update
This commit is contained in:
parent
c35eb6ae29
commit
c0e2c9ccb0
@ -55,11 +55,30 @@ pub async fn judger(
|
|||||||
let runner = process.runner.clone();
|
let runner = process.runner.clone();
|
||||||
let status = runner.await?;
|
let status = runner.await?;
|
||||||
|
|
||||||
// TODO: 根据返回值等判断 tle、mle、re 等状态
|
resp.set_process_status(&status);
|
||||||
// TODO: 对比答案,检查结果
|
// 先判断 tle 和 mle,一是因为 tle 和 mle 也会导致信号中断,二是优先程序复杂度判断
|
||||||
if status.exit_code != 0 {
|
if status.time_used > data.time_limit.into() {
|
||||||
resp.set_process_status(&status);
|
// TLE
|
||||||
resp.state = Some(State::Result(JudgeResult::WrongAnswer as i32));
|
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)
|
Ok(resp)
|
||||||
}
|
}
|
||||||
@ -114,16 +133,14 @@ pub async fn compile(
|
|||||||
if status.exit_code != 0 {
|
if status.exit_code != 0 {
|
||||||
debug!("compile exit code: {}", status.exit_code);
|
debug!("compile exit code: {}", status.exit_code);
|
||||||
// 从 stdout 和 stderr 中获取错误信息
|
// 从 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,
|
Ok(val) => val,
|
||||||
Err(e) => return Err(Error::FileReadError(e)),
|
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,
|
Ok(val) => val,
|
||||||
Err(e) => return Err(Error::FileReadError(e)),
|
Err(e) => return Err(Error::FileReadError(e)),
|
||||||
};
|
};
|
||||||
resp.stdout = stdout;
|
|
||||||
resp.stderr = stderr;
|
|
||||||
resp.state = Some(State::Result(JudgeResult::CompileError as i32));
|
resp.state = Some(State::Result(JudgeResult::CompileError as i32));
|
||||||
} else {
|
} else {
|
||||||
resp.state = Some(State::Result(JudgeResult::Accepted as i32));
|
resp.state = Some(State::Result(JudgeResult::Accepted as i32));
|
||||||
|
|||||||
22
src/main.rs
22
src/main.rs
@ -1,4 +1,4 @@
|
|||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "512"]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
|
||||||
@ -6,8 +6,9 @@ use env_logger::Env;
|
|||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use futures_core::Stream;
|
use futures_core::Stream;
|
||||||
use river::judge_request::Data;
|
use river::judge_request::Data;
|
||||||
|
use river::judge_response::State;
|
||||||
use river::river_server::{River, RiverServer};
|
use river::river_server::{River, RiverServer};
|
||||||
use river::{JudgeRequest, JudgeResponse};
|
use river::{JudgeRequest, JudgeResponse, JudgeResult};
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use tempfile::tempdir_in;
|
use tempfile::tempdir_in;
|
||||||
use tonic::transport::Server;
|
use tonic::transport::Server;
|
||||||
@ -48,6 +49,8 @@ impl River for RiverService {
|
|||||||
return
|
return
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
// 是否通过编译
|
||||||
|
let mut compile_success = false;
|
||||||
debug!("create tempdir: {:?}", pwd);
|
debug!("create tempdir: {:?}", pwd);
|
||||||
|
|
||||||
while let Some(req) = stream.next().await {
|
while let Some(req) = stream.next().await {
|
||||||
@ -64,7 +67,12 @@ impl River for RiverService {
|
|||||||
},
|
},
|
||||||
Some(Data::JudgeData(data)) => {
|
Some(Data::JudgeData(data)) => {
|
||||||
debug!("judge request");
|
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),
|
None => Err(error::Error::RequestDataNotFound),
|
||||||
_ => Err(error::Error::UnknownRequestData),
|
_ => Err(error::Error::UnknownRequestData),
|
||||||
@ -73,6 +81,14 @@ impl River for RiverService {
|
|||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(e) => error::system_error(e)
|
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;
|
yield result;
|
||||||
}
|
}
|
||||||
while let Some(_) = stream.next().await {}
|
while let Some(_) = stream.next().await {}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user