mirror of
https://github.com/MeiK2333/river.git
synced 2025-11-04 14:49:40 +08:00
Update
This commit is contained in:
parent
fdaeb0c7e0
commit
7931f6b2bc
@ -7,15 +7,12 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
tonic = "0.3"
|
tonic = "0.3"
|
||||||
prost = "0.6"
|
prost = "0.6"
|
||||||
tokio = { version = "0.2", features = ["macros", "sync", "stream", "time"] }
|
tokio = { version = "0.2", features = ["macros", "sync", "stream", "time", "fs"] }
|
||||||
futures = { version = "0.3" }
|
futures = { version = "0.3" }
|
||||||
futures-core = "0.3"
|
futures-core = "0.3"
|
||||||
futures-util = { version = "0.3", default-features = false }
|
futures-util = { version = "0.3", default-features = false }
|
||||||
async-stream = "0.2"
|
async-stream = "0.2"
|
||||||
tower = "0.3"
|
tower = "0.3"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
|
||||||
serde_json = "1.0"
|
|
||||||
rand = "0.7"
|
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
|
|
||||||
|
|||||||
4
runner/.gitignore
vendored
Normal file
4
runner/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
||||||
@ -1,10 +1,15 @@
|
|||||||
use crate::river::judge_response::{JudgeResult, JudgeStatus};
|
use crate::river::judge_response::{JudgeResult, JudgeStatus};
|
||||||
use crate::river::JudgeResponse;
|
use crate::river::JudgeResponse;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use std::io;
|
||||||
use std::result;
|
use std::result;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {}
|
pub enum Error {
|
||||||
|
CreateTempDirError(io::Error),
|
||||||
|
LanguageNotFound(i32),
|
||||||
|
FileWriteError(io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
use super::error::Result;
|
use super::error::{Error, Result};
|
||||||
|
use crate::river::judge_request::Language;
|
||||||
use crate::river::judge_response::{JudgeResult, JudgeStatus};
|
use crate::river::judge_response::{JudgeResult, JudgeStatus};
|
||||||
use crate::river::{JudgeRequest, JudgeResponse};
|
use crate::river::{JudgeRequest, JudgeResponse};
|
||||||
|
use std::path::Path;
|
||||||
|
use tokio::fs;
|
||||||
|
|
||||||
pub async fn judger(request: &JudgeRequest) -> Result<JudgeResponse> {
|
pub async fn judger(request: &JudgeRequest) -> Result<JudgeResponse> {
|
||||||
return Ok(JudgeResponse {
|
return Ok(JudgeResponse {
|
||||||
@ -16,7 +19,23 @@ pub async fn judger(request: &JudgeRequest) -> Result<JudgeResponse> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn compile(request: &JudgeRequest) -> Result<JudgeResponse> {
|
pub async fn compile(request: &JudgeRequest, path: &Path) -> Result<JudgeResponse> {
|
||||||
|
// 写入代码
|
||||||
|
let filename = match Language::from_i32(request.language) {
|
||||||
|
Some(Language::C) => "main.c",
|
||||||
|
Some(Language::Cpp) => "main.cpp",
|
||||||
|
Some(Language::Python) => "main.py",
|
||||||
|
Some(Language::Rust) => "main.rs",
|
||||||
|
Some(Language::Node) => "main.js",
|
||||||
|
Some(Language::TypeScript) => "main.ts",
|
||||||
|
Some(Language::Go) => "main.go",
|
||||||
|
None => return Err(Error::LanguageNotFound(request.language)),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(e) = fs::write(path.join(filename), request.code.clone()).await {
|
||||||
|
return Err(Error::FileWriteError(e));
|
||||||
|
};
|
||||||
|
|
||||||
return Ok(JudgeResponse {
|
return Ok(JudgeResponse {
|
||||||
time_used: request.time_limit,
|
time_used: request.time_limit,
|
||||||
memory_used: 2,
|
memory_used: 2,
|
||||||
|
|||||||
19
src/main.rs
19
src/main.rs
@ -6,6 +6,7 @@ use futures_core::Stream;
|
|||||||
use river::river_server::{River, RiverServer};
|
use river::river_server::{River, RiverServer};
|
||||||
use river::{JudgeRequest, JudgeResponse};
|
use river::{JudgeRequest, JudgeResponse};
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
use tempfile::tempdir_in;
|
||||||
use tonic::transport::Server;
|
use tonic::transport::Server;
|
||||||
use tonic::{Request, Response, Status};
|
use tonic::{Request, Response, Status};
|
||||||
|
|
||||||
@ -33,15 +34,27 @@ impl River for RiverService {
|
|||||||
|
|
||||||
let output = async_stream::try_stream! {
|
let output = async_stream::try_stream! {
|
||||||
let mut need_compile = true;
|
let mut need_compile = true;
|
||||||
|
// TODO: 使用锁或者资源量等机制限制并发
|
||||||
|
yield judger::pending();
|
||||||
|
|
||||||
|
// 创建评测使用的临时目录
|
||||||
|
// 无需主动删除,变量在 drop 之后会自动删除临时文件夹
|
||||||
|
let pwd = match tempdir_in("./runner") {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(err) => {
|
||||||
|
yield error::system_error(error::Error::CreateTempDirError(err));
|
||||||
|
return
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("{:?}", pwd);
|
||||||
while let Some(req) = stream.next().await {
|
while let Some(req) = stream.next().await {
|
||||||
// TODO: 使用锁或者资源量等机制限制并发
|
|
||||||
yield judger::pending();
|
|
||||||
let req = req?;
|
let req = req?;
|
||||||
|
|
||||||
// 首次获取流进行编译
|
// 首次获取流进行编译
|
||||||
if need_compile {
|
if need_compile {
|
||||||
yield judger::compiling();
|
yield judger::compiling();
|
||||||
let result = match judger::compile(&req).await {
|
let result = match judger::compile(&req, &pwd.path()).await {
|
||||||
Ok(res) => res,
|
Ok(res) => res,
|
||||||
Err(e) => error::system_error(e)
|
Err(e) => error::system_error(e)
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user