源碼見:https://github.com/lovercode/GO_OJ.git,demo見:https://codelover.me/run.html
manager的實現(xiàn)
整個系統(tǒng)只需要啟動manager
,就能帶動后面的Compiler
和Runner
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 -
prepareFile
和prepareOtherFile
是為編譯運行做文件準(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"