2.從0實現(xiàn)Online Judge(go語言)-Manager實現(xiàn)

源碼見:https://github.com/lovercode/GO_OJ.git,demo見:https://codelover.me/run.html

manager的實現(xiàn)

整個系統(tǒng)只需要啟動manager,就能帶動后面的CompilerRunner

problem協(xié)議實現(xiàn)

problem協(xié)議是manager咙俩,compiler病涨,runner相互通信的存淫,采用protobuf定義:

syntax="proto3";

enum status{
    Invail = 0;
    Pending = 1;            //系統(tǒng)繁忙榨婆,用戶程序正在排隊等待窿锉。
    Pending_Rejudge = 2;    //因為數(shù)據(jù)更新或其他原因酵熙,系統(tǒng)將重新判你的答案
    Compiling = 3;          //正在編譯轧简。
    Running = 4;            //正在運行并與標(biāo)準(zhǔn)數(shù)據(jù)進行比較。
    Wrong_Answer = 5;       //答案錯誤匾二。
    Runtime_Error = 6;      //運行時錯誤哮独,程序崩潰拳芙。
    Compile_Error = 7;      //編譯錯誤。
    Time_Limit_Exceeded = 8;//運行超出時間限制皮璧。
    Memory_Limit_Exceeded = 9;//超出內(nèi)存限制舟扎。
    Output_Limit_Exceeded = 10;//輸出的長度超過限制。
    Presentation_Error = 11;//答案正確悴务,但是輸出格式不匹配題目要求睹限。在一些要求比較嚴(yán)格的比賽中,格式錯也會被視為答案錯誤
    Accepted = 12;          //程序通過
}

enum language_type{
    Defalut = 0;
    C = 1;
    Cpp = 2;
    Java = 3;
    Bash = 4;
    Php = 5;
    Python = 6;
    Go = 7;
    Node = 8;

}
message source_code{
    string file_name=1;
    string file_data=2;
}

message problem{
    string uuid=1;                     //uuid唯一標(biāo)識
    status status = 2;                 //狀態(tài)
    repeated source_code source_code = 3;       //源碼
    repeated string input = 4;                  //輸入
    repeated string output = 5;                 //輸出
    string err_msg = 6;                //錯誤信息
    language_type type = 7;            //語言類型
    int64 create_time = 8;             //創(chuàng)建時間 
    string outside_id = 9;                  //外部outside_id
}

服務(wù)啟動先初始化消息隊列的消費者和生產(chǎn)者

func init() {
    consumer = mq.NewMqConsumer(conf.GlobalConfig.MsgConsumer)
    producer = mq.NewMqProducer(conf.GlobalConfig.CompileProducer)
}

然后開一直接收消息

func Prepare4Compile() {
    for data := range consumer.Ch {
        go prepare(data)
    }
}

編譯前準(zhǔn)備工作

