mirror of
https://github.com/tendermint/tendermint.git
synced 2026-01-09 14:43:19 +00:00
Closes #5074 Old code does not work when --consensus.create_empty_blocks=false (because it only calls tmos.Kill when ApplyBlock fails). New code is listening ABCI clients for Quit and kills TM process if there were any errors.
88 lines
2.6 KiB
Go
88 lines
2.6 KiB
Go
package proxy
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
abcicli "github.com/tendermint/tendermint/abci/client"
|
|
"github.com/tendermint/tendermint/abci/example/counter"
|
|
"github.com/tendermint/tendermint/abci/example/kvstore"
|
|
"github.com/tendermint/tendermint/abci/types"
|
|
)
|
|
|
|
// ClientCreator creates new ABCI clients.
|
|
type ClientCreator interface {
|
|
// NewABCIClient returns a new ABCI client.
|
|
NewABCIClient() (abcicli.Client, error)
|
|
}
|
|
|
|
//----------------------------------------------------
|
|
// local proxy uses a mutex on an in-proc app
|
|
|
|
type localClientCreator struct {
|
|
mtx *sync.Mutex
|
|
app types.Application
|
|
}
|
|
|
|
// NewLocalClientCreator returns a ClientCreator for the given app,
|
|
// which will be running locally.
|
|
func NewLocalClientCreator(app types.Application) ClientCreator {
|
|
return &localClientCreator{
|
|
mtx: new(sync.Mutex),
|
|
app: app,
|
|
}
|
|
}
|
|
|
|
func (l *localClientCreator) NewABCIClient() (abcicli.Client, error) {
|
|
return abcicli.NewLocalClient(l.mtx, l.app), nil
|
|
}
|
|
|
|
//---------------------------------------------------------------
|
|
// remote proxy opens new connections to an external app process
|
|
|
|
type remoteClientCreator struct {
|
|
addr string
|
|
transport string
|
|
mustConnect bool
|
|
}
|
|
|
|
// NewRemoteClientCreator returns a ClientCreator for the given address (e.g.
|
|
// "192.168.0.1") and transport (e.g. "tcp"). Set mustConnect to true if you
|
|
// want the client to connect before reporting success.
|
|
func NewRemoteClientCreator(addr, transport string, mustConnect bool) ClientCreator {
|
|
return &remoteClientCreator{
|
|
addr: addr,
|
|
transport: transport,
|
|
mustConnect: mustConnect,
|
|
}
|
|
}
|
|
|
|
func (r *remoteClientCreator) NewABCIClient() (abcicli.Client, error) {
|
|
remoteApp, err := abcicli.NewClient(r.addr, r.transport, r.mustConnect)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to connect to proxy: %w", err)
|
|
}
|
|
return remoteApp, nil
|
|
}
|
|
|
|
// DefaultClientCreator returns a default ClientCreator, which will create a
|
|
// local client if addr is one of: 'counter', 'counter_serial', 'kvstore',
|
|
// 'persistent_kvstore' or 'noop', otherwise - a remote client.
|
|
func DefaultClientCreator(addr, transport, dbDir string) ClientCreator {
|
|
switch addr {
|
|
case "counter":
|
|
return NewLocalClientCreator(counter.NewApplication(false))
|
|
case "counter_serial":
|
|
return NewLocalClientCreator(counter.NewApplication(true))
|
|
case "kvstore":
|
|
return NewLocalClientCreator(kvstore.NewApplication())
|
|
case "persistent_kvstore":
|
|
return NewLocalClientCreator(kvstore.NewPersistentKVStoreApplication(dbDir))
|
|
case "noop":
|
|
return NewLocalClientCreator(types.NewBaseApplication())
|
|
default:
|
|
mustConnect := false // loop retrying
|
|
return NewRemoteClientCreator(addr, transport, mustConnect)
|
|
}
|
|
}
|