2019-11-06 12:33:46 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2019-12-13 16:02:48 +00:00
|
|
|
"crypto/ecdsa"
|
2020-02-14 10:07:52 +00:00
|
|
|
"errors"
|
2019-12-21 10:26:14 +00:00
|
|
|
"net/http"
|
|
|
|
_ "net/http/pprof"
|
2019-11-06 12:33:46 +00:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/labstack/echo/v4"
|
2019-12-21 10:26:14 +00:00
|
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
2019-11-06 12:33:46 +00:00
|
|
|
"go.uber.org/zap"
|
2019-12-13 16:02:48 +00:00
|
|
|
"google.golang.org/grpc/grpclog"
|
2019-11-06 12:33:46 +00:00
|
|
|
)
|
|
|
|
|
2019-12-21 10:26:14 +00:00
|
|
|
type router struct {
|
|
|
|
pool *Pool
|
2019-11-06 12:33:46 +00:00
|
|
|
log *zap.Logger
|
|
|
|
timeout time.Duration
|
2019-12-13 16:02:48 +00:00
|
|
|
key *ecdsa.PrivateKey
|
2019-11-06 12:33:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
var (
|
2020-02-25 15:35:46 +00:00
|
|
|
err error
|
|
|
|
pool *Pool
|
|
|
|
|
2019-12-21 10:26:14 +00:00
|
|
|
v = settings()
|
|
|
|
l = newLogger(v)
|
|
|
|
g = newGracefulContext(l)
|
2019-11-06 12:33:46 +00:00
|
|
|
)
|
|
|
|
|
2019-12-13 16:02:48 +00:00
|
|
|
if v.GetBool("verbose") {
|
2019-12-21 10:26:14 +00:00
|
|
|
grpclog.SetLoggerV2(gRPCLogger(l))
|
2019-12-13 16:02:48 +00:00
|
|
|
}
|
|
|
|
|
2020-02-25 15:35:46 +00:00
|
|
|
switch pool, err = newPool(g, l, v); {
|
|
|
|
case err == nil:
|
|
|
|
// ignore
|
|
|
|
case errors.Is(err, context.Canceled):
|
|
|
|
l.Info("close application")
|
|
|
|
return
|
|
|
|
default:
|
|
|
|
l.Error("could get connection", zap.Error(err))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2019-12-21 10:26:14 +00:00
|
|
|
r := &router{
|
|
|
|
log: l,
|
2020-02-25 15:35:46 +00:00
|
|
|
pool: pool,
|
2019-12-21 10:26:14 +00:00
|
|
|
key: fetchKey(l, v),
|
|
|
|
timeout: v.GetDuration("request_timeout"),
|
2019-11-06 12:33:46 +00:00
|
|
|
}
|
|
|
|
|
2019-12-21 10:26:14 +00:00
|
|
|
go checkConnection(g, r.pool)
|
2019-11-06 12:33:46 +00:00
|
|
|
|
|
|
|
e := echo.New()
|
|
|
|
e.Debug = false
|
|
|
|
e.HidePort = true
|
|
|
|
e.HideBanner = true
|
|
|
|
|
2019-12-21 10:26:14 +00:00
|
|
|
e.GET("/:cid/:oid", r.receiveFile)
|
|
|
|
|
|
|
|
// enable metrics
|
|
|
|
if v.GetBool("metrics") {
|
|
|
|
l.Info("enabled /metrics")
|
|
|
|
e.GET("/metrics", echo.WrapHandler(promhttp.Handler()))
|
|
|
|
}
|
|
|
|
|
|
|
|
// enable pprof
|
|
|
|
if v.GetBool("pprof") {
|
|
|
|
l.Info("enabled /debug/pprof")
|
|
|
|
e.Any("/debug/pprof*", echo.WrapHandler(http.DefaultServeMux))
|
|
|
|
}
|
2019-12-13 16:02:48 +00:00
|
|
|
|
2019-11-06 12:33:46 +00:00
|
|
|
go func() {
|
2019-12-21 10:26:14 +00:00
|
|
|
l.Info("run gateway server",
|
2019-11-06 12:33:46 +00:00
|
|
|
zap.String("address", v.GetString("listen_address")))
|
2019-12-13 16:02:48 +00:00
|
|
|
|
2020-02-14 10:07:52 +00:00
|
|
|
if err := e.Start(v.GetString("listen_address")); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
2019-12-21 10:26:14 +00:00
|
|
|
l.Panic("could not start server", zap.Error(err))
|
2019-11-06 12:33:46 +00:00
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
2019-12-21 10:26:14 +00:00
|
|
|
<-g.Done()
|
2019-11-06 12:33:46 +00:00
|
|
|
|
2019-12-21 10:26:14 +00:00
|
|
|
ctx, cancel := context.WithTimeout(context.TODO(), time.Second*30)
|
2019-11-06 12:33:46 +00:00
|
|
|
defer cancel()
|
|
|
|
|
2019-12-21 10:26:14 +00:00
|
|
|
l.Info("stopping server", zap.Error(e.Shutdown(ctx)))
|
2019-11-06 12:33:46 +00:00
|
|
|
}
|
|
|
|
|
2019-12-21 10:26:14 +00:00
|
|
|
func checkConnection(ctx context.Context, p *Pool) {
|
2020-02-14 11:35:35 +00:00
|
|
|
dur := time.Second * 15
|
|
|
|
tick := time.NewTimer(dur)
|
2019-12-21 10:26:14 +00:00
|
|
|
|
2019-11-06 12:33:46 +00:00
|
|
|
loop:
|
|
|
|
for {
|
|
|
|
select {
|
|
|
|
case <-ctx.Done():
|
|
|
|
break loop
|
|
|
|
case <-tick.C:
|
2019-12-21 10:26:14 +00:00
|
|
|
p.reBalance(ctx)
|
2020-02-14 11:35:35 +00:00
|
|
|
tick.Reset(dur)
|
2019-11-06 12:33:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tick.Stop()
|
2019-12-21 10:26:14 +00:00
|
|
|
|
|
|
|
p.log.Info("stop connection worker")
|
2019-11-06 12:33:46 +00:00
|
|
|
}
|