mirror of
https://github.com/tendermint/tendermint.git
synced 2026-08-18 21:26:20 +00:00
abci/client: remove client-level callback (#7845)
* abci/client: remove client-level callback * ditch multi conn con * fix lint * fix teset
This commit is contained in:
@@ -16,7 +16,6 @@ import (
|
||||
// Enforce which abci msgs can be sent on a connection at the type level
|
||||
|
||||
type AppConnConsensus interface {
|
||||
SetResponseCallback(abciclient.Callback)
|
||||
Error() error
|
||||
|
||||
InitChain(context.Context, types.RequestInitChain) (*types.ResponseInitChain, error)
|
||||
@@ -30,7 +29,6 @@ type AppConnConsensus interface {
|
||||
}
|
||||
|
||||
type AppConnMempool interface {
|
||||
SetResponseCallback(abciclient.Callback)
|
||||
Error() error
|
||||
|
||||
CheckTxAsync(context.Context, types.RequestCheckTx) (*abciclient.ReqRes, error)
|
||||
@@ -74,10 +72,6 @@ func NewAppConnConsensus(appConn abciclient.Client, metrics *Metrics) AppConnCon
|
||||
}
|
||||
}
|
||||
|
||||
func (app *appConnConsensus) SetResponseCallback(cb abciclient.Callback) {
|
||||
app.appConn.SetResponseCallback(cb)
|
||||
}
|
||||
|
||||
func (app *appConnConsensus) Error() error {
|
||||
return app.appConn.Error()
|
||||
}
|
||||
@@ -150,10 +144,6 @@ func NewAppConnMempool(appConn abciclient.Client, metrics *Metrics) AppConnMempo
|
||||
}
|
||||
}
|
||||
|
||||
func (app *appConnMempool) SetResponseCallback(cb abciclient.Callback) {
|
||||
app.appConn.SetResponseCallback(cb)
|
||||
}
|
||||
|
||||
func (app *appConnMempool) Error() error {
|
||||
return app.appConn.Error()
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ package mocks
|
||||
import (
|
||||
context "context"
|
||||
|
||||
abciclient "github.com/tendermint/tendermint/abci/client"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
types "github.com/tendermint/tendermint/abci/types"
|
||||
@@ -169,11 +167,6 @@ func (_m *AppConnConsensus) ProcessProposal(_a0 context.Context, _a1 types.Reque
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SetResponseCallback provides a mock function with given fields: _a0
|
||||
func (_m *AppConnConsensus) SetResponseCallback(_a0 abciclient.Callback) {
|
||||
_m.Called(_a0)
|
||||
}
|
||||
|
||||
// VerifyVoteExtension provides a mock function with given fields: _a0, _a1
|
||||
func (_m *AppConnConsensus) VerifyVoteExtension(_a0 context.Context, _a1 types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) {
|
||||
ret := _m.Called(_a0, _a1)
|
||||
|
||||
@@ -113,8 +113,3 @@ func (_m *AppConnMempool) FlushAsync(_a0 context.Context) (*abciclient.ReqRes, e
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// SetResponseCallback provides a mock function with given fields: _a0
|
||||
func (_m *AppConnMempool) SetResponseCallback(_a0 abciclient.Callback) {
|
||||
_m.Called(_a0)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package proxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
@@ -11,13 +10,6 @@ import (
|
||||
"github.com/tendermint/tendermint/libs/service"
|
||||
)
|
||||
|
||||
const (
|
||||
connConsensus = "consensus"
|
||||
connMempool = "mempool"
|
||||
connQuery = "query"
|
||||
connSnapshot = "snapshot"
|
||||
)
|
||||
|
||||
// AppConns is the Tendermint's interface to the application that consists of
|
||||
// multiple connections.
|
||||
type AppConns interface {
|
||||
@@ -53,10 +45,7 @@ type multiAppConn struct {
|
||||
queryConn AppConnQuery
|
||||
snapshotConn AppConnSnapshot
|
||||
|
||||
consensusConnClient stoppableClient
|
||||
mempoolConnClient stoppableClient
|
||||
queryConnClient stoppableClient
|
||||
snapshotConnClient stoppableClient
|
||||
client stoppableClient
|
||||
|
||||
clientCreator abciclient.Creator
|
||||
}
|
||||
@@ -89,122 +78,48 @@ func (app *multiAppConn) OnStart(ctx context.Context) error {
|
||||
var err error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
app.stopAllClients()
|
||||
app.client.Stop()
|
||||
}
|
||||
}()
|
||||
|
||||
app.queryConnClient, err = app.abciClientFor(ctx, connQuery)
|
||||
var client abciclient.Client
|
||||
client, err = app.clientCreator(app.logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
app.queryConn = NewAppConnQuery(app.queryConnClient, app.metrics)
|
||||
|
||||
app.snapshotConnClient, err = app.abciClientFor(ctx, connSnapshot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
app.snapshotConn = NewAppConnSnapshot(app.snapshotConnClient, app.metrics)
|
||||
app.queryConn = NewAppConnQuery(client, app.metrics)
|
||||
app.snapshotConn = NewAppConnSnapshot(client, app.metrics)
|
||||
app.mempoolConn = NewAppConnMempool(client, app.metrics)
|
||||
app.consensusConn = NewAppConnConsensus(client, app.metrics)
|
||||
|
||||
app.mempoolConnClient, err = app.abciClientFor(ctx, connMempool)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
app.mempoolConn = NewAppConnMempool(app.mempoolConnClient, app.metrics)
|
||||
|
||||
app.consensusConnClient, err = app.abciClientFor(ctx, connConsensus)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
app.consensusConn = NewAppConnConsensus(app.consensusConnClient, app.metrics)
|
||||
app.client = client.(stoppableClient)
|
||||
|
||||
// Kill Tendermint if the ABCI application crashes.
|
||||
app.startWatchersForClientErrorToKillTendermint(ctx)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *multiAppConn) OnStop() { app.stopAllClients() }
|
||||
|
||||
func (app *multiAppConn) startWatchersForClientErrorToKillTendermint(ctx context.Context) {
|
||||
// this function starts a number of threads (per abci client)
|
||||
// that will SIGTERM's our own PID if any of the ABCI clients
|
||||
// exit/return early. If the context is canceled then these
|
||||
// functions will not kill tendermint.
|
||||
|
||||
killFn := func(conn string, err error, logger log.Logger) {
|
||||
logger.Error(
|
||||
fmt.Sprintf("%s connection terminated. Did the application crash? Please restart tendermint", conn),
|
||||
"err", err)
|
||||
if killErr := kill(); killErr != nil {
|
||||
logger.Error("Failed to kill this process - please do so manually", "err", killErr)
|
||||
go func() {
|
||||
if !client.IsRunning() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for _, client := range []struct {
|
||||
connClient stoppableClient
|
||||
name string
|
||||
}{
|
||||
{
|
||||
connClient: app.consensusConnClient,
|
||||
name: connConsensus,
|
||||
},
|
||||
{
|
||||
connClient: app.mempoolConnClient,
|
||||
name: connMempool,
|
||||
},
|
||||
{
|
||||
connClient: app.queryConnClient,
|
||||
name: connQuery,
|
||||
},
|
||||
{
|
||||
connClient: app.snapshotConnClient,
|
||||
name: connSnapshot,
|
||||
},
|
||||
} {
|
||||
go func(name string, client stoppableClient) {
|
||||
client.Wait()
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
if err := client.Error(); err != nil {
|
||||
killFn(name, err, app.logger)
|
||||
}
|
||||
}(client.name, client.connClient)
|
||||
}
|
||||
}
|
||||
|
||||
func (app *multiAppConn) stopAllClients() {
|
||||
for _, client := range []stoppableClient{
|
||||
app.consensusConnClient,
|
||||
app.mempoolConnClient,
|
||||
app.queryConnClient,
|
||||
app.snapshotConnClient,
|
||||
} {
|
||||
if client != nil {
|
||||
client.Stop()
|
||||
app.client.Wait()
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := app.client.Error(); err != nil {
|
||||
app.logger.Error("client connection terminated. Did the application crash? Please restart tendermint",
|
||||
"err", err)
|
||||
if killErr := kill(); killErr != nil {
|
||||
app.logger.Error("Failed to kill this process - please do so manually",
|
||||
"err", killErr)
|
||||
}
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
return client.Start(ctx)
|
||||
}
|
||||
|
||||
func (app *multiAppConn) abciClientFor(ctx context.Context, conn string) (stoppableClient, error) {
|
||||
c, err := app.clientCreator(app.logger.With(
|
||||
"module", "abci-client",
|
||||
"connection", conn))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating ABCI client (%s connection): %w", conn, err)
|
||||
}
|
||||
|
||||
if err := c.Start(ctx); err != nil {
|
||||
return nil, fmt.Errorf("error starting ABCI client (%s connection): %w", conn, err)
|
||||
}
|
||||
|
||||
client, ok := c.(stoppableClient)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%T is not a stoppable client", c)
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
func (app *multiAppConn) OnStop() { app.client.Stop() }
|
||||
|
||||
func kill() error {
|
||||
p, err := os.FindProcess(os.Getpid())
|
||||
|
||||
@@ -30,9 +30,10 @@ func TestAppConns_Start_Stop(t *testing.T) {
|
||||
defer cancel()
|
||||
|
||||
clientMock := &abcimocks.Client{}
|
||||
clientMock.On("Start", mock.Anything).Return(nil).Times(4)
|
||||
clientMock.On("Start", mock.Anything).Return(nil)
|
||||
clientMock.On("Error").Return(nil)
|
||||
clientMock.On("Wait").Return(nil).Times(4)
|
||||
clientMock.On("IsRunning").Return(true)
|
||||
clientMock.On("Wait").Return(nil).Times(1)
|
||||
cl := &noopStoppableClientImpl{Client: clientMock}
|
||||
|
||||
creatorCallCount := 0
|
||||
@@ -46,14 +47,14 @@ func TestAppConns_Start_Stop(t *testing.T) {
|
||||
err := appConns.Start(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
|
||||
cancel()
|
||||
appConns.Wait()
|
||||
|
||||
clientMock.AssertExpectations(t)
|
||||
assert.Equal(t, 4, cl.count)
|
||||
assert.Equal(t, 4, creatorCallCount)
|
||||
assert.Equal(t, 1, cl.count)
|
||||
assert.Equal(t, 1, creatorCallCount)
|
||||
}
|
||||
|
||||
// Upon failure, we call tmos.Kill
|
||||
@@ -74,7 +75,7 @@ func TestAppConns_Failure(t *testing.T) {
|
||||
clientMock := &abcimocks.Client{}
|
||||
clientMock.On("SetLogger", mock.Anything).Return()
|
||||
clientMock.On("Start", mock.Anything).Return(nil)
|
||||
|
||||
clientMock.On("IsRunning").Return(true)
|
||||
clientMock.On("Wait").Return(nil)
|
||||
clientMock.On("Error").Return(errors.New("EOF"))
|
||||
cl := &noopStoppableClientImpl{Client: clientMock}
|
||||
|
||||
Reference in New Issue
Block a user