rpc/jsonrpc/server: ws server optimizations (#5312)

* docs: goleveldb is much more stable now

Refs https://github.com/syndtr/goleveldb/issues/226#issuecomment-682495490

* rpc/core/events: make sure WS client receives every event

previously, if the write buffer was full, the response would've been
lost without any trace (log msg, etc.)

* rpc/jsonrpc/server: set defaultWSWriteChanCapacity to 1

Refs #3905
Closes #3829

setting write buffer capacity to 1 makes transactions count per block
more stable and also reduces the pauses length by 20s.

before: https://github.com/tendermint/tendermint/issues/3905#issuecomment-681854328 net.Read - 20s
after: net.Read - 0.66s

* rpc/jsonrpc/server: buffer writes and avoid io.ReadAll during read
This commit is contained in:
Anton Kaliaev
2020-09-04 10:58:47 +04:00
committed by GitHub
parent 39d2ac4dbc
commit 59ec3d91e4
6 changed files with 133 additions and 75 deletions

View File

@@ -3,6 +3,7 @@ package core
import (
"context"
"fmt"
"time"
tmpubsub "github.com/tendermint/tendermint/libs/pubsub"
tmquery "github.com/tendermint/tendermint/libs/pubsub/query"
@@ -47,12 +48,16 @@ func Subscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultSubscribe, er
for {
select {
case msg := <-sub.Out():
resultEvent := &ctypes.ResultEvent{Query: query, Data: msg.Data(), Events: msg.Events()}
ctx.WSConn.TryWriteRPCResponse(
rpctypes.NewRPCSuccessResponse(
subscriptionID,
resultEvent,
))
var (
resultEvent = &ctypes.ResultEvent{Query: query, Data: msg.Data(), Events: msg.Events()}
resp = rpctypes.NewRPCSuccessResponse(subscriptionID, resultEvent)
)
writeCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := ctx.WSConn.WriteRPCResponse(writeCtx, resp); err != nil {
env.Logger.Info("Can't write response (slow client)",
"to", addr, "subscriptionID", subscriptionID, "err", err)
}
case <-sub.Cancelled():
if sub.Err() != tmpubsub.ErrUnsubscribed {
var reason string
@@ -61,11 +66,14 @@ func Subscribe(ctx *rpctypes.Context, query string) (*ctypes.ResultSubscribe, er
} else {
reason = sub.Err().Error()
}
ctx.WSConn.TryWriteRPCResponse(
rpctypes.RPCServerError(
subscriptionID,
fmt.Errorf("subscription was cancelled (reason: %s)", reason),
))
var (
err = fmt.Errorf("subscription was cancelled (reason: %s)", reason)
resp = rpctypes.RPCServerError(subscriptionID, err)
)
if ok := ctx.WSConn.TryWriteRPCResponse(resp); !ok {
env.Logger.Info("Can't write response (slow client)",
"to", addr, "subscriptionID", subscriptionID, "err", err)
}
}
return
}