func prepare(data []byte) {
    pro := &problem.Problem{}
    e := proto.Unmarshal(data, pro)
    if e != nil {
        log.Println("解析錯誤")
        return
    }
    config, has := hasConfig(pro)
    if !has {
        log.Println("不支持語言類型")
        return
    }
    initProblem(pro)
    prepareFile(pro, config)
    prepareOtherFile(pro, config)

    //通知 compiler
    info, e := proto.Marshal(pro)
    if e != nil {
        panic(e)
    }
    producer.MqPublish(conf.GlobalConfig.CompileProducer.Topic, string(info))

  • initProblem主要是分配id
  • prepareFileprepareOtherFile是為編譯運行做文件準(zhǔn)備
  • 準(zhǔn)備輸入文件格式為input_0.in
  • 準(zhǔn)備編譯腳本compiler.sh
  • 準(zhǔn)備運行前腳本before_run.sh
  • 準(zhǔn)備運行腳本run.sh
  • 準(zhǔn)備清理腳本clear.sh
  • 編譯腳本示例(C語言)compiler.sh
    此處編譯會有安全風(fēng)險讯檐,應(yīng)該控制gcc輸出內(nèi)容大小
#!/bin/sh
echo "c compile...$1"
resCode=0
gcc -o main *.c 1>compiler_err.msg 2>compiler_err.msg
res=$?
if [ "$res" -gt 0 ]
    then 
        resCode=1
fi

exit $resCode
  • 運行前腳本示例(C語言)before_run.sh
echo "before run..,user $2 run $1"
chown $2 ../$1 -R
chmod 700 ../$1 -R
  • 運行腳本示例(C語言)run.sh
    process是監(jiān)控程序
echo "c run...$1"
list=`find ./ |grep [0-9]\.in$`
for i in $list
do
    ../../process $2 ./main $i $i.out 
    res=$?
    echo $res
    if [ "$res" -gt 0 ]
        then 
            echo "run error"
            exit $res
    fi
done
  • 清理腳本示例(C語言)clear.sh
echo "c clear...$1"
rm -rf ../$1
ps -o pid,user | grep $2 | awk '{print$1}' | xargs kill -9

配置腳本的配置文件


[CompileConfigs.1]
    CompileSh="/home/codelover/go/src/go_oj/sh/C_Compile.sh"
    RunSh="/home/codelover/go/src/go_oj/sh/C_Run.sh"
    ClearSh="/home/codelover/go/src/go_oj/sh/C_Clear.sh"
    BeforeRunSh="/home/codelover/go/src/go_oj/sh/Before_Run.sh"
[CompileConfigs.2]
    CompileSh="/home/codelover/go/src/go_oj/sh/Cpp_Compile.sh"
    RunSh="/home/codelover/go/src/go_oj/sh/Cpp_Run.sh"
    ClearSh="/home/codelover/go/src/go_oj/sh/Cpp_Clear.sh"
    BeforeRunSh="/home/codelover/go/src/go_oj/sh/Before_Run.sh"
[CompileConfigs.3]
    CompileSh="/home/codelover/go/src/go_oj/sh/Java_Compile.sh"
    RunSh="/home/codelover/go/src/go_oj/sh/Java_Run.sh"
    ClearSh="/home/codelover/go/src/go_oj/sh/Java_Clear.sh"
    BeforeRunSh="/home/codelover/go/src/go_oj/sh/Before_Run.sh"
[CompileConfigs.4]
    CompileSh="/home/codelover/go/src/go_oj/sh/Bash_Compile.sh"
    RunSh="/home/codelover/go/src/go_oj/sh/Bash_Run.sh"
    ClearSh="/home/codelover/go/src/go_oj/sh/Bash_Clear.sh"
    BeforeRunSh="/home/codelover/go/src/go_oj/sh/Before_Run.sh"

[CompileConfigs.5]
    CompileSh="/home/codelover/go/src/go_oj/sh/Php_Compile.sh"
    RunSh="/home/codelover/go/src/go_oj/sh/Php_Run.sh"
    ClearSh="/home/codelover/go/src/go_oj/sh/Php_Clear.sh"
    BeforeRunSh="/home/codelover/go/src/go_oj/sh/Before_Run.sh"
[CompileConfigs.6]
    CompileSh="/home/codelover/go/src/go_oj/sh/Python_Compile.sh"
    RunSh="/home/codelover/go/src/go_oj/sh/Python_Run.sh"
    ClearSh="/home/codelover/go/src/go_oj/sh/Python_Clear.sh"
    BeforeRunSh="/home/codelover/go/src/go_oj/sh/Before_Run.sh"
[CompileConfigs.7]
    CompileSh="/home/codelover/go/src/go_oj/sh/Go_Compile.sh"
    RunSh="/home/codelover/go/src/go_oj/sh/Go_Run.sh"
    ClearSh="/home/codelover/go/src/go_oj/sh/Go_Clear.sh"
    BeforeRunSh="/home/codelover/go/src/go_oj/sh/Before_Run.sh"
[CompileConfigs.8]
    CompileSh="/home/codelover/go/src/go_oj/sh/Node_Compile.sh"
    RunSh="/home/codelover/go/src/go_oj/sh/Node_Run.sh"
    ClearSh="/home/codelover/go/src/go_oj/sh/Node_Clear.sh"
    BeforeRunSh="/home/codelover/go/src/go_oj/sh/Before_Run.sh"

準(zhǔn)備好文件后通過nsq通知compiler

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末羡疗,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子裂垦,更是在濱河造成了極大的恐慌顺囊,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蕉拢,死亡現(xiàn)場離奇詭異特碳,居然都是意外死亡,警方通過查閱死者的電腦和手機晕换,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進店門午乓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人闸准,你說我怎么就攤上這事益愈。” “怎么了夷家?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵蒸其,是天一觀的道長。 經(jīng)常有香客問我库快,道長摸袁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任义屏,我火速辦了婚禮靠汁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘闽铐。我一直安慰自己蝶怔,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布兄墅。 她就那樣靜靜地躺著踢星,像睡著了一般。 火紅的嫁衣襯著肌膚如雪察迟。 梳的紋絲不亂的頭發(fā)上斩狱,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天耳高,我揣著相機與錄音,去河邊找鬼所踊。 笑死泌枪,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的秕岛。 我是一名探鬼主播碌燕,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼继薛!你這毒婦竟也來了修壕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤遏考,失蹤者是張志新(化名)和其女友劉穎慈鸠,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體灌具,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡青团,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了咖楣。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片督笆。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡蘸拔,死狀恐怖天通,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情黍衙,我是刑警寧澤珠十,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布料扰,位于F島的核電站,受9級特大地震影響焙蹭,放射性物質(zhì)發(fā)生泄漏记罚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一壳嚎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧末早,春花似錦烟馅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至姿搜,卻和暖如春寡润,著一層夾襖步出監(jiān)牢的瞬間捆憎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工梭纹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留躲惰,地道東北人。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓变抽,卻偏偏與公主長得像础拨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子绍载,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內(nèi)容