Skip to content

Commit

Permalink
feat: 🐛 change judger proto, dragft submit endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
Eason0729 committed Nov 23, 2023
1 parent 4a4b121 commit c30cd1c
Show file tree
Hide file tree
Showing 12 changed files with 271 additions and 80 deletions.
4 changes: 3 additions & 1 deletion backend/entity/src/submit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ pub struct Model {
pub user_id: Option<i32>,
pub problem_id: i32,
#[sea_orm(column_type = "Timestamp", on_insert = "current_timestamp", indexed)]
pub upload: DateTime,
pub upload_at: DateTime,
#[sea_orm(nullable, indexed)]
pub time: Option<u64>,
#[sea_orm(nullable)]
pub accuracy: Option<u64>,
#[sea_orm(default_value = "false")]
pub committed: bool,
pub lang: String,
Expand Down
13 changes: 6 additions & 7 deletions backend/src/controller/util/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,12 @@ impl Upstream {

let res = info.into_inner();

let langs: BTreeMap<String, LangInfo> = match res.langs {
Some(x) => x.list,
None => Vec::new(),
}
.into_iter()
.map(|x| (x.lang_uid.clone(), x))
.collect();
let langs: BTreeMap<String, LangInfo> = res
.langs
.list
.into_iter()
.map(|x| (x.lang_uid.clone(), x))
.collect();

*self.accuracy.write() = res.accuracy;
*self.langs.write() = langs;
Expand Down
68 changes: 39 additions & 29 deletions backend/src/controller/util/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,39 @@ use std::cmp;

use tokio::sync::broadcast::*;

use crate::grpc::backend::{self, submit_status, JudgeResultState as BackendState, SubmitStatus};
use crate::grpc::judger::{judge_response, JudgeResponse, JudgeResultState as JudgeState};
use crate::grpc::backend::{
self, judge_result, submit_status, StateCode as BackendCode, SubmitStatus,
};
use crate::grpc::judger::{judge_response, JudgeResponse, JudgeResultState as JudgeCode};

impl Into<BackendState> for JudgeState {
fn into(self) -> BackendState {
impl Into<BackendCode> for JudgeCode {
fn into(self) -> BackendCode {
match self {
JudgeState::Ac => BackendState::Ac,
JudgeState::Wa => BackendState::Wa,
JudgeState::Tle => BackendState::Tle,
JudgeState::Mle => BackendState::Mle,
JudgeState::Re => BackendState::Re,
JudgeState::Ce => BackendState::Ce,
JudgeState::Ole => BackendState::Ole,
JudgeState::Na => BackendState::Na,
JudgeState::Rf => BackendState::Rf,
JudgeCode::Ac => BackendCode::Ac,
JudgeCode::Wa => BackendCode::Wa,
JudgeCode::Tle => BackendCode::Tle,
JudgeCode::Mle => BackendCode::Mle,
JudgeCode::Re => BackendCode::Re,
JudgeCode::Ce => BackendCode::Ce,
JudgeCode::Ole => BackendCode::Ole,
JudgeCode::Na => BackendCode::Na,
JudgeCode::Rf => BackendCode::Rf,
}
}
}

impl Into<JudgeState> for BackendState {
fn into(self) -> JudgeState {
impl Into<JudgeCode> for BackendCode {
fn into(self) -> JudgeCode {
match self {
BackendState::Ac => JudgeState::Ac,
BackendState::Wa => JudgeState::Wa,
BackendState::Tle => JudgeState::Tle,
BackendState::Mle => JudgeState::Mle,
BackendState::Re => JudgeState::Re,
BackendState::Ce => JudgeState::Ce,
BackendState::Ole => JudgeState::Ole,
BackendState::Na => JudgeState::Na,
BackendState::Rf => JudgeState::Rf,
BackendCode::Ac => JudgeCode::Ac,
BackendCode::Wa => JudgeCode::Wa,
BackendCode::Tle => JudgeCode::Tle,
BackendCode::Mle => JudgeCode::Mle,
BackendCode::Re => JudgeCode::Re,
BackendCode::Ce => JudgeCode::Ce,
BackendCode::Ole => JudgeCode::Ole,
BackendCode::Na => JudgeCode::Na,
BackendCode::Rf => JudgeCode::Rf,
}
}
}
Expand All @@ -50,7 +52,11 @@ impl State {
tx: &mut Sender<Result<SubmitStatus, tonic::Status>>,
res: JudgeResponse,
) {
match res.task.unwrap_or_default() {
if res.task.is_none() {
log::warn!("mismatch proto(judger)");
return;
}
match res.task.unwrap() {
judge_response::Task::Case(case) => {
tx.send(Ok(SubmitStatus {
task: Some(submit_status::Task::Case(case)),
Expand All @@ -59,16 +65,20 @@ impl State {
}
judge_response::Task::Result(res) => {
tx.send(Ok(SubmitStatus {
// TODO: rework the judger.proto
task: Some(submit_status::Task::Result(backend::JudgeResult {
status: res.status() as i32,
max_time: Some(res.max_time),
max_mem: Some(res.max_mem),
info: Some(judge_result::Info::Committed(judge_result::Committed {
code: JudgeCode::from_i32(res.status).unwrap_or_default().into(),
accuracy: res.accuracy,
time: res.max_time,
memory: res.max_mem,
})),
})),
}))
.ok();
self.time = cmp::max(self.time, res.max_time);
self.mem = cmp::max(self.mem, res.max_mem);
if res.status() == JudgeState::Ac {
if res.status() == JudgeCode::Ac {
self.pass += 1;
}
}
Expand Down
1 change: 1 addition & 0 deletions backend/src/endpoint/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod contest;
mod education;
pub mod problem;
pub mod submit;
pub mod testcase;
pub mod token;
pub mod user;
Expand Down
127 changes: 127 additions & 0 deletions backend/src/endpoint/submit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
use super::endpoints::*;
use super::tools::*;

use super::util::stream::*;
use super::util::time::into_prost;
use crate::grpc::backend::submit_set_server::*;
use crate::grpc::backend::*;

use entity::{submit::*, *};

impl Filter for Entity {
fn read_filter<S: QueryFilter + Send>(query: S, auth: &Auth) -> Result<S, Error> {
Ok(query)
}

fn write_filter<S: QueryFilter + Send>(query: S, auth: &Auth) -> Result<S, Error> {
if let Some(perm) = auth.user_perm() {
if perm.can_manage_submit() || perm.can_root() {
return Ok(query);
}
}
Err(Error::Unauthenticated)
}
}

impl From<i32> for SubmitId {
fn from(value: i32) -> Self {
SubmitId { id: value }
}
}

impl From<SubmitId> for i32 {
fn from(value: SubmitId) -> Self {
value.id
}
}

impl From<Model> for SubmitInfo {
fn from(value: Model) -> Self {
// TODO: solve devation aand uncommitted submit!
let state: JudgeResult = match value.committed {
true => todo!(),
false => todo!(),
};
SubmitInfo {
id: value.id.into(),
upload_time: into_prost(value.upload_at),
score: value.score,
state,
}
}
}

#[async_trait]
impl SubmitSet for Arc<Server> {
async fn list(
&self,
req: Request<ListRequest>,
) -> Result<Response<ListSubmitResponse>, Status> {
let (auth, req) = self.parse_request(req).await?;

let mut reverse = false;
let mut pager: Pager<Entity> = match req.request.ok_or(Error::NotInPayload("request"))? {
list_request::Request::Create(create) => {
Pager::sort_search(create.sort_by(), create.reverse)
}
list_request::Request::Pager(old) => {
reverse = old.reverse;
<Pager<Entity> as HasParentPager<problem::Entity, Entity>>::from_raw(old.session)?
}
};

let list = pager
.fetch(req.size, req.offset.unwrap_or_default(), reverse, &auth)
.await?
.into_iter()
.map(|x| x.into())
.collect();

let next_session = pager.into_raw();

Ok(Response::new(ListSubmitResponse { list, next_session }))
}

async fn list_by_problem(
&self,
req: Request<ListByRequest>,
) -> Result<Response<ListSubmitResponse>, tonic::Status> {
todo!()
}

async fn info(&self, req: Request<SubmitId>) -> Result<Response<SubmitInfo>, Status> {
todo!()
}

async fn create(
&self,
req: Request<CreateSubmitRequest>,
) -> Result<Response<SubmitId>, Status> {
todo!()
}

async fn remove(
&self,
req: Request<SubmitId>,
) -> std::result::Result<tonic::Response<()>, Status> {
todo!()
}

#[doc = " Server streaming response type for the Follow method."]
type FollowStream = TonicStream<SubmitStatus>;

#[doc = " are not guarantee to yield status"]
async fn follow(
&self,
req: Request<SubmitId>,
) -> std::result::Result<tonic::Response<Self::FollowStream>, Status> {
todo!()
}

async fn rejudge(
&self,
req: Request<RejudgeRequest>,
) -> std::result::Result<tonic::Response<()>, Status> {
todo!()
}
}
8 changes: 4 additions & 4 deletions backend/src/endpoint/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ impl Filter for Entity {
}

fn write_filter<S: QueryFilter + Send>(query: S, auth: &Auth) -> Result<S, Error> {
let (user_id,perm)=auth.ok_or_default()?;
if perm.can_root() || perm.can_manage_user() {
return Ok(query);
}
let (user_id, perm) = auth.ok_or_default()?;
if perm.can_root() || perm.can_manage_user() {
return Ok(query);
}
Ok(query.filter(Column::Id.eq(user_id)))
}
}
Expand Down
1 change: 1 addition & 0 deletions backend/src/endpoint/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ pub mod filter;
pub mod hash;
pub mod macro_tool;
pub mod pagination;
pub mod stream;
pub mod time;
27 changes: 27 additions & 0 deletions backend/src/endpoint/util/pagination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,3 +517,30 @@ impl PagerTrait for user::Entity {
user::Entity::read_filter(select, auth)
}
}
#[tonic::async_trait]
impl PagerTrait for submit::Entity {
const TYPE_NUMBER: i32 = 539267;

const COL_ID: Self::Column = submit::Column::Id;

const COL_TEXT: &'static [Self::Column] = &[submit::Column::Id];

const COL_SELECT: &'static [Self::Column] = &[
submit::Column::Committed,
submit::Column::Id,
submit::Column::Time,
submit::Column::Memory,
submit::Column::PassCase,
submit::Column::UploadAt,
];

type ParentMarker = HasParent<problem::Entity>;

fn get_id(model: &Self::Model) -> i32 {
model.id
}

async fn query_filter(select: Select<Self>, auth: &Auth) -> Result<Select<Self>, Error> {
submit::Entity::read_filter(select, auth)
}
}
12 changes: 10 additions & 2 deletions judger/src/grpc/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ use super::proto::prelude::{judger_server::Judger, *};

pub type UUID = String;

fn accuracy() -> u64 {
let config = CONFIG.get().unwrap();
(1000 * 1000 / config.kernel.kernel_hz) as u64
}

macro_rules! report {
($result:expr,$tx:expr) => {
match $result {
Expand Down Expand Up @@ -58,6 +63,7 @@ macro_rules! report {
status: res as i32,
max_time: 0,
max_mem: 0,
accuracy: accuracy(),
})),
}))
.await
Expand Down Expand Up @@ -138,6 +144,7 @@ impl Judger for Server {
status: x as i32,
max_time: result.time().total_us,
max_mem: result.mem().peak,
accuracy: accuracy(),
})),
}))
.await
Expand All @@ -153,6 +160,7 @@ impl Judger for Server {
} as i32,
max_time: result.time().total_us,
max_mem: result.mem().peak,
accuracy: accuracy(),
})),
}))
.await
Expand All @@ -176,9 +184,9 @@ impl Judger for Server {
let modules = self.factory.list_module();

Ok(Response::new(JudgeInfo {
langs: Some(Langs { list: modules }),
langs: Langs { list: modules },
memory: config.platform.available_memory,
accuracy: (1000 * 1000 / config.kernel.kernel_hz) as u64,
accuracy: accuracy(),
cpu_factor: config.platform.cpu_time_multiplier as f32,
}))
}
Expand Down
Loading

0 comments on commit c30cd1c

Please sign in to comment.