refactoring pool, replace zap.Duration with zap.Stringer

This commit is contained in:
Evgeniy Kulikov 2020-02-25 18:35:46 +03:00
parent cf61136da5
commit 62c6bbd875
No known key found for this signature in database
GPG key ID: BF6AEE0A2A699BF2
3 changed files with 47 additions and 16 deletions

16
main.go
View file

@ -23,6 +23,9 @@ type router struct {
func main() { func main() {
var ( var (
err error
pool *Pool
v = settings() v = settings()
l = newLogger(v) l = newLogger(v)
g = newGracefulContext(l) g = newGracefulContext(l)
@ -32,10 +35,21 @@ func main() {
grpclog.SetLoggerV2(gRPCLogger(l)) grpclog.SetLoggerV2(gRPCLogger(l))
} }
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
}
r := &router{ r := &router{
log: l, log: l,
pool: pool,
key: fetchKey(l, v), key: fetchKey(l, v),
pool: newPool(g, l, v),
timeout: v.GetDuration("request_timeout"), timeout: v.GetDuration("request_timeout"),
} }

26
pool.go
View file

@ -54,7 +54,7 @@ var (
errNoHealthyConnections = errors.New("no active connections") errNoHealthyConnections = errors.New("no active connections")
) )
func newPool(ctx context.Context, l *zap.Logger, v *viper.Viper) *Pool { func newPool(ctx context.Context, l *zap.Logger, v *viper.Viper) (*Pool, error) {
p := &Pool{ p := &Pool{
log: l, log: l,
Mutex: new(sync.Mutex), Mutex: new(sync.Mutex),
@ -128,11 +128,9 @@ func newPool(ctx context.Context, l *zap.Logger, v *viper.Viper) *Pool {
p.reBalance(ctx) p.reBalance(ctx)
if _, err := p.getConnection(ctx); err != nil { _, err := p.getConnection(ctx)
l.Panic("could get connection", zap.Error(err))
}
return p return p, err
} }
func (p *Pool) close() { func (p *Pool) close() {
@ -168,6 +166,12 @@ func (p *Pool) reBalance(ctx context.Context) {
weight = p.nodes[i].weight weight = p.nodes[i].weight
) )
if ctx.Err() != nil {
p.log.Warn("something went wrong", zap.Error(ctx.Err()))
return
}
if conn == nil { if conn == nil {
p.log.Warn("empty connection, try to connect", p.log.Warn("empty connection, try to connect",
zap.String("address", p.nodes[i].address)) zap.String("address", p.nodes[i].address))
@ -182,7 +186,7 @@ func (p *Pool) reBalance(ctx context.Context) {
if err != nil || conn == nil { if err != nil || conn == nil {
p.log.Warn("skip, could not connect to node", p.log.Warn("skip, could not connect to node",
zap.String("address", p.nodes[i].address), zap.String("address", p.nodes[i].address),
zap.Duration("elapsed", time.Since(start)), zap.Stringer("elapsed", time.Since(start)),
zap.Error(err)) zap.Error(err))
continue continue
} }
@ -206,7 +210,7 @@ func (p *Pool) reBalance(ctx context.Context) {
if err = p.isAlive(ctx, conn); err != nil || usedAt > p.ttl { if err = p.isAlive(ctx, conn); err != nil || usedAt > p.ttl {
p.log.Warn("connection not alive", p.log.Warn("connection not alive",
zap.String("address", p.nodes[i].address), zap.String("address", p.nodes[i].address),
zap.Duration("used_at", usedAt), zap.Stringer("used_at", usedAt),
zap.Error(err)) zap.Error(err))
if exists { if exists {
@ -217,7 +221,7 @@ func (p *Pool) reBalance(ctx context.Context) {
if err = conn.Close(); err != nil { if err = conn.Close(); err != nil {
p.log.Warn("could not close bad connection", p.log.Warn("could not close bad connection",
zap.String("address", p.nodes[i].address), zap.String("address", p.nodes[i].address),
zap.Duration("used_at", usedAt), zap.Stringer("used_at", usedAt),
zap.Error(err)) zap.Error(err))
} }
@ -231,7 +235,7 @@ func (p *Pool) reBalance(ctx context.Context) {
p.log.Info("connection alive", p.log.Info("connection alive",
zap.String("address", p.nodes[i].address), zap.String("address", p.nodes[i].address),
zap.Duration("used_at", usedAt)) zap.Stringer("used_at", usedAt))
if !exists { if !exists {
p.conns[weight] = append(p.conns[weight], p.nodes[i]) p.conns[weight] = append(p.conns[weight], p.nodes[i])
@ -281,6 +285,10 @@ func (p *Pool) getConnection(ctx context.Context) (*grpc.ClientConn, error) {
p.currentConn = nil p.currentConn = nil
p.currentIdx.Store(-1) p.currentIdx.Store(-1)
if ctx.Err() != nil {
return nil, ctx.Err()
}
return nil, errNoHealthyConnections return nil, errNoHealthyConnections
} }

View file

@ -28,6 +28,7 @@ func (r *router) receiveFile(c echo.Context) error {
start = time.Now() start = time.Now()
con *grpc.ClientConn con *grpc.ClientConn
ctx = c.Request().Context() ctx = c.Request().Context()
cli object.Service_GetClient
download = c.QueryParam("download") != "" download = c.QueryParam("download") != ""
) )
@ -36,14 +37,14 @@ func (r *router) receiveFile(c echo.Context) error {
zap.String("cid", c.Param("cid")), zap.String("cid", c.Param("cid")),
zap.String("oid", c.Param("oid"))) zap.String("oid", c.Param("oid")))
if err := cid.Parse(c.Param("cid")); err != nil { if err = cid.Parse(c.Param("cid")); err != nil {
log.Error("wrong container id", zap.Error(err)) log.Error("wrong container id", zap.Error(err))
return echo.NewHTTPError( return echo.NewHTTPError(
http.StatusBadRequest, http.StatusBadRequest,
errors.Wrap(err, "wrong container id").Error(), errors.Wrap(err, "wrong container id").Error(),
) )
} else if err := oid.Parse(c.Param("oid")); err != nil { } else if err = oid.Parse(c.Param("oid")); err != nil {
log.Error("wrong object id", zap.Error(err)) log.Error("wrong object id", zap.Error(err))
return echo.NewHTTPError( return echo.NewHTTPError(
@ -57,6 +58,7 @@ func (r *router) receiveFile(c echo.Context) error {
defer cancel() defer cancel()
if con, err = r.pool.getConnection(ctx); err != nil { if con, err = r.pool.getConnection(ctx); err != nil {
log.Error("getConnection timeout", zap.Error(err))
return echo.NewHTTPError(http.StatusBadRequest, err.Error()) return echo.NewHTTPError(http.StatusBadRequest, err.Error())
} }
} }
@ -66,18 +68,25 @@ func (r *router) receiveFile(c echo.Context) error {
log = log.With(zap.String("node", con.Target())) log = log.With(zap.String("node", con.Target()))
defer func() {
if err != nil {
return
}
log.Error("object sent to client", zap.Stringer("elapsed", time.Since(start)))
}()
req := &object.GetRequest{Address: refs.Address{ObjectID: oid, CID: cid}} req := &object.GetRequest{Address: refs.Address{ObjectID: oid, CID: cid}}
req.SetTTL(service.SingleForwardingTTL) req.SetTTL(service.SingleForwardingTTL)
if err := service.SignRequestHeader(r.key, req); err != nil { if err = service.SignRequestHeader(r.key, req); err != nil {
log.Error("could not sign request", zap.Error(err)) log.Error("could not sign request", zap.Error(err))
return echo.NewHTTPError( return echo.NewHTTPError(
http.StatusBadRequest, http.StatusBadRequest,
errors.Wrap(err, "could not sign request").Error()) errors.Wrap(err, "could not sign request").Error())
} }
cli, err := object.NewServiceClient(con).Get(ctx, req) if cli, err = object.NewServiceClient(con).Get(ctx, req); err != nil {
if err != nil {
log.Error("could not prepare connection", zap.Error(err)) log.Error("could not prepare connection", zap.Error(err))
return echo.NewHTTPError( return echo.NewHTTPError(
@ -86,7 +95,7 @@ func (r *router) receiveFile(c echo.Context) error {
) )
} else if obj, err = receiveObject(cli); err != nil { } else if obj, err = receiveObject(cli); err != nil {
log.Error("could not receive object", log.Error("could not receive object",
zap.Duration("elapsed", time.Since(start)), zap.Stringer("elapsed", time.Since(start)),
zap.Error(err)) zap.Error(err))
switch { switch {