github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/pkg/rpc/connection.go (about)

     1  package rpc
     2  
     3  import (
     4  	"sort"
     5  	"strings"
     6  
     7  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base"
     8  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/cache"
     9  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger"
    10  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/walk"
    11  )
    12  
    13  // Connection carries additional context to rpc calls
    14  type Connection struct {
    15  	Chain                string
    16  	Store                *cache.Store // Cache Store to use for read/write. Write can be disabled by setting Store to read-only mode
    17  	LatestBlockTimestamp base.Timestamp
    18  	EnabledMap           map[walk.CacheType]bool
    19  }
    20  
    21  // settings allows every command has its own options type, we have to
    22  // accept any here, but will use interfaces to read the needed information
    23  type settings struct {
    24  	Chain         string
    25  	ReadonlyCache bool
    26  	CacheEnabled  bool
    27  	EnabledMap    map[walk.CacheType]bool
    28  }
    29  
    30  func NewConnection(chain string, cacheEnabled bool, caches map[walk.CacheType]bool) *Connection {
    31  	settings := settings{
    32  		Chain:        chain,
    33  		CacheEnabled: cacheEnabled,
    34  		EnabledMap:   caches,
    35  	}
    36  	return settings.GetRpcConnection()
    37  }
    38  
    39  func TempConnection(chain string) *Connection {
    40  	settings := settings{
    41  		Chain: chain,
    42  	}
    43  	return settings.GetRpcConnection()
    44  }
    45  
    46  func NewReadOnlyConnection(chain string) *Connection {
    47  	settings := settings{
    48  		Chain:         chain,
    49  		ReadonlyCache: true,
    50  	}
    51  	return settings.GetRpcConnection()
    52  }
    53  
    54  // GetRpcConnection builds the store and enables the caches and returns the RPC connection
    55  func (settings settings) GetRpcConnection() *Connection {
    56  	forceReadonly := !settings.CacheEnabled || settings.ReadonlyCache
    57  
    58  	var store *cache.Store
    59  	var err error
    60  	if store, err = cache.NewStore(&cache.StoreOptions{
    61  		Location: cache.FsCache,
    62  		Chain:    settings.Chain,
    63  		ReadOnly: forceReadonly,
    64  	}); err != nil {
    65  		// If there was an error, we won't use the cache
    66  		logger.Warn("Cannot initialize cache:", err)
    67  	}
    68  
    69  	ret := &Connection{
    70  		Chain:      settings.Chain,
    71  		Store:      store,
    72  		EnabledMap: settings.EnabledMap,
    73  	}
    74  
    75  	if store != nil && !store.ReadOnly() {
    76  		ret.LatestBlockTimestamp = ret.GetBlockTimestamp(base.NOPOSN)
    77  	}
    78  
    79  	return ret
    80  }
    81  
    82  // StoreReadable is a shorthand to check if Store is initialized. It will return
    83  // false for nil pointer to Connection
    84  func (conn *Connection) StoreReadable() bool {
    85  	if conn == nil {
    86  		logger.Fatal("should not happen ==> implementation error in StoreReadable.")
    87  	}
    88  
    89  	return conn.Store != nil
    90  }
    91  
    92  func (conn *Connection) StoreWritable() bool {
    93  	if !conn.StoreReadable() {
    94  		return false
    95  	}
    96  	return !conn.Store.ReadOnly()
    97  }
    98  
    99  // TestLog prints the enabledMap to the log. Note this routine gets called prior to full initialization, thus it takes the enabledMap
   100  func (conn *Connection) TestLog(caches map[walk.CacheType]bool) {
   101  	if conn.StoreWritable() {
   102  		enabled := []string{}
   103  		for k, v := range caches {
   104  			if v {
   105  				enabled = append(enabled, k.String())
   106  			}
   107  		}
   108  		sort.Strings(enabled)
   109  		logger.TestLog(len(enabled) > 0, "Enabled: ", strings.Join(enabled, ", "))
   110  	}
   111  	// logger.TestLog(options.LatestBlockTimestamp != 0, "LatestBlockTimestamp: ", options.LatestBlockTimestamp)
   112  }