From 8429988cb46817ec0aefa285e9ba27b9c76da5e6 Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Sun, 28 Jan 2024 18:15:07 +0800 Subject: [PATCH] fix: Prebuild should be independent of Languages --- internal/api/runner/build.go | 8 ++---- internal/service/runner/config.go | 27 ++++++++++++--------- internal/service/runner/new_problem.go | 16 ++++-------- resource/runner/problem/example/README.md | 10 ++++---- resource/runner/problem/example/config.json | 10 ++++---- 5 files changed, 33 insertions(+), 38 deletions(-) diff --git a/internal/api/runner/build.go b/internal/api/runner/build.go index 7cc13d5..c6749c7 100644 --- a/internal/api/runner/build.go +++ b/internal/api/runner/build.go @@ -34,12 +34,8 @@ func (h *handler) Build(_ context.Context, t *asynq.Task) error { for i := range config.Languages { // do not store in db - config.Languages[i].Judge.Type = "" - config.Languages[i].Judge.Script = "" - config.Languages[i].Judge.Cmp = "" - - // Compile and Run is ok - config.Languages[i].Runtime.Prebuild = runner.ConfigRuntime{} + config.Languages[i].Judge = runner.ConfigJudge{} + config.Prebuild = runner.ConfigRuntime{} config.Languages[i].Runtime.Check = runner.ConfigRuntime{} } diff --git a/internal/service/runner/config.go b/internal/service/runner/config.go index 92cd0cd..7e5ef5c 100644 --- a/internal/service/runner/config.go +++ b/internal/service/runner/config.go @@ -80,12 +80,11 @@ func (c *ConfigJudge) Validate(base string, lang string) error { type ConfigLanguage struct { Lang string `json:"Lang"` - Judge ConfigJudge `json:"Judge"` + Judge ConfigJudge `json:"Judge,omitempty"` Runtime struct { - Prebuild ConfigRuntime `json:"Prebuild"` - Compile ConfigRuntime `json:"Compile"` - Run ConfigRuntime `json:"Run"` - Check ConfigRuntime `json:"Check"` + Compile ConfigRuntime `json:"Compile"` + Run ConfigRuntime `json:"Run"` + Check ConfigRuntime `json:"Check,omitempty"` } `json:"Runtime"` } @@ -99,6 +98,7 @@ func (l *ConfigLanguage) JudgeScript() string { type Config struct { Languages []ConfigLanguage `json:"Languages"` + Prebuild ConfigRuntime `json:"Prebuild,omitempty"` Tasks []struct { Id int `json:"Id"` Points int32 `json:"Points"` @@ -115,8 +115,8 @@ func (c *Config) Validate(base string) error { "pypy3": {}, } + // check per language config for _, lang := range c.Languages { - // check language if _, ok := allowedLang[lang.Lang]; !ok { return fmt.Errorf("language %s is not allowed", lang.Lang) } @@ -125,7 +125,6 @@ func (c *Config) Validate(base string) error { // check judge config Do(func() error { return lang.Judge.Validate(base, lang.Lang) }). // 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.Run.Validate() }). Do(func() error { return lang.Runtime.Check.Validate() }). @@ -134,9 +133,15 @@ func (c *Config) Validate(base string) error { if err != nil { return err } - } + // check prebuild config + if err := c.Prebuild.Validate(); err != nil { + return err + } + + // check tasks + if len(c.Tasks) == 0 { return errors.New("no tasks") } @@ -193,9 +198,6 @@ func (s *service) ParseConfig(meta *JudgeMeta, skipCheck bool) (*Config, error) // fill default 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 { 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 } } + if config.Prebuild.Validate() != nil { + config.Prebuild = DefaultPrebuildRuntime + } if skipCheck { return config, nil diff --git a/internal/service/runner/new_problem.go b/internal/service/runner/new_problem.go index d75ec28..94fbb93 100644 --- a/internal/service/runner/new_problem.go +++ b/internal/service/runner/new_problem.go @@ -32,7 +32,7 @@ func (s *service) DownloadProblem(meta *JudgeMeta, url string) e.Status { 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) { return e.RunnerProblemNotExist } @@ -50,12 +50,6 @@ func (s *service) PrebuildProblem(meta *JudgeMeta, force bool) e.Status { 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") 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{ Image: ContainerImageFull, - Pid: int64(cLang.Runtime.Prebuild.NProcLimit + 3), // sh + bash + make - Memory: uint64(cLang.Runtime.Prebuild.MemoryLimit * 1024 * 1024), - Timeout: time.Duration((cLang.Runtime.Prebuild.TimeLimit+1000)/1000) * time.Second, + Pid: int64(config.Prebuild.NProcLimit + 3), // sh + bash + make + Memory: uint64(config.Prebuild.MemoryLimit * 1024 * 1024), + Timeout: time.Duration((config.Prebuild.TimeLimit+1000)/1000) * time.Second, }, } args.Runtime.Mount = []specs.Mount{ @@ -114,7 +108,7 @@ func (s *service) NewProblem(meta *JudgeMeta, url string, force bool) (*Config, return &Config{}, e.RunnerProblemParseFailed } - status := s.PrebuildProblem(meta, true) + status := s.PrebuildProblem(meta, cfg, true) if status != e.Success { return &Config{}, status } diff --git a/resource/runner/problem/example/README.md b/resource/runner/problem/example/README.md index 14f9f0d..f577fd5 100644 --- a/resource/runner/problem/example/README.md +++ b/resource/runner/problem/example/README.md @@ -34,14 +34,12 @@ "Judge" : {"Type": "custom", "Script": "custom.Makefile", "Cmp": ""}, // 运行时配置:时间(ms) 内存(MB) 进/线程数目 "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 分 "Tasks" : [ // 第一个评测点,分值 10 分,使用 ./data/{input,output}/1.{input,output} 为测试数据 diff --git a/resource/runner/problem/example/config.json b/resource/runner/problem/example/config.json index acb3087..46bb174 100644 --- a/resource/runner/problem/example/config.json +++ b/resource/runner/problem/example/config.json @@ -2,12 +2,11 @@ "Languages": [ { "Lang" : "c", - "Judge" : {"Type": "custom", "Script": "XYZ.Makefile", "Cmp": ""}, + "Judge" : {"Type": "custom", "Script": "custom.Makefile", "Cmp": ""}, "Runtime": { - "Prebuild": {"TimeLimit": 300000, "MemoryLimit": 256, "NProcLimit": 64}, - "Compile" : {"TimeLimit": 60000, "MemoryLimit": 256, "NProcLimit": 64}, - "Run" : {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1}, - "Check" : {"TimeLimit": 60000, "MemoryLimit": 128, "NProcLimit": 64} + "Compile": {"TimeLimit": 60000, "MemoryLimit": 256, "NProcLimit": 64}, + "Run" : {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1}, + "Check" : {"TimeLimit": 60000, "MemoryLimit": 128, "NProcLimit": 64} } }, { @@ -18,6 +17,7 @@ } } ], + "Prebuild" : {"TimeLimit": 300000, "MemoryLimit": 256, "NProcLimit": 64}, "Tasks" : [ {"Id": 1, "Points": 10}, {"Id": 2, "Points": 20},