Skip to content

Commit

Permalink
Make dev more convient
Browse files Browse the repository at this point in the history
  • Loading branch information
slhmy committed Mar 30, 2024
1 parent 952e637 commit cde4466
Show file tree
Hide file tree
Showing 19 changed files with 120 additions and 57 deletions.
9 changes: 3 additions & 6 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
.github/
.vscode/
tmp/
test-collection/
target/
rclone/
postman/
docker/
.devcontainer/
target/
2 changes: 1 addition & 1 deletion .github/workflows/docker-publish-judger.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ jobs:
id: build-and-push
uses: docker/build-push-action@v5
with:
file: docker/judger.dockerfile
file: Dockerfile
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
Expand Down
28 changes: 28 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
// This name overrides rust-analyzer's debugging settings
"name": "run judger",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/target/debug/judger",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/judger/envs/development",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"preLaunchTask": "build debug judger",
"setupCommands": [
{
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
12 changes: 2 additions & 10 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
{
"material-icon-theme.folders.associations": {
"judge-core": "core",
"judge-cli": "command",
"judge-service": "helper",
"judge-server": "server",
"postman": "api"
},
"rust-analyzer.linkedProjects": [
"./judger/Cargo.toml",
"./judger/Cargo.toml",
"./judger/Cargo.toml"
]
"judger": "app"
}
}
13 changes: 13 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build debug judger",
"type": "shell",
"command": "cargo",
"args": ["build", "--bin", "judger"]
}
]
}
12 changes: 6 additions & 6 deletions docker/judger.dockerfile → Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
FROM rust:latest as build

COPY judge-core /usr/src/judge-core
COPY judger /usr/src/judger
WORKDIR /usr/src/judger
COPY judge-core/ /usr/src/judge-core
COPY judger/ /usr/src/judger

WORKDIR /usr/src/judger
RUN apt update && apt install -y libseccomp-dev gcc
RUN cargo build --bin judger --release

Expand All @@ -16,10 +16,10 @@ COPY --from=build /usr/src/judger/target/release/judger /usr/local/bin/judger
RUN curl https://rclone.org/install.sh | bash

RUN mkdir /workspace
WORKDIR /workspace
COPY data/default-rclone.conf /workspace/data/default-rclone.conf
RUN mkdir /workspace/data/problem-package
RUN mkdir /workspace/problem-package
COPY judger/envs/docker/rclone.conf /workspace/rclone.conf

WORKDIR /workspace
ENV RUST_LOG=DEBUG
EXPOSE 8000
CMD [ "judger-server" ]
18 changes: 16 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,33 @@
# Judger

