Skip to content

Commit

Permalink
Refactor judger code
Browse files Browse the repository at this point in the history
  • Loading branch information
slhmy committed Mar 23, 2024
1 parent 0fe9d32 commit dbd5de9
Show file tree
Hide file tree
Showing 27 changed files with 349 additions and 789 deletions.
3 changes: 1 addition & 2 deletions data/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
rclone-minio.conf
rclone-problem-package/
problem-package/
4 changes: 2 additions & 2 deletions data/rclone-minio.conf.example → data/default-rclone.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
type = s3
provider = Minio
env_auth = false
access_key_id = YOUR_ACCESS_KEY
secret_access_key = YOUR_SECRET_KEY
access_key_id = minio-root-user
secret_access_key = minio-root-password
endpoint = http://127.0.0.1:9000
location_constraint =
acl = private
File renamed without changes.
10 changes: 1 addition & 9 deletions judger/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,4 @@ chrono = { version = "0.4", features = ["serde"] }
anyhow = "1"
thiserror = "1"

uuid = { version = "1.4", features = ["serde", "v4"] }

[[bin]]
name ="judger-cli"
path ="src/cli/main.rs"

[[bin]]
name ="judger-server"
path ="src/server/main.rs"
uuid = { version = "1.4", features = ["serde", "v4"] }
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ impl HttpClient {
let client = reqwest::Client::new();
Self { client, base_url }
}
pub fn _get(&self, path: String) -> reqwest::RequestBuilder {
self.client.get(format!("{}{}", self.base_url, path))
}

pub fn post(&self, path: String) -> reqwest::RequestBuilder {
self.client.post(format!("{}{}", self.base_url, path))
}
Expand Down
3 changes: 3 additions & 0 deletions judger/src/agent/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod http;
pub mod rclone;
pub mod platform;
99 changes: 99 additions & 0 deletions judger/src/agent/platform/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
use super::http::HttpClient;
use judge_core::{compiler::Language, judge::result::JudgeResultInfo};

pub struct PlatformClient {
client: HttpClient,
}

impl PlatformClient {
pub fn new(base_url: String) -> Self {
Self {
client: HttpClient::new(base_url),
}
}

pub async fn pick_task(&self) -> Result<JudgeTask, anyhow::Error> {
pick_task(&self.client).await
}

pub async fn report_task(
&self,
stream_id: &str,
results: Vec<JudgeResultInfo>,
) -> Result<(), anyhow::Error> {
report_task(&self.client, stream_id, results).await
}
}

#[derive(Deserialize, Debug)]
pub struct JudgeTask {
#[serde(rename = "submissionUID")]
pub submission_uid: String,
#[serde(rename = "problemSlug")]
pub problem_slug: String,
pub code: String,
pub language: Language,
#[serde(rename = "redisStreamID")]
pub redis_stream_id: String,
}
#[derive(Serialize)]
struct PickTaskBody {
consumer: String,
}
#[derive(Deserialize, Debug)]
struct PickTaskResponse {
task: JudgeTask,
}

async fn pick_task(client: &HttpClient) -> Result<JudgeTask, anyhow::Error> {
let pick_url = "/api/v1/judge/task/pick";
let body = PickTaskBody {
consumer: "".to_string(),
};
let response = client.post(pick_url.to_string()).json(&body).send().await?;

match response.status() {
reqwest::StatusCode::OK => Ok(response.json::<PickTaskResponse>().await?.task),
_ => Err(anyhow::anyhow!("Queue is empty")),
}
}

#[derive(Serialize)]
struct ReportTaskBody {
consumer: String,
stream_id: String,
verdict_json: String,
}
#[derive(Deserialize, Debug)]
struct ReportTaskResponse {
message: String,
}

async fn report_task(
client: &HttpClient,
stream_id: &str,
results: Vec<JudgeResultInfo>,
) -> Result<(), anyhow::Error> {
let report_url = "/api/v1/judge/task/report";
let body = ReportTaskBody {
consumer: "".to_string(),
stream_id: stream_id.to_owned(),
verdict_json: serde_json::to_string(&results).unwrap(),
};
let response = client
.post(report_url.to_string())
.json(&body)
.send()
.await?;

match response.status() {
reqwest::StatusCode::OK => {
log::debug!(
"Report message: {:?}",
response.json::<ReportTaskResponse>().await?.message
);
Ok(())
}
_ => Err(anyhow::anyhow!("Report Failed")),
}
}
41 changes: 41 additions & 0 deletions judger/src/agent/rclone.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use anyhow::{self, Error};
use std::path::PathBuf;
use std::process::Command;

