Add environment variable controls

This commit is contained in:
criyle 2020-06-11 15:16:46 -04:00
parent d6f5660d6c
commit 140aeffcd9
2 changed files with 90 additions and 52 deletions

View File

@ -28,7 +28,8 @@ A rest service to run program in restricted environment and it is basically a wr
- /file/:fileId GET downloads file from executor service (in memory), returns file content
- /file/:fileId DELETE delete file specified by fileId
- /ws WebSocket for /run
- /metrics prometheus metrics
- /metrics prometheus metrics (specifies `METRICS=1` environment variable to enable metrics)
- /debug (specifies `DEBUG=1` environment variable to enable go runtime debug endpoint)
### Install & Run Developing Server
@ -49,15 +50,22 @@ Build by your own `docker build -t executorserver -f Dockerfile.exec .`
The `executorserver` need root privilege to create `cgroup`. Either creates sub-directory `/sys/fs/cgroup/cpuacct/go-judger`, `/sys/fs/cgroup/memory/go-judger`, `/sys/fs/cgroup/pids/go-judger` and make execution user readable or use `sudo` to run it.
The default binding address for the executor server is `:5050`. Can be specified with `-http` flag.
#### Command Line Arguments
The default binding address for the gRPC executor server is `:5051`. Can be specified with `-grpc` flag.
- The default binding address for the executor server is `:5050`. Can be specified with `-http` flag.
- The default binding address for the gRPC executor server is `:5051`. Can be specified with `-grpc` flag. (Notice: need to set `GRPC=1` environment variable to enable GRPC endpoint)
- The default concurrency is `4`, Can be specified with `-parallism` flag.
- The default file store is in memory, local cache can be specified with `-dir` flag.
- The default log level is debug, use `-silent` to disable logs.
The default concurrency is `4`, Can be specified with `-parallism` flag.
#### Environment Variables
The default file store is in memory, local cache can be specified with `-dir` flag.
The default log level is debug, use `-silent` to disable logs.
- The http binding address specifies as `HTTP_ADDR=addr`
- The grpc binding address specifies as `GRPC_ADDR=addr`
- The parallism specifies as `PARALLISM=4`
- `GRPC=1` enables gRPC
- `METRICS=1` enables metrics
- `DEBUG=1` enables debug
### Build Shared object

View File

@ -10,7 +10,7 @@ import (
"net/http"
"os"
"os/signal"
"runtime/pprof"
"strconv"
"strings"
"time"
@ -27,6 +27,16 @@ import (
"google.golang.org/grpc"
)
const (
envDebug = "DEBUG"
envMetrics = "METRICS"
envAddr = "HTTP_ADDR"
envGRPC = "GRPC"
envGRPCAddr = "GRPC_ADDR"
envParallism = "PARALLISM"
)
var (
addr = flag.String("http", ":5050", "specifies the http binding address")
grpcAddr = flag.String("grpc", ":5051", "specifies the grpc binding address")
@ -38,8 +48,6 @@ var (
mountConf = flag.String("mount", "mount.yaml", "specifics mount configuration file")
cinitPath = flag.String("cinit", "", "container init absolute path")
cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
printLog = func(v ...interface{}) {}
work *worker.Worker
@ -56,25 +64,39 @@ func newFilsStore(dir string) filestore.FileStore {
return fs
}
func initEnv() (bool, error) {
eneableGRPC := false
if s := os.Getenv(envAddr); s != "" {
addr = &s
}
if os.Getenv(envGRPC) == "1" {
eneableGRPC = true
}
if s := os.Getenv(envGRPCAddr); s != "" {
eneableGRPC = true
grpcAddr = &s
}
if s := os.Getenv(envParallism); s != "" {
p, err := strconv.Atoi(s)
if err != nil {
return false, err
}
parallism = &p
}
return eneableGRPC, nil
}
func main() {
flag.Parse()
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal("could not create CPU profile: ", err)
}
defer f.Close() // error handling omitted for example
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal("could not start CPU profile: ", err)
}
defer pprof.StopCPUProfile()
}
if !*silent {
printLog = log.Println
}
enableGRPC, err := initEnv()
if err != nil {
log.Fatalln("init environment variable failed", err)
}
// Init environment pool
fs := newFilsStore(*dir)
b, err := env.NewBuilder(*cinitPath, *mountConf, *tmpFsParam, *netShare, printLog)
if err != nil {
@ -95,17 +117,19 @@ func main() {
}
// Metrics Handle
p := ginprometheus.NewPrometheus("gin")
p.ReqCntURLLabelMappingFn = func(c *gin.Context) string {
url := c.Request.URL.Path
for _, p := range c.Params {
if p.Key == "fid" {
url = strings.Replace(url, p.Value, ":fid", 1)
if os.Getenv(envMetrics) == "1" {
p := ginprometheus.NewPrometheus("gin")
p.ReqCntURLLabelMappingFn = func(c *gin.Context) string {
url := c.Request.URL.Path
for _, p := range c.Params {
if p.Key == "fid" {
url = strings.Replace(url, p.Value, ":fid", 1)
}
}
return url
}
return url
p.Use(r)
}
p.Use(r)
// File Handles
fh := &fileHandle{fs: fs}
@ -121,20 +145,29 @@ func main() {
r.GET("/ws", handleWS)
// pprof
ginpprof.Register(r)
if os.Getenv(envDebug) != "" {
ginpprof.Register(r)
}
// gRPC server
grpcServer := grpc.NewServer(
grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),
grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor),
)
pb.RegisterExecutorServer(grpcServer, &execServer{fs: fs})
grpc_prometheus.Register(grpcServer)
grpc_prometheus.EnableHandlingTimeHistogram()
var grpcServer *grpc.Server
if enableGRPC {
grpcServer = grpc.NewServer(
grpc.StreamInterceptor(grpc_prometheus.StreamServerInterceptor),
grpc.UnaryInterceptor(grpc_prometheus.UnaryServerInterceptor),
)
pb.RegisterExecutorServer(grpcServer, &execServer{fs: fs})
grpc_prometheus.Register(grpcServer)
grpc_prometheus.EnableHandlingTimeHistogram()
lis, err := net.Listen("tcp", *grpcAddr)
if err != nil {
log.Fatalln(err)
lis, err := net.Listen("tcp", *grpcAddr)
if err != nil {
log.Fatalln(err)
}
go func() {
printLog("Starting grpc server at", *grpcAddr)
printLog("GRPC serve", grpcServer.Serve(lis))
}()
}
srv := http.Server{
@ -142,11 +175,6 @@ func main() {
Handler: r,
}
go func() {
printLog("Starting grpc server at", *grpcAddr)
printLog("GRPC serve", grpcServer.Serve(lis))
}()
go func() {
printLog("Starting http server at", *addr)
printLog("Http serve", srv.ListenAndServe())
@ -174,11 +202,13 @@ func main() {
return nil
})
eg.Go(func() error {
grpcServer.GracefulStop()
printLog("GRPC server shutdown")
return nil
})
if grpcServer != nil {
eg.Go(func() error {
grpcServer.GracefulStop()
printLog("GRPC server shutdown")
return nil
})
}
go func() {
printLog("Shutdown Finished", eg.Wait())