![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/OJ-lab/judger/rust-check.yml?logo=github&label=Tests)
[![Discord](https://img.shields.io/discord/916955582181822486?label=Discord&color=blue&logo=discord&logoColor=white)](https://discord.gg/vh8NCgdp8J)
![Codespace Supported](https://img.shields.io/badge/Codespace_Supported-000000?style=flat&logo=github)

Judger is supposed to be a simple **sandbox service** which works for online-judge systems.

## System

judger-rs currently use `nix` to make necessary system invoke like `fork()`.
Judger currently use `nix` to make necessary system invoke like `fork()`.
So you might need to check whether you are using the supported system from the main-page of [nix](https://github.com/nix-rust/nix).

**Briefly speaking, judger-rs is now supposing you are decided to run it on linux.**
We'll consider other platform, but in a lower priority.

## Development

Judger should works fine in VSCode with all recommended extensions installed.

### Before you start

You may need to setup your environment before you start.
There is a setup script to help you quickly get ready.

> 🥰 You won't need to run this script if you are using GitHub Codespaces.
```sh
./scripts/env_setup.bash
```

## Contribute

We have a guide in judger's [WIKI](https://github.com/OJ-lab/judger/wiki/Contribution-Guide)
Expand Down
9 changes: 0 additions & 9 deletions docker/README.md

This file was deleted.

4 changes: 0 additions & 4 deletions judger/.env.development

This file was deleted.

2 changes: 1 addition & 1 deletion judger/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ judge-core = { path = "../judge-core" }
clap = { version = "4.0", features = ["derive"] }

# Client
reqwest = { version = "0.12.1", features = ["json"] }
reqwest = { version = "0.12", features = ["json"] }

# Async runtime
tokio = { version = "1", features = ["full"] }
Expand Down
2 changes: 2 additions & 0 deletions judger/envs/development/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
RUST_LOG=DEBUG
FETCH_TASK_INTERVAL=10
1 change: 1 addition & 0 deletions judger/envs/development/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
problem-package/
File renamed without changes.
9 changes: 9 additions & 0 deletions judger/envs/docker/rclone.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[minio]
type = s3
provider = Minio
env_auth = false
access_key_id = minio-root-user
secret_access_key = minio-root-password
endpoint = http://host.docker.internal:9000
location_constraint =
acl = private
5 changes: 4 additions & 1 deletion judger/src/agent/platform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ async fn pick_task(client: &HttpClient) -> Result<JudgeTask, anyhow::Error> {

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

Expand Down
16 changes: 12 additions & 4 deletions judger/src/agent/rclone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,21 @@ impl RcloneClient {
}

pub fn is_avaliable(&self) -> bool {
let status = Command::new("rclone")
let mut binding = Command::new("rclone");
let command = binding
.arg("--config")
.arg(format!("{}", self.config_path.to_string_lossy()))
.arg("--contimeout")
.arg("5s")
// HTTP request is a typical low level operation, which will retry for many times
// https://rclone.org/docs/#low-level-retries-number
// Here we set it to 3 to avoid long waiting time
.arg("--low-level-retries")
.arg("3")
.arg("ls")
.arg("minio:")
.status()
.expect("Failed to rclone");
.arg("minio:");
log::debug!("Checking rclone with command: {:?}", command);
let status = command.status().expect("Failed to rclone");

status.success()
}
Expand Down
9 changes: 5 additions & 4 deletions judger/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod agent;
mod env;
mod error;
mod handler;
mod option;
mod worker;

#[macro_use]
Expand All @@ -12,16 +12,17 @@ use actix_web::{web::Data, App, HttpServer};
use worker::JudgeWorker;

#[actix_web::main] // or #[tokio::main]
// The `Run` button provided by rust-analyzer will not work here
// Use `Debug` button instead
async fn main() -> std::io::Result<()> {
let opt = env::load_option();
env::setup_logger();
let opt = option::load_option();

// TODO: Send heartbeat here to a remote host

let worker = match JudgeWorker::new(
opt.platform_uri,
opt.fetch_task_interval,
opt.rclone_config,
opt.rclone_config_path,
opt.problem_package_bucket.clone(),
opt.problem_package_dir.clone(),
) {
Expand Down
25 changes: 16 additions & 9 deletions judger/src/env/mod.rs → judger/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,21 @@ use structopt::StructOpt;
#[structopt(name = "judger")]
pub struct JudgeServerOpt {
/// For loading Opt from .env file
#[structopt(long)]
pub env_path: Option<String>,
#[structopt(long, default_value = ".env")]
pub env_path: PathBuf,

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

// TODO: make rclone optional
#[structopt(long, default_value = "data/default-rclone.conf")]
pub rclone_config: PathBuf,
#[structopt(env = "RCLONE_CONFIG_PATH", default_value = "rclone.conf")]
pub rclone_config_path: 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")]
#[structopt(long, default_value = "problem-package")]
pub problem_package_dir: PathBuf,

#[structopt(env = "PLATFORM_URI", default_value = "http://localhost:8080/")]
Expand All @@ -29,21 +30,27 @@ pub struct JudgeServerOpt {
pub fetch_task_interval: u64,
}

/// Try to load env from a .env file, if not found, fallback to ENV
pub fn load_option() -> JudgeServerOpt {
println!("PWD: {:?}", std::env::current_dir().unwrap());
// First load env_path from Args
let opt = JudgeServerOpt::from_args();
if let Some(env_path) = opt.env_path {
dotenv::from_path(env_path).ok();
if opt.env_path.exists() {
println!("loading env from file: {:?}", opt.env_path);
dotenv::from_path(opt.env_path).ok();
} else {
println!("loading env from ENV");
dotenv::dotenv().ok();
}

setup_logger();

// Load opt again with ENV
let opt = JudgeServerOpt::from_args();
log::debug!("load opt: {:?}", opt);
opt
}

pub fn setup_logger() {
fn setup_logger() {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("debug")).init();
}
1 change: 1 addition & 0 deletions judger/src/worker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ impl JudgeWorker {
}

pub async fn run(&self) {
log::info!("judge task worker started");
let _ = self
.rclone_client
.sync_bucket(&self.package_bucket, &self.package_dir)
Expand Down

0 comments on commit cde4466

Please sign in to comment.