pub struct RcloneClient {
config_path: PathBuf,
}

impl RcloneClient {
pub fn new(config_path: PathBuf) -> Self {
Self { config_path }
}

pub fn is_avaliable(&self) -> bool {
let status = Command::new("rclone")
.arg("--config")
.arg(format!("{}", self.config_path.to_string_lossy()))
.arg("ls")
.arg("minio:")
.status()
.expect("Failed to rclone");

status.success()
}

pub fn sync_bucket(&self, bucket_name: &str, target_dir: &PathBuf) -> Result<(), Error> {
let status = Command::new("rclone")
.arg("--config")
.arg(format!("{}", self.config_path.to_string_lossy()))
.arg("sync")
.arg(format!("minio:{}", bucket_name))
.arg(format!("{}", target_dir.to_string_lossy()))
.status()
.expect("Failed to rclone");
if status.success() {
Ok(())
} else {
Err(anyhow::anyhow!("rclone sync failed, please check config."))
}
}
}
108 changes: 0 additions & 108 deletions judger/src/cli/main.rs

This file was deleted.

21 changes: 14 additions & 7 deletions judger/src/server/environment/mod.rs → judger/src/env/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,30 @@ use std::path::PathBuf;
use structopt::StructOpt;

#[derive(StructOpt, Debug, Clone)]
#[structopt(name = "judge-server")]
#[structopt(name = "judger")]
pub struct JudgeServerOpt {
/// For loading Opt from .env file
#[structopt(long)]
pub env_path: Option<String>,

/// Port to listen to
#[structopt(env = "PORT", default_value = "8080")]
pub port: u16,

#[structopt(long, default_value = "data/dev-problem-package")]
// TODO: make rclone optional
#[structopt(long, default_value = "data/default-rclone.conf")]
pub rclone_config: PathBuf,
#[structopt(long, default_value = "oj-lab-problem-package")]
pub problem_package_bucket: String,
/// Where to store problem package
#[structopt(long, default_value = "data/problem-package")]
pub problem_package_dir: PathBuf,

#[structopt(env = "BASE_URL", default_value = "http://localhost:8080/api/v1/judge")]
pub base_url: String,

#[structopt(env = "INTERVAL", default_value = "10")]
pub interval: i32,
#[structopt(env = "PLATFORM_URI", default_value = "http://localhost:8080/")]
pub platform_uri: String,
/// Interval to fetch task in seconds
#[structopt(env = "FETCH_TASK_INTERVAL", default_value = "10")]
pub fetch_task_interval: u64,
}

pub fn load_option() -> JudgeServerOpt {
Expand Down
2 changes: 0 additions & 2 deletions judger/src/server/error.rs → judger/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

use actix_web::{HttpResponse, ResponseError};
use judge_core::error::JudgeCoreError;
use judger::service::error::JudgeServiceError;

#[derive(Debug, thiserror::Error)]
pub enum ServiceError {
Expand All @@ -23,7 +22,6 @@ pub enum ServiceError {
#[derive(Debug)]
pub enum ClientError {
InternalError(anyhow::Error),
PackageError(JudgeServiceError),
}

#[derive(Serialize)]
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
mod greet;
mod judge;
pub mod state;

use actix_web::web;
Expand All @@ -15,7 +14,6 @@ pub struct ApiDoc;
pub fn route(cfg: &mut web::ServiceConfig) {
cfg.service(
web::scope("/api/v1")
.configure(judge::route)
.service(greet::greet)
.configure(state::route),
)
Expand All @@ -25,10 +23,6 @@ pub fn route(cfg: &mut web::ServiceConfig) {
utoipa_swagger_ui::Url::new("root", "/api-docs/openapi.json"),
ApiDoc::openapi(),
),
(
utoipa_swagger_ui::Url::new("judge", "/api-docs/judge.json"),
judge::JudgeApiDoc::openapi(),
),
(
utoipa_swagger_ui::Url::new("state", "/api-docs/state.json"),
state::StateApiDoc::openapi(),
Expand Down
File renamed without changes.
1 change: 0 additions & 1 deletion judger/src/lib.rs

This file was deleted.

Loading

0 comments on commit dbd5de9

Please sign in to comment.