This commit is contained in:
MeiK 2020-08-22 23:22:59 +08:00
parent 525f566466
commit e8e335d284
4 changed files with 127 additions and 2 deletions

View File

@ -5,3 +5,17 @@ authors = ["MeiK <meik2333@gmail.com>"]
edition = "2018"
[dependencies]
tonic = "0.3"
prost = "0.6"
tokio = { version = "0.2", features = ["macros", "sync", "stream", "time"] }
futures = { version = "0.3" }
futures-core = "0.3"
futures-util = { version = "0.3", default-features = false }
async-stream = "0.2"
tower = "0.3"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
rand = "0.7"
[build-dependencies]
tonic-build ={ version = "0.3" }

4
build.rs Normal file
View File

@ -0,0 +1,4 @@
fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::compile_protos("proto/river.proto")?;
Ok(())
}

54
proto/river.proto Normal file
View File

@ -0,0 +1,54 @@
syntax = "proto3";
package river;
service River {
rpc Judge(stream JudgeRequest) returns (stream JudgeResponse) {}
}
message JudgeRequest {
enum Language {
C = 0;
Cpp = 1;
Python = 2;
Rust = 3;
Node = 4;
TypeScript = 5;
Go = 6;
}
Language language = 1;
string code = 2;
enum JudgeType {
Standard = 0;
// Special = 1;
}
JudgeType judge_type = 3;
string in_data = 4;
string out_data = 5;
int32 time_limit = 6;
int32 memory_limit = 7;
}
message JudgeResponse {
int32 time_used = 1;
int32 memory_used = 2;
enum JudgeResult {
Accepted = 0;
WrongAnswer = 1;
TimeLimitExceeded = 2;
MemoryLimitExceeded = 3;
RuntimeError = 4;
OutputLimitExceeded = 5;
CompileError = 6;
PresentationError = 7;
SystemError = 8;
}
JudgeResult result = 3;
int32 errno = 4;
int32 exit_code = 5;
string stdout = 6;
string stderr = 7;
}

View File

@ -1,3 +1,56 @@
fn main() {
println!("Hello World!");
use futures_core::Stream;
use river::river_server::{River, RiverServer};
use river::{JudgeRequest, JudgeResponse};
use std::pin::Pin;
use std::sync::Arc;
use tokio::sync::mpsc;
use tonic::{transport::Server, Request, Response, Status};
pub mod river {
tonic::include_proto!("river"); // The string specified here must match the proto package name
}
#[derive(Debug, Default)]
pub struct RiverService {}
#[tonic::async_trait]
impl River for RiverService {
type JudgeStream =
Pin<Box<dyn Stream<Item = Result<JudgeResponse, Status>> + Send + Sync + 'static>>;
async fn judge(
&self,
request: Request<tonic::Streaming<JudgeRequest>>,
) -> Result<Response<Self::JudgeStream>, Status> {
let mut stream = request.into_inner();
let output = async_stream::try_stream! {
// while let Some(note) = stream.next().await {
yield river::JudgeResponse {
time_used: 1,
memory_used: 2,
result: 0,
errno: 0,
exit_code: 0,
stdout: "stdout".into(),
stderr: "stderr".into(),
};
// }
};
Ok(Response::new(Box::pin(output) as Self::JudgeStream))
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let addr = "[::1]:50051".parse()?;
let greeter = RiverService::default();
Server::builder()
.add_service(RiverServer::new(greeter))
.serve(addr)
.await?;
Ok(())
}