Browse Source

service: remove quit method (#7293)

pull/7296/head
Sam Kleinman 3 years ago
committed by GitHub
parent
commit
7e58f02eb8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 34 deletions
  1. +39
    -19
      internal/proxy/multi_app_conn.go
  2. +5
    -12
      internal/proxy/multi_app_conn_test.go
  3. +0
    -3
      libs/service/service.go

+ 39
- 19
internal/proxy/multi_app_conn.go View File

@ -128,7 +128,7 @@ func (app *multiAppConn) OnStart(ctx context.Context) error {
app.consensusConn = NewAppConnConsensus(c, app.metrics) app.consensusConn = NewAppConnConsensus(c, app.metrics)
// Kill Tendermint if the ABCI application crashes. // Kill Tendermint if the ABCI application crashes.
go app.killTMOnClientError()
app.startWatchersForClientErrorToKillTendermint(ctx)
return nil return nil
} }
@ -137,7 +137,12 @@ func (app *multiAppConn) OnStop() {
app.stopAllClients() app.stopAllClients()
} }
func (app *multiAppConn) killTMOnClientError() {
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) { killFn := func(conn string, err error, logger log.Logger) {
logger.Error( logger.Error(
fmt.Sprintf("%s connection terminated. Did the application crash? Please restart tendermint", conn), fmt.Sprintf("%s connection terminated. Did the application crash? Please restart tendermint", conn),
@ -147,23 +152,38 @@ func (app *multiAppConn) killTMOnClientError() {
} }
} }
select {
case <-app.consensusConnClient.Quit():
if err := app.consensusConnClient.Error(); err != nil {
killFn(connConsensus, err, app.Logger)
}
case <-app.mempoolConnClient.Quit():
if err := app.mempoolConnClient.Error(); err != nil {
killFn(connMempool, err, app.Logger)
}
case <-app.queryConnClient.Quit():
if err := app.queryConnClient.Error(); err != nil {
killFn(connQuery, err, app.Logger)
}
case <-app.snapshotConnClient.Quit():
if err := app.snapshotConnClient.Error(); err != nil {
killFn(connSnapshot, err, app.Logger)
}
type op struct {
connClient stoppableClient
name string
}
for _, client := range []op{
{
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)
} }
} }


+ 5
- 12
internal/proxy/multi_app_conn_test.go View File

@ -26,14 +26,13 @@ type noopStoppableClientImpl struct {
func (c *noopStoppableClientImpl) Stop() error { c.count++; return nil } func (c *noopStoppableClientImpl) Stop() error { c.count++; return nil }
func TestAppConns_Start_Stop(t *testing.T) { func TestAppConns_Start_Stop(t *testing.T) {
quitCh := make(<-chan struct{})
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
clientMock := &abcimocks.Client{} clientMock := &abcimocks.Client{}
clientMock.On("Start", mock.Anything).Return(nil).Times(4) clientMock.On("Start", mock.Anything).Return(nil).Times(4)
clientMock.On("Quit").Return(quitCh).Times(4)
clientMock.On("Error").Return(nil)
clientMock.On("Wait").Return(nil).Times(4)
cl := &noopStoppableClientImpl{Client: clientMock} cl := &noopStoppableClientImpl{Client: clientMock}
creatorCallCount := 0 creatorCallCount := 0
@ -65,22 +64,19 @@ func TestAppConns_Failure(t *testing.T) {
go func() { go func() {
for range c { for range c {
close(ok) close(ok)
return
} }
}() }()
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
quitCh := make(chan struct{})
var recvQuitCh <-chan struct{} // nolint:gosimple
recvQuitCh = quitCh
clientMock := &abcimocks.Client{} clientMock := &abcimocks.Client{}
clientMock.On("SetLogger", mock.Anything).Return() clientMock.On("SetLogger", mock.Anything).Return()
clientMock.On("Start", mock.Anything).Return(nil) clientMock.On("Start", mock.Anything).Return(nil)
clientMock.On("Quit").Return(recvQuitCh)
clientMock.On("Error").Return(errors.New("EOF")).Once()
clientMock.On("Wait").Return(nil)
clientMock.On("Error").Return(errors.New("EOF"))
cl := &noopStoppableClientImpl{Client: clientMock} cl := &noopStoppableClientImpl{Client: clientMock}
creator := func(log.Logger) (abciclient.Client, error) { creator := func(log.Logger) (abciclient.Client, error) {
@ -93,9 +89,6 @@ func TestAppConns_Failure(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() { cancel(); appConns.Wait() }) t.Cleanup(func() { cancel(); appConns.Wait() })
// simulate failure
close(quitCh)
select { select {
case <-ok: case <-ok:
t.Log("SIGTERM successfully received") t.Log("SIGTERM successfully received")


+ 0
- 3
libs/service/service.go View File

@ -30,9 +30,6 @@ type Service interface {
// Return true if the service is running // Return true if the service is running
IsRunning() bool IsRunning() bool
// Quit returns a channel, which is closed once service is stopped.
Quit() <-chan struct{}
// String representation of the service // String representation of the service
String() string String() string


Loading…
Cancel
Save