- package proxy
-
- import (
- "fmt"
- "io"
-
- abcicli "github.com/tendermint/tendermint/abci/client"
- "github.com/tendermint/tendermint/abci/example/kvstore"
- "github.com/tendermint/tendermint/abci/types"
- tmsync "github.com/tendermint/tendermint/internal/libs/sync"
- )
-
- // 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 *tmsync.RWMutex
- 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(tmsync.RWMutex),
- 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: 'kvstore',
- // 'persistent_kvstore' or 'noop', otherwise - a remote client.
- //
- // The Closer is a noop except for persistent_kvstore applications,
- // which will clean up the store.
- func DefaultClientCreator(addr, transport, dbDir string) (ClientCreator, io.Closer) {
- switch addr {
- case "kvstore":
- return NewLocalClientCreator(kvstore.NewApplication()), noopCloser{}
- case "persistent_kvstore":
- app := kvstore.NewPersistentKVStoreApplication(dbDir)
- return NewLocalClientCreator(app), app
- case "noop":
- return NewLocalClientCreator(types.NewBaseApplication()), noopCloser{}
- default:
- mustConnect := false // loop retrying
- return NewRemoteClientCreator(addr, transport, mustConnect), noopCloser{}
- }
- }
-
- type noopCloser struct{}
-
- func (noopCloser) Close() error { return nil }
|