github.com/vipernet-xyz/tm@v0.34.24/proxy/client.go (about)

     1  package proxy
     2  
     3  import (
     4  	"fmt"
     5  
     6  	abcicli "github.com/vipernet-xyz/tm/abci/client"
     7  	"github.com/vipernet-xyz/tm/abci/example/counter"
     8  	"github.com/vipernet-xyz/tm/abci/example/kvstore"
     9  	"github.com/vipernet-xyz/tm/abci/types"
    10  	tmsync "github.com/vipernet-xyz/tm/libs/sync"
    11  	e2e "github.com/vipernet-xyz/tm/test/e2e/app"
    12  )
    13  
    14  //go:generate ../scripts/mockery_generate.sh ClientCreator
    15  
    16  // ClientCreator creates new ABCI clients.
    17  type ClientCreator interface {
    18  	// NewABCIClient returns a new ABCI client.
    19  	NewABCIClient() (abcicli.Client, error)
    20  }
    21  
    22  //----------------------------------------------------
    23  // local proxy uses a mutex on an in-proc app
    24  
    25  type localClientCreator struct {
    26  	mtx *tmsync.Mutex
    27  	app types.Application
    28  }
    29  
    30  // NewLocalClientCreator returns a ClientCreator for the given app,
    31  // which will be running locally.
    32  func NewLocalClientCreator(app types.Application) ClientCreator {
    33  	return &localClientCreator{
    34  		mtx: new(tmsync.Mutex),
    35  		app: app,
    36  	}
    37  }
    38  
    39  func (l *localClientCreator) NewABCIClient() (abcicli.Client, error) {
    40  	return abcicli.NewLocalClient(l.mtx, l.app), nil
    41  }
    42  
    43  //---------------------------------------------------------------
    44  // remote proxy opens new connections to an external app process
    45  
    46  type remoteClientCreator struct {
    47  	addr        string
    48  	transport   string
    49  	mustConnect bool
    50  }
    51  
    52  // NewRemoteClientCreator returns a ClientCreator for the given address (e.g.
    53  // "192.168.0.1") and transport (e.g. "tcp"). Set mustConnect to true if you
    54  // want the client to connect before reporting success.
    55  func NewRemoteClientCreator(addr, transport string, mustConnect bool) ClientCreator {
    56  	return &remoteClientCreator{
    57  		addr:        addr,
    58  		transport:   transport,
    59  		mustConnect: mustConnect,
    60  	}
    61  }
    62  
    63  func (r *remoteClientCreator) NewABCIClient() (abcicli.Client, error) {
    64  	remoteApp, err := abcicli.NewClient(r.addr, r.transport, r.mustConnect)
    65  	if err != nil {
    66  		return nil, fmt.Errorf("failed to connect to proxy: %w", err)
    67  	}
    68  
    69  	return remoteApp, nil
    70  }
    71  
    72  // DefaultClientCreator returns a default ClientCreator, which will create a
    73  // local client if addr is one of: 'counter', 'counter_serial', 'kvstore',
    74  // 'persistent_kvstore' or 'noop', otherwise - a remote client.
    75  func DefaultClientCreator(addr, transport, dbDir string) ClientCreator {
    76  	switch addr {
    77  	case "counter":
    78  		return NewLocalClientCreator(counter.NewApplication(false))
    79  	case "counter_serial":
    80  		return NewLocalClientCreator(counter.NewApplication(true))
    81  	case "kvstore":
    82  		return NewLocalClientCreator(kvstore.NewApplication())
    83  	case "persistent_kvstore":
    84  		return NewLocalClientCreator(kvstore.NewPersistentKVStoreApplication(dbDir))
    85  	case "e2e":
    86  		app, err := e2e.NewApplication(e2e.DefaultConfig(dbDir))
    87  		if err != nil {
    88  			panic(err)
    89  		}
    90  		return NewLocalClientCreator(app)
    91  	case "noop":
    92  		return NewLocalClientCreator(types.NewBaseApplication())
    93  	default:
    94  		mustConnect := false // loop retrying
    95  		return NewRemoteClientCreator(addr, transport, mustConnect)
    96  	}
    97  }