mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
Add in routine that checks internet connectivity for bot services (#287)
* Add in routine that checks internet connectivity for bot services * Packaged connection checker
This commit is contained in:
committed by
Adrian Gallagher
parent
2f1405ead4
commit
6e2cba566f
@@ -15,6 +15,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/connchecker"
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
"github.com/thrasher-/gocryptotrader/currency/forexprovider"
|
||||
@@ -104,18 +105,19 @@ type CurrencyPairFormatConfig struct {
|
||||
// prestart management of Portfolio, Communications, Webserver and Enabled
|
||||
// Exchanges
|
||||
type Config struct {
|
||||
Name string `json:"name"`
|
||||
EncryptConfig int `json:"encryptConfig"`
|
||||
GlobalHTTPTimeout time.Duration `json:"globalHTTPTimeout"`
|
||||
Logging log.Logging `json:"logging"`
|
||||
Profiler ProfilerConfig `json:"profiler"`
|
||||
NTPClient NTPClientConfig `json:"ntpclient"`
|
||||
Currency CurrencyConfig `json:"currencyConfig"`
|
||||
Communications CommunicationsConfig `json:"communications"`
|
||||
Portfolio portfolio.Base `json:"portfolioAddresses"`
|
||||
Webserver WebserverConfig `json:"webserver"`
|
||||
Exchanges []ExchangeConfig `json:"exchanges"`
|
||||
BankAccounts []BankAccount `json:"bankAccounts"`
|
||||
Name string `json:"name"`
|
||||
EncryptConfig int `json:"encryptConfig"`
|
||||
GlobalHTTPTimeout time.Duration `json:"globalHTTPTimeout"`
|
||||
Logging log.Logging `json:"logging"`
|
||||
Profiler ProfilerConfig `json:"profiler"`
|
||||
NTPClient NTPClientConfig `json:"ntpclient"`
|
||||
Currency CurrencyConfig `json:"currencyConfig"`
|
||||
Communications CommunicationsConfig `json:"communications"`
|
||||
Portfolio portfolio.Base `json:"portfolioAddresses"`
|
||||
Webserver WebserverConfig `json:"webserver"`
|
||||
Exchanges []ExchangeConfig `json:"exchanges"`
|
||||
BankAccounts []BankAccount `json:"bankAccounts"`
|
||||
ConnectionMonitor ConnectionMonitorConfig `json:"connectionMonitor"`
|
||||
|
||||
// Deprecated config settings, will be removed at a future date
|
||||
CurrencyPairFormat *CurrencyPairFormatConfig `json:"currencyPairFormat,omitempty"`
|
||||
@@ -124,6 +126,14 @@ type Config struct {
|
||||
SMS *SMSGlobalConfig `json:"smsGlobal,omitempty"`
|
||||
}
|
||||
|
||||
// ConnectionMonitorConfig defines the connection monitor variables to ensure
|
||||
// that there is internet connectivity
|
||||
type ConnectionMonitorConfig struct {
|
||||
DNSList []string `json:"preferredDNSList"`
|
||||
PublicDomainList []string `json:"preferredDomainList"`
|
||||
CheckInterval time.Duration `json:"checkInterval"`
|
||||
}
|
||||
|
||||
// ProfilerConfig defines the profiler configuration to enable pprof
|
||||
type ProfilerConfig struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
@@ -1158,6 +1168,24 @@ func (c *Config) DisableNTPCheck(input io.Reader) (string, error) {
|
||||
return "", errors.New("something went wrong NTPCheck should never make it this far")
|
||||
}
|
||||
|
||||
// CheckConnectionMonitorConfig checks and if zero value assigns default values
|
||||
func (c *Config) CheckConnectionMonitorConfig() {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
|
||||
if c.ConnectionMonitor.CheckInterval == 0 {
|
||||
c.ConnectionMonitor.CheckInterval = connchecker.DefaultCheckInterval
|
||||
}
|
||||
|
||||
if len(c.ConnectionMonitor.DNSList) == 0 {
|
||||
c.ConnectionMonitor.DNSList = connchecker.DefaultDNSList
|
||||
}
|
||||
|
||||
if len(c.ConnectionMonitor.PublicDomainList) == 0 {
|
||||
c.ConnectionMonitor.PublicDomainList = connchecker.DefaultDomainList
|
||||
}
|
||||
}
|
||||
|
||||
// GetFilePath returns the desired config file or the default config file name
|
||||
// based on if the application is being run under test or normal mode.
|
||||
func GetFilePath(file string) (string, error) {
|
||||
@@ -1351,6 +1379,7 @@ func (c *Config) CheckConfig() error {
|
||||
return fmt.Errorf(ErrCheckingConfigValues, err)
|
||||
}
|
||||
|
||||
c.CheckConnectionMonitorConfig()
|
||||
c.CheckCommunicationsConfig()
|
||||
|
||||
if c.Webserver.Enabled {
|
||||
|
||||
121
connchecker/connchecker.go
Normal file
121
connchecker/connchecker.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package connchecker
|
||||
|
||||
import (
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
log "github.com/thrasher-/gocryptotrader/logger"
|
||||
)
|
||||
|
||||
// DefaultCheckInterval is a const that defines the amount of time between
|
||||
// checking if the connection is lost
|
||||
const DefaultCheckInterval = time.Second
|
||||
|
||||
// Default check lists
|
||||
var (
|
||||
DefaultDNSList = []string{"8.8.8.8", "8.8.4.4", "1.1.1.1", "1.0.0.1"}
|
||||
DefaultDomainList = []string{"www.google.com", "www.cloudflare.com", "www.facebook.com"}
|
||||
)
|
||||
|
||||
// New returns a new connection checker, if no values set it will default it out
|
||||
func New(dnsList, domainList []string, checkInterval time.Duration) *Checker {
|
||||
c := &Checker{}
|
||||
if len(dnsList) == 0 {
|
||||
c.DNSList = DefaultDNSList
|
||||
} else {
|
||||
c.DNSList = dnsList
|
||||
}
|
||||
|
||||
if len(domainList) == 0 {
|
||||
c.DomainList = DefaultDomainList
|
||||
} else {
|
||||
c.DomainList = domainList
|
||||
}
|
||||
|
||||
if checkInterval == 0 {
|
||||
c.CheckInterval = DefaultCheckInterval
|
||||
} else {
|
||||
c.CheckInterval = checkInterval
|
||||
}
|
||||
|
||||
go c.Monitor()
|
||||
return c
|
||||
}
|
||||
|
||||
// Checker defines a struct to determine connectivity to the interwebs
|
||||
type Checker struct {
|
||||
DNSList []string
|
||||
DomainList []string
|
||||
CheckInterval time.Duration
|
||||
shutdown chan struct{}
|
||||
wg sync.WaitGroup
|
||||
connected bool
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
// Shutdown cleanly shutsdown monitor routine
|
||||
func (c *Checker) Shutdown() {
|
||||
c.shutdown <- struct{}{}
|
||||
c.wg.Wait()
|
||||
}
|
||||
|
||||
// Monitor determines internet connectivity via a DNS lookup
|
||||
func (c *Checker) Monitor() {
|
||||
c.wg.Add(1)
|
||||
tick := time.NewTicker(time.Second)
|
||||
defer func() { tick.Stop(); c.wg.Done() }()
|
||||
c.connectionTest()
|
||||
for {
|
||||
select {
|
||||
case <-tick.C:
|
||||
c.connectionTest()
|
||||
case <-c.shutdown:
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ConnectionTest determines if a connection to the internet is available by
|
||||
// iterating over a set list of dns ip and popular domains
|
||||
func (c *Checker) connectionTest() {
|
||||
for i := range c.DNSList {
|
||||
_, err := net.LookupAddr(c.DNSList[i])
|
||||
if err == nil {
|
||||
c.Lock()
|
||||
if !c.connected {
|
||||
log.Warnf("Internet connectivity re-established")
|
||||
c.connected = true
|
||||
}
|
||||
c.Unlock()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for i := range c.DomainList {
|
||||
_, err := net.LookupHost(c.DomainList[i])
|
||||
if err == nil {
|
||||
c.Lock()
|
||||
if !c.connected {
|
||||
log.Warnf("Internet connectivity re-established")
|
||||
c.connected = true
|
||||
}
|
||||
c.Unlock()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.Lock()
|
||||
if c.connected {
|
||||
log.Warnf("Internet connectivity lost")
|
||||
c.connected = false
|
||||
}
|
||||
c.Unlock()
|
||||
}
|
||||
|
||||
// IsConnected returns if there is internet connectivity
|
||||
func (c *Checker) IsConnected() bool {
|
||||
c.Lock()
|
||||
defer c.Unlock()
|
||||
return c.connected
|
||||
}
|
||||
27
main.go
27
main.go
@@ -8,12 +8,14 @@ import (
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/communications"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/connchecker"
|
||||
"github.com/thrasher-/gocryptotrader/currency"
|
||||
"github.com/thrasher-/gocryptotrader/currency/coinmarketcap"
|
||||
exchange "github.com/thrasher-/gocryptotrader/exchanges"
|
||||
@@ -25,14 +27,16 @@ import (
|
||||
// Bot contains configuration, portfolio, exchange & ticker data and is the
|
||||
// overarching type across this code base.
|
||||
type Bot struct {
|
||||
config *config.Config
|
||||
portfolio *portfolio.Base
|
||||
exchanges []exchange.IBotExchange
|
||||
comms *communications.Communications
|
||||
shutdown chan bool
|
||||
dryRun bool
|
||||
configFile string
|
||||
dataDir string
|
||||
config *config.Config
|
||||
portfolio *portfolio.Base
|
||||
exchanges []exchange.IBotExchange
|
||||
comms *communications.Communications
|
||||
shutdown chan bool
|
||||
dryRun bool
|
||||
configFile string
|
||||
dataDir string
|
||||
connectivity *connchecker.Checker
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
const banner = `
|
||||
@@ -129,6 +133,11 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
// Sets up internet connectivity monitor
|
||||
bot.connectivity = connchecker.New(bot.config.ConnectionMonitor.DNSList,
|
||||
bot.config.ConnectionMonitor.PublicDomainList,
|
||||
bot.config.ConnectionMonitor.CheckInterval)
|
||||
|
||||
AdjustGoMaxProcs()
|
||||
log.Debugf("Bot '%s' started.\n", bot.config.Name)
|
||||
log.Debugf("Bot dry run mode: %v.\n", common.IsEnabled(bot.dryRun))
|
||||
@@ -243,7 +252,7 @@ func HandleInterrupt() {
|
||||
go func() {
|
||||
sig := <-c
|
||||
log.Debugf("Captured %v, shutdown requested.", sig)
|
||||
bot.shutdown <- true
|
||||
close(bot.shutdown)
|
||||
}()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user