fix: Prebuild should be independent of Languages

This commit is contained in:
Paul Pan 2024-01-28 18:15:07 +08:00
parent 83d3913ba7
commit 8429988cb4
Signed by: Paul
GPG Key ID: D639BDF5BA578AF4
5 changed files with 33 additions and 38 deletions

View File

@ -34,12 +34,8 @@ func (h *handler) Build(_ context.Context, t *asynq.Task) error {
for i := range config.Languages { for i := range config.Languages {
// do not store in db // do not store in db
config.Languages[i].Judge.Type = "" config.Languages[i].Judge = runner.ConfigJudge{}
config.Languages[i].Judge.Script = "" config.Prebuild = runner.ConfigRuntime{}
config.Languages[i].Judge.Cmp = ""
// Compile and Run is ok
config.Languages[i].Runtime.Prebuild = runner.ConfigRuntime{}
config.Languages[i].Runtime.Check = runner.ConfigRuntime{} config.Languages[i].Runtime.Check = runner.ConfigRuntime{}
} }

View File

@ -80,12 +80,11 @@ func (c *ConfigJudge) Validate(base string, lang string) error {
type ConfigLanguage struct { type ConfigLanguage struct {
Lang string `json:"Lang"` Lang string `json:"Lang"`
Judge ConfigJudge `json:"Judge"` Judge ConfigJudge `json:"Judge,omitempty"`
Runtime struct { Runtime struct {
Prebuild ConfigRuntime `json:"Prebuild"` Compile ConfigRuntime `json:"Compile"`
Compile ConfigRuntime `json:"Compile"` Run ConfigRuntime `json:"Run"`
Run ConfigRuntime `json:"Run"` Check ConfigRuntime `json:"Check,omitempty"`
Check ConfigRuntime `json:"Check"`
} `json:"Runtime"` } `json:"Runtime"`
} }
@ -99,6 +98,7 @@ func (l *ConfigLanguage) JudgeScript() string {
type Config struct { type Config struct {
Languages []ConfigLanguage `json:"Languages"` Languages []ConfigLanguage `json:"Languages"`
Prebuild ConfigRuntime `json:"Prebuild,omitempty"`
Tasks []struct { Tasks []struct {
Id int `json:"Id"` Id int `json:"Id"`
Points int32 `json:"Points"` Points int32 `json:"Points"`
@ -115,8 +115,8 @@ func (c *Config) Validate(base string) error {
"pypy3": {}, "pypy3": {},
} }
// check per language config
for _, lang := range c.Languages { for _, lang := range c.Languages {
// check language
if _, ok := allowedLang[lang.Lang]; !ok { if _, ok := allowedLang[lang.Lang]; !ok {
return fmt.Errorf("language %s is not allowed", lang.Lang) return fmt.Errorf("language %s is not allowed", lang.Lang)
} }
@ -125,7 +125,6 @@ func (c *Config) Validate(base string) error {
// check judge config // check judge config
Do(func() error { return lang.Judge.Validate(base, lang.Lang) }). Do(func() error { return lang.Judge.Validate(base, lang.Lang) }).
// check runtime limits // check runtime limits
Do(func() error { return lang.Runtime.Prebuild.Validate() }).
Do(func() error { return lang.Runtime.Compile.Validate() }). Do(func() error { return lang.Runtime.Compile.Validate() }).
Do(func() error { return lang.Runtime.Run.Validate() }). Do(func() error { return lang.Runtime.Run.Validate() }).
Do(func() error { return lang.Runtime.Check.Validate() }). Do(func() error { return lang.Runtime.Check.Validate() }).
@ -134,9 +133,15 @@ func (c *Config) Validate(base string) error {
if err != nil { if err != nil {
return err return err
} }
} }
// check prebuild config
if err := c.Prebuild.Validate(); err != nil {
return err
}
// check tasks
if len(c.Tasks) == 0 { if len(c.Tasks) == 0 {
return errors.New("no tasks") return errors.New("no tasks")
} }
@ -193,9 +198,6 @@ func (s *service) ParseConfig(meta *JudgeMeta, skipCheck bool) (*Config, error)
// fill default // fill default
for idx := range config.Languages { for idx := range config.Languages {
if config.Languages[idx].Runtime.Prebuild.Validate() != nil {
config.Languages[idx].Runtime.Prebuild = DefaultPrebuildRuntime
}
if config.Languages[idx].Runtime.Compile.Validate() != nil { if config.Languages[idx].Runtime.Compile.Validate() != nil {
config.Languages[idx].Runtime.Compile = DefaultCompileRuntime config.Languages[idx].Runtime.Compile = DefaultCompileRuntime
} }
@ -203,6 +205,9 @@ func (s *service) ParseConfig(meta *JudgeMeta, skipCheck bool) (*Config, error)
config.Languages[idx].Runtime.Check = DefaultCheckRuntime config.Languages[idx].Runtime.Check = DefaultCheckRuntime
} }
} }
if config.Prebuild.Validate() != nil {
config.Prebuild = DefaultPrebuildRuntime
}
if skipCheck { if skipCheck {
return config, nil return config, nil

View File

@ -32,7 +32,7 @@ func (s *service) DownloadProblem(meta *JudgeMeta, url string) e.Status {
return e.Success return e.Success
} }
func (s *service) PrebuildProblem(meta *JudgeMeta, force bool) e.Status { func (s *service) PrebuildProblem(meta *JudgeMeta, config *Config, force bool) e.Status {
if !s.ProblemExists(meta) { if !s.ProblemExists(meta) {
return e.RunnerProblemNotExist return e.RunnerProblemNotExist
} }
@ -50,12 +50,6 @@ func (s *service) PrebuildProblem(meta *JudgeMeta, force bool) e.Status {
return e.Success return e.Success
} }
_, cLang, status := s.GetConfig(meta, false)
if status != e.Success {
s.log.Error("[new] parse config failed", zap.Any("meta", *meta))
return e.RunnerProblemParseFailed
}
dataDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version), "data") dataDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version), "data")
judgeDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version), "judge") judgeDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Version), "judge")
@ -65,9 +59,9 @@ func (s *service) PrebuildProblem(meta *JudgeMeta, force bool) e.Status {
}, },
Runtime: RuntimeArgs{ Runtime: RuntimeArgs{
Image: ContainerImageFull, Image: ContainerImageFull,
Pid: int64(cLang.Runtime.Prebuild.NProcLimit + 3), // sh + bash + make Pid: int64(config.Prebuild.NProcLimit + 3), // sh + bash + make
Memory: uint64(cLang.Runtime.Prebuild.MemoryLimit * 1024 * 1024), Memory: uint64(config.Prebuild.MemoryLimit * 1024 * 1024),
Timeout: time.Duration((cLang.Runtime.Prebuild.TimeLimit+1000)/1000) * time.Second, Timeout: time.Duration((config.Prebuild.TimeLimit+1000)/1000) * time.Second,
}, },
} }
args.Runtime.Mount = []specs.Mount{ args.Runtime.Mount = []specs.Mount{
@ -114,7 +108,7 @@ func (s *service) NewProblem(meta *JudgeMeta, url string, force bool) (*Config,
return &Config{}, e.RunnerProblemParseFailed return &Config{}, e.RunnerProblemParseFailed
} }
status := s.PrebuildProblem(meta, true) status := s.PrebuildProblem(meta, cfg, true)
if status != e.Success { if status != e.Success {
return &Config{}, status return &Config{}, status
} }

View File

@ -34,14 +34,12 @@
"Judge" : {"Type": "custom", "Script": "custom.Makefile", "Cmp": ""}, "Judge" : {"Type": "custom", "Script": "custom.Makefile", "Cmp": ""},
// 运行时配置:时间(ms) 内存(MB) 进/线程数目 // 运行时配置:时间(ms) 内存(MB) 进/线程数目
"Runtime": { "Runtime": {
// 题目构建阶段,用于生成测试数据等,可选,默认值见下
"Prebuild": {"TimeLimit": 300000, "MemoryLimit": 256, "NProcLimit": 64},
// 编译阶段,可选,默认值见下 // 编译阶段,可选,默认值见下
"Compile" : {"TimeLimit": 60000, "MemoryLimit": 256, "NProcLimit": 64}, "Compile": {"TimeLimit": 60000, "MemoryLimit": 256, "NProcLimit": 64},
// 运行阶段,必选 // 运行阶段,必选
"Run" : {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1}, "Run" : {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1},
// 答案检查阶段,可选,默认值见下 // 答案检查阶段,可选,默认值见下
"Check" : {"TimeLimit": 60000, "MemoryLimit": 128, "NProcLimit": 64} "Check" : {"TimeLimit": 60000, "MemoryLimit": 128, "NProcLimit": 64}
} }
}, },
{ {
@ -55,6 +53,8 @@
} }
} }
], ],
// 题目构建阶段,用于生成测试数据等,可选,默认值见下
"Prebuild" : {"TimeLimit": 300000, "MemoryLimit": 256, "NProcLimit": 64},
// 评测点信息,总分应当为 100 分 // 评测点信息,总分应当为 100 分
"Tasks" : [ "Tasks" : [
// 第一个评测点,分值 10 分,使用 ./data/{input,output}/1.{input,output} 为测试数据 // 第一个评测点,分值 10 分,使用 ./data/{input,output}/1.{input,output} 为测试数据

View File

@ -2,12 +2,11 @@
"Languages": [ "Languages": [
{ {
"Lang" : "c", "Lang" : "c",
"Judge" : {"Type": "custom", "Script": "XYZ.Makefile", "Cmp": ""}, "Judge" : {"Type": "custom", "Script": "custom.Makefile", "Cmp": ""},
"Runtime": { "Runtime": {
"Prebuild": {"TimeLimit": 300000, "MemoryLimit": 256, "NProcLimit": 64}, "Compile": {"TimeLimit": 60000, "MemoryLimit": 256, "NProcLimit": 64},
"Compile" : {"TimeLimit": 60000, "MemoryLimit": 256, "NProcLimit": 64}, "Run" : {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1},
"Run" : {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1}, "Check" : {"TimeLimit": 60000, "MemoryLimit": 128, "NProcLimit": 64}
"Check" : {"TimeLimit": 60000, "MemoryLimit": 128, "NProcLimit": 64}
} }
}, },
{ {
@ -18,6 +17,7 @@
} }
} }
], ],
"Prebuild" : {"TimeLimit": 300000, "MemoryLimit": 256, "NProcLimit": 64},
"Tasks" : [ "Tasks" : [
{"Id": 1, "Points": 10}, {"Id": 1, "Points": 10},
{"Id": 2, "Points": 20}, {"Id": 2, "Points": 20},