Skip to content

Commit

Permalink
New judge and glue components.
Browse files Browse the repository at this point in the history
  • Loading branch information
mraron committed Apr 9, 2024
1 parent b7741f3 commit 980aaa2
Show file tree
Hide file tree
Showing 13 changed files with 569 additions and 363 deletions.
95 changes: 73 additions & 22 deletions cmd/glue.go
Original file line number Diff line number Diff line change
@@ -1,39 +1,90 @@
package cmd

import (
"errors"
"fmt"
"github.com/mraron/njudge/internal/glue"
"github.com/mraron/njudge/internal/judge2"
"github.com/mraron/njudge/internal/web/helpers/config"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"io/fs"
"strings"
)

var GlueCmd = &cobra.Command{
Use: "glue",
Short: "",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
BindEnvs(glue.Config{})
viper.SetEnvPrefix("njudge")

viper.SetConfigName("glue")
viper.AddConfigPath(".")
viper.AutomaticEnv()
return viper.MergeInConfig()
type GlueConfig struct {
Database config.Database
}

var DefaultGlueConfig = GlueConfig{
Database: config.Database{
User: "postgres",
Password: "postgres",
Host: "db",
Name: "postgres",
Port: 5432,
SSLMode: true,
},
}

RunE: func(cmd *cobra.Command, args []string) error {
cfg := glue.Config{}
func NewGlueCmd(v *viper.Viper) *cobra.Command {
cfg := GlueConfig{}
cmd := &cobra.Command{
Use: "glue",
Short: "start glue service",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
v.SetConfigFile("glue.yaml")
v.AddConfigPath(".")

err := viper.Unmarshal(&cfg)
if err != nil {
return err
}
v.SetDefault("db.user", DefaultGlueConfig.Database.User)
v.SetDefault("db.password", DefaultGlueConfig.Database.Password)
v.SetDefault("db.host", DefaultGlueConfig.Database.Host)
v.SetDefault("db.name", DefaultGlueConfig.Database.Name)
v.SetDefault("db.port", DefaultGlueConfig.Database.Port)
v.SetDefault("db.sslmode", DefaultGlueConfig.Database.SSLMode)

s := glue.Server{Config: cfg}
s.Run()
v.AutomaticEnv()
v.SetEnvPrefix("njudge")

return nil
},
if err := v.ReadInConfig(); err != nil {
var res *fs.PathError
if !errors.As(err, &res) {
return err
}
}

cmd.Flags().VisitAll(func(flag *pflag.Flag) {
configName := strings.ReplaceAll(flag.Name, "-", "")
if !flag.Changed && v.IsSet(configName) {
val := v.Get(configName)
_ = cmd.Flags().Set(flag.Name, fmt.Sprintf("%v", val))
}
})

return nil
},

RunE: func(cmd *cobra.Command, args []string) error {
g, err := glue.New(judge2.NewClient("http://localhost:8888"), glue.WithDatabaseOption(cfg.Database))
if err != nil {
return err
}
g.Start(cmd.Context())
return nil
},
}

cmd.Flags().StringVar(&cfg.Database.User, "db.user", DefaultGlueConfig.Database.User, "database user")
cmd.Flags().StringVar(&cfg.Database.Password, "db.password", DefaultGlueConfig.Database.Password, "database password")
cmd.Flags().StringVar(&cfg.Database.Host, "db.host", DefaultGlueConfig.Database.Password, "database host")
cmd.Flags().StringVar(&cfg.Database.Name, "db.name", DefaultGlueConfig.Database.Name, "database name")
cmd.Flags().IntVar(&cfg.Database.Port, "db.port", DefaultGlueConfig.Database.Port, "database port")
cmd.Flags().BoolVar(&cfg.Database.SSLMode, "db.sslmode", DefaultGlueConfig.Database.SSLMode, "database sslmode")

return cmd
}

func init() {
RootCmd.AddCommand(GlueCmd)
RootCmd.AddCommand(NewGlueCmd(viper.GetViper()))
}
146 changes: 90 additions & 56 deletions cmd/judge.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package cmd

import (
"errors"
"fmt"
"github.com/mraron/njudge/internal/judge2"
"github.com/mraron/njudge/pkg/language"
"github.com/mraron/njudge/pkg/language/sandbox"
"github.com/mraron/njudge/pkg/problems"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"io/fs"
"log/slog"
"strings"
"time"
)

Expand All @@ -21,68 +26,97 @@ type JudgeConfig struct {
UpdateStatusLimitEvery time.Duration
}

var JudgeCmd = &cobra.Command{
Use: "judge",
Short: "start judge server",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
viper.SetConfigFile("judge.yaml")
viper.AddConfigPath(".")

viper.SetDefault("port", 8080)
viper.SetDefault("problemsDir", "/problems")
viper.SetDefault("isolate", true)
viper.SetDefault("isolateSandboxRange", []int{400, 444})
viper.SetDefault("updateStatusLimitEvery", 5*time.Second)

viper.AutomaticEnv()
viper.SetEnvPrefix("njudge")

return viper.MergeInConfig()
},

