mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-05-21 06:16:45 +00:00
101 lines
2.2 KiB
Go
101 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"github.com/kaspanet/kaspad/app/appmessage"
|
|
"github.com/kaspanet/kaspad/infrastructure/logger"
|
|
"github.com/kaspanet/kaspad/infrastructure/network/rpcclient"
|
|
"github.com/pkg/errors"
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
const minerTimeout = 10 * time.Second
|
|
|
|
type minerClient struct {
|
|
isReconnecting uint32
|
|
clientLock sync.RWMutex
|
|
rpcClient *rpcclient.RPCClient
|
|
|
|
cfg *configFlags
|
|
blockAddedNotificationChan chan struct{}
|
|
}
|
|
|
|
func (mc *minerClient) safeRPCClient() *rpcclient.RPCClient {
|
|
mc.clientLock.RLock()
|
|
defer mc.clientLock.RUnlock()
|
|
return mc.rpcClient
|
|
}
|
|
|
|
func (mc *minerClient) reconnect() {
|
|
swapped := atomic.CompareAndSwapUint32(&mc.isReconnecting, 0, 1)
|
|
if !swapped {
|
|
return
|
|
}
|
|
|
|
defer atomic.StoreUint32(&mc.isReconnecting, 0)
|
|
|
|
mc.clientLock.Lock()
|
|
defer mc.clientLock.Unlock()
|
|
|
|
retryDuration := time.Second
|
|
const maxRetryDuration = time.Minute
|
|
log.Infof("Reconnecting RPC connection")
|
|
for {
|
|
err := mc.connect()
|
|
if err == nil {
|
|
return
|
|
}
|
|
|
|
if retryDuration < time.Minute {
|
|
retryDuration *= 2
|
|
} else {
|
|
retryDuration = maxRetryDuration
|
|
}
|
|
|
|
log.Errorf("Got error '%s' while reconnecting. Trying again in %s", err, retryDuration)
|
|
time.Sleep(retryDuration)
|
|
}
|
|
}
|
|
|
|
func (mc *minerClient) connect() error {
|
|
rpcAddress, err := mc.cfg.NetParams().NormalizeRPCServerAddress(mc.cfg.RPCServer)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
mc.rpcClient, err = rpcclient.NewRPCClient(rpcAddress)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
mc.rpcClient.SetTimeout(minerTimeout)
|
|
mc.rpcClient.SetLogger(backendLog, logger.LevelTrace)
|
|
|
|
err = mc.rpcClient.RegisterForBlockAddedNotifications(func(_ *appmessage.BlockAddedNotificationMessage) {
|
|
select {
|
|
case mc.blockAddedNotificationChan <- struct{}{}:
|
|
default:
|
|
}
|
|
})
|
|
if err != nil {
|
|
return errors.Wrapf(err, "error requesting block-added notifications")
|
|
}
|
|
|
|
log.Infof("Connected to %s", rpcAddress)
|
|
|
|
return nil
|
|
}
|
|
|
|
func newMinerClient(cfg *configFlags) (*minerClient, error) {
|
|
minerClient := &minerClient{
|
|
cfg: cfg,
|
|
blockAddedNotificationChan: make(chan struct{}),
|
|
}
|
|
|
|
err := minerClient.connect()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return minerClient, nil
|
|
}
|