源码见:https://github.com/lovercode/GO_OJ.git,demo见:https://codelover.me/run.html
Compiler的实现
compiler
的实现比较简单,直接调用 compile.sh
编译代码就行,编译期的安全,可以在脚本中限制,同时可以限制编译的运行时间。
OJ技术思考:评测安全
var consumer *mq.MqConsumer
var producer *mq.MqProducer
func init() {
consumer = mq.NewMqConsumer(conf.GlobalConfig.CompilerConsumer)
producer = mq.NewMqProducer(conf.GlobalConfig.RunProducer)
}
func main() {
for data := range consumer.Ch {
go compile(data)
}
ch := make(chan int)
<-ch
}
func compile(data []byte) {
pro := &problem.Problem{}
e := proto.Unmarshal(data, pro)
if e != nil {
log.Println("解析错误")
return
}
topic, has := conf.GlobalConfig.RunConfig[fmt.Sprintf("%d", pro.GetType())]
if !has {
log.Println("没有找到相关配置")
return
}
cmd := exec.Command("/bin/sh", "./compile.sh", pro.GetUuid())
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Dir = conf.GlobalConfig.WorkDirPre + "/" + pro.GetUuid()
err := cmd.Run()
if err != nil {
bytes, err := ioutil.ReadFile(conf.GlobalConfig.WorkDirPre + "/" + pro.GetUuid() + "/compiler_err.msg")
if err != nil {
pro.ErrMsg = "获取编译信息失败"
} else {
pro.ErrMsg = string(bytes)
}
pro.Status = problem.Status_Compile_Error
notifyOther(pro)
log.Println("编译错误", err)
return
}
pro.Status = problem.Status_Running
info, e := proto.Marshal(pro)
if e != nil {
panic(e)
}
log.Printf("%s:compile cost:%dms\n", pro.GetUuid(), time.Now().UnixNano()/1000000-pro.GetCreateTime())
producer.MqPublish(topic.RunTopic, string(info))
}
func notifyOther(pro *problem.Problem) {
info, e := proto.Marshal(pro)
if e != nil {
panic(e)
}
producer.MqPublish(conf.GlobalConfig.RunEndTopic, string(info))
}
编译完就可以通知runner
了
网友评论