RunE: func(cmd *cobra.Command, args []string) error {
cfg := JudgeConfig{}

if err := viper.Unmarshal(&cfg); err != nil {
return err
}

store := problems.NewFsStore(cfg.ProblemsDir)
provider := sandbox.NewProvider()
if cfg.Isolate {
for i := cfg.IsolateSandboxRange[0]; i <= cfg.IsolateSandboxRange[1]; i++ {
s, err := sandbox.NewIsolate(i)
if err != nil {
var DefaultJudgeConfig = JudgeConfig{
Port: 8080,
ProblemsDir: "/problems",
Isolate: true,
IsolateSandboxRange: []int{400, 444},
UpdateStatusLimitEvery: 5 * time.Second,
}

func NewJudgeCmd(v *viper.Viper) *cobra.Command {
cfg := JudgeConfig{}
cmd := &cobra.Command{
Use: "judge",
Short: "start judge server",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
v.SetConfigFile("judge.yaml")
v.AddConfigPath(".")

v.SetDefault("port", DefaultJudgeConfig.Port)
v.SetDefault("problemsDir", DefaultJudgeConfig.ProblemsDir)
v.SetDefault("isolate", DefaultJudgeConfig.Isolate)
v.SetDefault("isolateSandboxRange", DefaultJudgeConfig.IsolateSandboxRange)
v.SetDefault("updateStatusLimitEvery", DefaultJudgeConfig.UpdateStatusLimitEvery)

v.AutomaticEnv()
v.SetEnvPrefix("njudge")

if err := v.ReadInConfig(); err != nil {
var res *fs.PathError
if !errors.As(err, &res) {
return err
}
provider.Put(s)
}
} else {
for i := 0; i < 10; i++ {
s, err := sandbox.NewDummy()
if err != nil {
return err

cmd.Flags().VisitAll(func(flag *pflag.Flag) {
configName := strings.ReplaceAll(flag.Name, "-", "")
fmt.Println(configName, flag.Changed, v.IsSet(configName))
if !flag.Changed && v.IsSet(configName) {
val := v.Get(configName)
_ = cmd.Flags().Set(flag.Name, fmt.Sprintf("%v", val))
}
})

return nil
},

RunE: func(cmd *cobra.Command, args []string) error {
store := problems.NewFsStore(cfg.ProblemsDir)
provider := sandbox.NewProvider()
if cfg.Isolate {
for i := cfg.IsolateSandboxRange[0]; i <= cfg.IsolateSandboxRange[1]; i++ {
s, err := sandbox.NewIsolate(i)
if err != nil {
return err
}
provider.Put(s)
}
} else {
for i := 0; i < 10; i++ {
s, err := sandbox.NewDummy()
if err != nil {
return err
}
provider.Put(s)
}
provider.Put(s)
}
}

server := judge2.NewServer(
slog.Default(),
&judge2.Judge{
SandboxProvider: provider,
ProblemStore: store,
LanguageStore: language.DefaultStore,
RateLimit: cfg.UpdateStatusLimitEvery,
},
store,
judge2.WithPortServerOption(cfg.Port),
)

return server.Run()
},

server := judge2.NewServer(
slog.Default(),
&judge2.Judge{
SandboxProvider: provider,
ProblemStore: store,
LanguageStore: language.DefaultStore,
RateLimit: cfg.UpdateStatusLimitEvery,
},
store,
judge2.WithPortServerOption(cfg.Port),
)

return server.Run()
},
}

cmd.Flags().IntVar(&cfg.Port, "port", DefaultJudgeConfig.Port, "port to listen on")
cmd.Flags().StringVar(&cfg.ProblemsDir, "problems-dir", DefaultJudgeConfig.ProblemsDir, "directory of the problems")
cmd.Flags().BoolVar(&cfg.Isolate, "isolate", DefaultJudgeConfig.Isolate, "use isolate (otherwise dummy sandboxes are used which are NOT secure)")
cmd.Flags().IntSliceVar(&cfg.IsolateSandboxRange, "isolate-sandbox-range", DefaultJudgeConfig.IsolateSandboxRange, "inclusive interval of isolate sandbox IDs")
cmd.Flags().DurationVar(&cfg.UpdateStatusLimitEvery, "updateStatus-limit-every", DefaultJudgeConfig.UpdateStatusLimitEvery, "the rate of status updates for the clients")

return cmd
}

func init() {
RootCmd.AddCommand(JudgeCmd)
RootCmd.AddCommand(NewJudgeCmd(viper.GetViper()))
}
2 changes: 1 addition & 1 deletion cmd/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ var WebCmd = &cobra.Command{

RunE: func(cmd *cobra.Command, args []string) error {
cfg := config.Server{}

err := viper.Unmarshal(&cfg)
if err != nil {
return err
}
fmt.Println(cfg)

s := web.Server{Server: cfg}
s.Run()
Expand Down
Loading

0 comments on commit 980aaa2

Please sign in to comment.