feat: #6 [3] Add LimitedWriter and move file related utils out from package utils
This commit is contained in:
parent
8e3222daab
commit
31391f6ce0
@ -7,6 +7,7 @@ import (
|
|||||||
"git.0x7f.app/WOJ/woj-server/internal/e"
|
"git.0x7f.app/WOJ/woj-server/internal/e"
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/model"
|
"git.0x7f.app/WOJ/woj-server/internal/model"
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/service/runner"
|
"git.0x7f.app/WOJ/woj-server/internal/service/runner"
|
||||||
|
"git.0x7f.app/WOJ/woj-server/pkg/file"
|
||||||
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
||||||
"github.com/hibiken/asynq"
|
"github.com/hibiken/asynq"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
@ -28,10 +29,10 @@ func (h *handler) Judge(_ context.Context, t *asynq.Task) error {
|
|||||||
|
|
||||||
// 1. write user code
|
// 1. write user code
|
||||||
userCode := filepath.Join(runner.UserDir, user, fmt.Sprintf("%s.%s", user, p.Submission.Language))
|
userCode := filepath.Join(runner.UserDir, user, fmt.Sprintf("%s.%s", user, p.Submission.Language))
|
||||||
if !utils.FileTouch(userCode) {
|
if !file.FileTouch(userCode) {
|
||||||
return e.InternalError, 0, systemError
|
return e.InternalError, 0, systemError
|
||||||
}
|
}
|
||||||
err := utils.FileWrite(userCode, []byte(p.Submission.Code))
|
err := file.FileWrite(userCode, []byte(p.Submission.Code))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return e.InternalError, 0, systemError
|
return e.InternalError, 0, systemError
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/model"
|
"git.0x7f.app/WOJ/woj-server/internal/model"
|
||||||
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
"git.0x7f.app/WOJ/woj-server/pkg/file"
|
||||||
"github.com/samber/do"
|
"github.com/samber/do"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
@ -19,7 +19,7 @@ type Service interface {
|
|||||||
func NewService(i *do.Injector) (Service, error) {
|
func NewService(i *do.Injector) (Service, error) {
|
||||||
cliCtx := do.MustInvoke[*cli.Context](i)
|
cliCtx := do.MustInvoke[*cli.Context](i)
|
||||||
|
|
||||||
data, err := utils.FileRead(cliCtx.String("config"))
|
data, err := file.FileRead(cliCtx.String("config"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to setup config: %s\n", err.Error())
|
log.Printf("Failed to setup config: %s\n", err.Error())
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -3,7 +3,7 @@ package runner
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/e"
|
"git.0x7f.app/WOJ/woj-server/internal/e"
|
||||||
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
"git.0x7f.app/WOJ/woj-server/pkg/file"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@ -69,10 +69,10 @@ func (s *service) checkAndExecute(version uint, user string, lang string, script
|
|||||||
|
|
||||||
func (s *service) ProblemExists(version uint) bool {
|
func (s *service) ProblemExists(version uint) bool {
|
||||||
problemPath := filepath.Join(ProblemDir, fmt.Sprintf("%d", version))
|
problemPath := filepath.Join(ProblemDir, fmt.Sprintf("%d", version))
|
||||||
return utils.FileExist(problemPath)
|
return file.FileExist(problemPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *service) userExists(user string, file string) bool {
|
func (s *service) userExists(user string, name string) bool {
|
||||||
userPath := filepath.Join(UserDir, user, file)
|
userPath := filepath.Join(UserDir, user, name)
|
||||||
return utils.FileExist(userPath)
|
return file.FileExist(userPath)
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package runner
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/e"
|
"git.0x7f.app/WOJ/woj-server/internal/e"
|
||||||
|
"git.0x7f.app/WOJ/woj-server/pkg/file"
|
||||||
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -15,11 +16,11 @@ func (s *service) Compile(version uint, user string, lang string) (JudgeStatus,
|
|||||||
status := s.checkAndExecute(version, user, lang, "problem_compile.sh", e.RunnerUserCompileFailed)
|
status := s.checkAndExecute(version, user, lang, "problem_compile.sh", e.RunnerUserCompileFailed)
|
||||||
|
|
||||||
log := filepath.Join(UserDir, user, fmt.Sprintf("%s.compile.log", user))
|
log := filepath.Join(UserDir, user, fmt.Sprintf("%s.compile.log", user))
|
||||||
msg, err := utils.FileRead(log)
|
msg, err := file.FileRead(log)
|
||||||
msg = utils.If(err == nil, msg, nil)
|
msg = utils.If(err == nil, msg, nil)
|
||||||
msgText := string(msg)
|
msgText := string(msg)
|
||||||
|
|
||||||
if !utils.FileExist(target) || utils.FileEmpty(target) {
|
if !file.FileExist(target) || file.FileEmpty(target) {
|
||||||
return JudgeStatus{
|
return JudgeStatus{
|
||||||
Message: "compile failed",
|
Message: "compile failed",
|
||||||
Tasks: []TaskStatus{{Verdict: VerdictCompileError, Message: msgText}}},
|
Tasks: []TaskStatus{{Verdict: VerdictCompileError, Message: msgText}}},
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/e"
|
"git.0x7f.app/WOJ/woj-server/internal/e"
|
||||||
|
"git.0x7f.app/WOJ/woj-server/pkg/file"
|
||||||
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"os"
|
"os"
|
||||||
@ -20,7 +21,7 @@ func (s *service) loadImage(cfg *depConfig) e.Status {
|
|||||||
err := utils.NewTryErr().
|
err := utils.NewTryErr().
|
||||||
Try(func() error {
|
Try(func() error {
|
||||||
// import from tarball
|
// import from tarball
|
||||||
if !utils.FileExist(cfg.tarball) {
|
if !file.FileExist(cfg.tarball) {
|
||||||
return errors.New("tarball not exists")
|
return errors.New("tarball not exists")
|
||||||
}
|
}
|
||||||
return s.execute("bash", "-c", fmt.Sprintf("gzip -d -c %s | podman load", cfg.tarball))
|
return s.execute("bash", "-c", fmt.Sprintf("gzip -d -c %s | podman load", cfg.tarball))
|
||||||
@ -31,7 +32,7 @@ func (s *service) loadImage(cfg *depConfig) e.Status {
|
|||||||
}).
|
}).
|
||||||
Or(func() error {
|
Or(func() error {
|
||||||
// build from dockerfile
|
// build from dockerfile
|
||||||
if !utils.FileExist(cfg.dockerfile) {
|
if !file.FileExist(cfg.dockerfile) {
|
||||||
return errors.New("dockerfile not exists")
|
return errors.New("dockerfile not exists")
|
||||||
}
|
}
|
||||||
return s.execute("podman", "build", "-f", cfg.dockerfile, "-t", cfg.image, ".")
|
return s.execute("podman", "build", "-f", cfg.dockerfile, "-t", cfg.image, ".")
|
||||||
@ -52,7 +53,7 @@ func (s *service) EnsureDeps(force bool) e.Status {
|
|||||||
// check mark
|
// check mark
|
||||||
if force {
|
if force {
|
||||||
_ = os.Remove(mark)
|
_ = os.Remove(mark)
|
||||||
} else if utils.FileExist(mark) {
|
} else if file.FileExist(mark) {
|
||||||
return e.Success
|
return e.Success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"git.0x7f.app/WOJ/woj-server/internal/e"
|
"git.0x7f.app/WOJ/woj-server/internal/e"
|
||||||
"git.0x7f.app/WOJ/woj-server/pkg/down"
|
"git.0x7f.app/WOJ/woj-server/pkg/down"
|
||||||
|
"git.0x7f.app/WOJ/woj-server/pkg/file"
|
||||||
"git.0x7f.app/WOJ/woj-server/pkg/unzip"
|
"git.0x7f.app/WOJ/woj-server/pkg/unzip"
|
||||||
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
@ -38,7 +39,7 @@ func (s *service) prebuild(version uint, force bool) e.Status {
|
|||||||
mark := filepath.Join(ProblemDir, fmt.Sprintf("%d", version), ".mark.prebuild")
|
mark := filepath.Join(ProblemDir, fmt.Sprintf("%d", version), ".mark.prebuild")
|
||||||
if force {
|
if force {
|
||||||
_ = os.Remove(mark)
|
_ = os.Remove(mark)
|
||||||
} else if utils.FileExist(mark) {
|
} else if file.FileExist(mark) {
|
||||||
return e.Success
|
return e.Success
|
||||||
}
|
}
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
"git.0x7f.app/WOJ/woj-server/pkg/file"
|
||||||
"golang.org/x/text/encoding/charmap"
|
"golang.org/x/text/encoding/charmap"
|
||||||
"io"
|
"io"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -57,7 +57,7 @@ func (t *TaskStatus) getInfoText(infoFile string) *TaskStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
t.infoText, err = utils.FileRead(infoFile)
|
t.infoText, err = file.FileRead(infoFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Verdict = VerdictSystemError
|
t.Verdict = VerdictSystemError
|
||||||
t.Message = "cannot read info file"
|
t.Message = "cannot read info file"
|
||||||
@ -128,7 +128,7 @@ func (t *TaskStatus) getJudgeText(judgeFile string) *TaskStatus {
|
|||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
j, err := utils.FileRead(judgeFile)
|
j, err := file.FileRead(judgeFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Verdict = VerdictSystemError
|
t.Verdict = VerdictSystemError
|
||||||
t.Message = "cannot read judge file"
|
t.Message = "cannot read judge file"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package utils
|
package file
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -20,7 +21,7 @@ func FileWrite(filePath string, content []byte) error {
|
|||||||
|
|
||||||
func FileExist(filePath string) bool {
|
func FileExist(filePath string) bool {
|
||||||
_, err := os.Stat(filePath)
|
_, err := os.Stat(filePath)
|
||||||
return If(err == nil || os.IsExist(err), true, false)
|
return utils.If(err == nil || os.IsExist(err), true, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func FileEmpty(filePath string) bool {
|
func FileEmpty(filePath string) bool {
|
||||||
@ -35,5 +36,5 @@ func FileTouch(filePath string) bool {
|
|||||||
base := filepath.Dir(filePath)
|
base := filepath.Dir(filePath)
|
||||||
_ = os.MkdirAll(base, 0755)
|
_ = os.MkdirAll(base, 0755)
|
||||||
_, err := os.OpenFile(filePath, os.O_RDONLY|os.O_CREATE, 0644)
|
_, err := os.OpenFile(filePath, os.O_RDONLY|os.O_CREATE, 0644)
|
||||||
return If(err == nil, true, false)
|
return utils.If(err == nil, true, false)
|
||||||
}
|
}
|
21
pkg/file/writer.go
Normal file
21
pkg/file/writer.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package file
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LimitedWriter struct {
|
||||||
|
File *os.File
|
||||||
|
Limit int64
|
||||||
|
n int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lw *LimitedWriter) Write(p []byte) (n int, err error) {
|
||||||
|
if lw.n+int64(len(p)) > lw.Limit {
|
||||||
|
return 0, fmt.Errorf("output limit exceeded")
|
||||||
|
}
|
||||||
|
n, err = lw.File.Write(p)
|
||||||
|
lw.n += int64(n)
|
||||||
|
return
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user