初版構想,碎碎念

簡易 OJ 的一些構想

想了一下,幾乎全是數據庫,crud,感覺在做上個世紀的破事(×)

還沒開始實現,所有構想都是口嗨,一些細節可能考慮不周。

也算是磕磕絆絆把一些基礎的 spring 學完了,找資料簡單看了一些全家桶,技術棧上應該除了兩個標黃的內容都差不多了。

數據庫

用 mybatis + mysql ,spring 提供了 mybatis 的集成,用起來非常方便。

登錄認證,權限

用 spring security:

加密用 Bcrypt 隨便瞎搞一下

認證用基礎的 name-password-sessionCookie 做認證,以下來自哈基米(×):

一句話結論:不要為了由於所謂的技術潮流而上 JWT,對於一個僅需郵箱登錄的 OJ,Session/Cookie 依然是統治級的最佳實踐。

鏈路認證和方法認證,spring security 都提供了完備的實現(我愛 spring!)

權限管理未解決

權限管理需要細化,簡單的線性 role 表不行,需要學習role hierarchy,製作有繼承關係的權限管理。

數據存儲

我想拿 alist 搞一個雲盤出來,或者直接存服務器本地,然後數據庫掛文件路徑讀文件。

各種數據

一個題面的數據schema

  • 題面.md
  • 數據包:
  • 一個 yml 配置數據列表,評測限制
  • 數據實例 in out
  • 如果有 specialjudge,需要 checker.cpp
  • 應該沒了?

可以仿照 polygon 包裝一個支持 testlib 的。

評測記錄schema(未確定)

想不動了,先鴿着。

個人界面(未確定)

頭都大了,要一堆東西。

評測系統

未解決

有兩個方案:

  • 搓一個,JVM 有線程管理工具,能掛 cgroup/namespace 做資源隔離,不過這個我不確定能否高性能,況且我只是瞭解過有這個東西,完全沒有手操過。和 cf 一樣採用的每個核跑一個評測(應該也只能這麼做?),對我這個 單U 8核 來説比較災難,分佈式的話一是沒錢,二是不會配(哭。
  • 用開源的,比如 青島U,domJudge,但得學,不會配。

實在沒時間搞就寫個最簡單的:只支持 c/c++,直接命令行搞,系統隔離統統不用,能跑就行。

後端交互

通信用 kafka ,隨便設計一個做交互就可以,測完結果直接存數據庫。

具體來説的話,數據庫只用來掛文件路由,可以在提交給 kafka 前就寫好,然後評測機不需要和數據庫交互,根據文件路由直接改文件就可以了。

讀的話通過數據庫找路由,直接讀,這裏可能會有線程同步的問題,不過應該問題不大?因為我也沒必要完全和當前評測相吻合,讀的時候缺一個少一個沒啥影響,最後能全測完就可以了。

有一説一,我多線程就沒怎麼看,算不上精通吧,只能説一點不會,所以説的很口嗨。

應該是個醜陋的實現()

前端交互

指如何把評測結果返回給前端。

作為 demo 自己刷新輪詢就行了,websocket 是不會配的。

輪詢的話,直接查數據庫,再掛個提交記錄的表,提交記錄,也搞進文件存儲,提交記錄掛數據庫去抓。

前端

AI 寫一個, 手搓是不可能的 ,寫後端已經夠累了。

比賽

這個應該得等大作業交完差後再實現了,需要重構一些底層。

一是權限管理太簡易了,是線性權限,如果給每一個比賽都加一個 contest+id 的權限,那數據庫得醜的不行,需要一些樹狀的繼承形權限。

二是對提交記錄的查詢需要更新,比賽和做題對同一個提交記錄的展示是不同的,例如數據點,評測細則這些就不能在比賽時展示,賽後可以展示。

三是比賽的種類多,NOI 賽制下需要部分分,xcpc 需要罰時和封榜,這需要多一些判題邏輯。

進一步

數據庫可以看情況做個緩存,不過 demo 上直接先查詢也是可接受的。

網關,反代沒有,要不就 Nginx 要不就 spring cloud gateway。

系統監控,不會。

vault 做個密鑰管理。

servlet MVC 用線程池掛請求,高併發估計會爆炸,有機會試試異步 MVC。

別的,再看?

到時候還能把多模塊配置掛到 git 上,用 spring cloud config 來讀。