mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
egnine/sync-manager: add config support (#1326)
* allows sync manager customisation for values and logs * config-example add * who doesnt like more coverage? * ensures you can actually disable it via config el oh el * less ifs, better control * fix verbose * sync trades default false * fix summary being printed when not enabled * fixes config checker and output * nits * I can put this behind me now * Fixed logCaSiNg Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * combines if statements --------- Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>
This commit is contained in:
@@ -696,6 +696,63 @@ func (c *Config) GetAvailablePairs(exchName string, assetType asset.Item) (curre
|
||||
return pairs.Format(pairFormat), nil
|
||||
}
|
||||
|
||||
// GetDefaultSyncManagerConfig returns a config with default values
|
||||
func GetDefaultSyncManagerConfig() SyncManagerConfig {
|
||||
return SyncManagerConfig{
|
||||
Enabled: true,
|
||||
SynchronizeTicker: true,
|
||||
SynchronizeOrderbook: true,
|
||||
SynchronizeTrades: false,
|
||||
SynchronizeContinuously: true,
|
||||
TimeoutREST: DefaultSyncerTimeoutREST,
|
||||
TimeoutWebsocket: DefaultSyncerTimeoutWebsocket,
|
||||
NumWorkers: DefaultSyncerWorkers,
|
||||
FiatDisplayCurrency: currency.USD,
|
||||
PairFormatDisplay: ¤cy.PairFormat{
|
||||
Delimiter: "-",
|
||||
Uppercase: true,
|
||||
},
|
||||
Verbose: false,
|
||||
LogSyncUpdateEvents: true,
|
||||
LogSwitchProtocolEvents: true,
|
||||
LogInitialSyncEvents: true,
|
||||
}
|
||||
}
|
||||
|
||||
// CheckSyncManagerConfig checks config for valid values
|
||||
// sets defaults if values are invalid
|
||||
func (c *Config) CheckSyncManagerConfig() {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
if c.SyncManagerConfig == (SyncManagerConfig{}) {
|
||||
c.SyncManagerConfig = GetDefaultSyncManagerConfig()
|
||||
return
|
||||
}
|
||||
if c.SyncManagerConfig.TimeoutWebsocket <= 0 {
|
||||
log.Warnf(log.ConfigMgr, "Invalid sync manager websocket timeout value %v, defaulting to %v\n", c.SyncManagerConfig.TimeoutWebsocket, DefaultSyncerTimeoutWebsocket)
|
||||
c.SyncManagerConfig.TimeoutWebsocket = DefaultSyncerTimeoutWebsocket
|
||||
}
|
||||
if c.SyncManagerConfig.PairFormatDisplay == nil {
|
||||
log.Warnf(log.ConfigMgr, "Invalid sync manager pair format value %v, using default format eg BTC-USD\n", c.SyncManagerConfig.PairFormatDisplay)
|
||||
c.SyncManagerConfig.PairFormatDisplay = ¤cy.PairFormat{
|
||||
Uppercase: true,
|
||||
Delimiter: currency.DashDelimiter,
|
||||
}
|
||||
}
|
||||
if c.SyncManagerConfig.TimeoutREST <= 0 {
|
||||
log.Warnf(log.ConfigMgr, "Invalid sync manager REST timeout value %v, defaulting to %v\n", c.SyncManagerConfig.TimeoutREST, DefaultSyncerTimeoutREST)
|
||||
c.SyncManagerConfig.TimeoutREST = DefaultSyncerTimeoutREST
|
||||
}
|
||||
if c.SyncManagerConfig.NumWorkers <= 0 {
|
||||
log.Warnf(log.ConfigMgr, "Invalid sync manager worker count value %v, defaulting to %v\n", c.SyncManagerConfig.NumWorkers, DefaultSyncerWorkers)
|
||||
c.SyncManagerConfig.NumWorkers = DefaultSyncerWorkers
|
||||
}
|
||||
if c.SyncManagerConfig.FiatDisplayCurrency.IsEmpty() {
|
||||
log.Warnf(log.ConfigMgr, "Invalid sync manager fiat display currency value, defaulting to %v\n", currency.USD)
|
||||
c.SyncManagerConfig.FiatDisplayCurrency = currency.USD
|
||||
}
|
||||
}
|
||||
|
||||
// GetEnabledPairs returns a list of currency pairs for a specific exchange
|
||||
func (c *Config) GetEnabledPairs(exchName string, assetType asset.Item) (currency.Pairs, error) {
|
||||
exchCfg, err := c.GetExchangeConfig(exchName)
|
||||
@@ -1730,6 +1787,7 @@ func (c *Config) CheckConfig() error {
|
||||
c.CheckClientBankAccounts()
|
||||
c.CheckBankAccountConfig()
|
||||
c.CheckRemoteControlConfig()
|
||||
c.CheckSyncManagerConfig()
|
||||
|
||||
err = c.CheckCurrencyConfigValues()
|
||||
if err != nil {
|
||||
|
||||
@@ -2299,3 +2299,46 @@ func TestExchangeConfigValidate(t *testing.T) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDefaultSyncManagerConfig(t *testing.T) {
|
||||
t.Parallel()
|
||||
cfg := GetDefaultSyncManagerConfig()
|
||||
if cfg == (SyncManagerConfig{}) {
|
||||
t.Error("expected config")
|
||||
}
|
||||
if cfg.TimeoutREST != DefaultSyncerTimeoutREST {
|
||||
t.Errorf("expected %v, received %v", DefaultSyncerTimeoutREST, cfg.TimeoutREST)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckSyncManagerConfig(t *testing.T) {
|
||||
t.Parallel()
|
||||
c := Config{}
|
||||
if c.SyncManagerConfig != (SyncManagerConfig{}) {
|
||||
t.Error("expected empty config")
|
||||
}
|
||||
c.CheckSyncManagerConfig()
|
||||
if c.SyncManagerConfig.TimeoutREST != DefaultSyncerTimeoutREST {
|
||||
t.Error("expected default config")
|
||||
}
|
||||
c.SyncManagerConfig.TimeoutWebsocket = -1
|
||||
c.SyncManagerConfig.PairFormatDisplay = nil
|
||||
c.SyncManagerConfig.TimeoutREST = -1
|
||||
c.SyncManagerConfig.NumWorkers = -1
|
||||
c.CurrencyPairFormat = ¤cy.PairFormat{
|
||||
Uppercase: true,
|
||||
}
|
||||
c.CheckSyncManagerConfig()
|
||||
if c.SyncManagerConfig.TimeoutWebsocket != DefaultSyncerTimeoutWebsocket {
|
||||
t.Errorf("received %v expected %v", c.SyncManagerConfig.TimeoutWebsocket, DefaultSyncerTimeoutWebsocket)
|
||||
}
|
||||
if c.SyncManagerConfig.PairFormatDisplay == nil {
|
||||
t.Errorf("received %v expected %v", c.SyncManagerConfig.PairFormatDisplay, c.CurrencyPairFormat)
|
||||
}
|
||||
if c.SyncManagerConfig.TimeoutREST != DefaultSyncerTimeoutREST {
|
||||
t.Errorf("received %v expected %v", c.SyncManagerConfig.TimeoutREST, DefaultSyncerTimeoutREST)
|
||||
}
|
||||
if c.SyncManagerConfig.NumWorkers != DefaultSyncerWorkers {
|
||||
t.Errorf("received %v expected %v", c.SyncManagerConfig.NumWorkers, DefaultSyncerWorkers)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,12 @@ const (
|
||||
defaultCurrencyStateManagerDelay = time.Minute
|
||||
defaultMaxJobsPerCycle = 5
|
||||
DefaultOrderbookPublishPeriod = time.Second * 10
|
||||
// DefaultSyncerWorkers limits the number of sync workers
|
||||
DefaultSyncerWorkers = 15
|
||||
// DefaultSyncerTimeoutREST the default time to switch from REST to websocket protocols without a response
|
||||
DefaultSyncerTimeoutREST = time.Second * 15
|
||||
// DefaultSyncerTimeoutWebsocket the default time to switch from websocket to REST protocols without a response
|
||||
DefaultSyncerTimeoutWebsocket = time.Minute
|
||||
)
|
||||
|
||||
// Constants here hold some messages
|
||||
@@ -81,6 +87,7 @@ type Config struct {
|
||||
GlobalHTTPTimeout time.Duration `json:"globalHTTPTimeout"`
|
||||
Database database.Config `json:"database"`
|
||||
Logging log.Config `json:"logging"`
|
||||
SyncManagerConfig SyncManagerConfig `json:"syncManager"`
|
||||
ConnectionMonitor ConnectionMonitorConfig `json:"connectionMonitor"`
|
||||
OrderManager OrderManager `json:"orderManager"`
|
||||
DataHistoryManager DataHistoryManager `json:"dataHistoryManager"`
|
||||
@@ -130,6 +137,25 @@ type CurrencyStateManager struct {
|
||||
Delay time.Duration `json:"delay"`
|
||||
}
|
||||
|
||||
// SyncManagerConfig stores the currency pair synchronization manager config
|
||||
type SyncManagerConfig struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
SynchronizeTicker bool `json:"synchronizeTicker"`
|
||||
SynchronizeOrderbook bool `json:"synchronizeOrderbook"`
|
||||
SynchronizeTrades bool `json:"synchronizeTrades"`
|
||||
SynchronizeContinuously bool `json:"synchronizeContinuously"`
|
||||
TimeoutREST time.Duration `json:"timeoutREST"`
|
||||
TimeoutWebsocket time.Duration `json:"timeoutWebsocket"`
|
||||
NumWorkers int `json:"numWorkers"`
|
||||
FiatDisplayCurrency currency.Code `json:"fiatDisplayCurrency"`
|
||||
PairFormatDisplay *currency.PairFormat `json:"pairFormatDisplay,omitempty"`
|
||||
// log events
|
||||
Verbose bool `json:"verbose"`
|
||||
LogSyncUpdateEvents bool `json:"logSyncUpdateEvents"`
|
||||
LogSwitchProtocolEvents bool `json:"logSwitchProtocolEvents"`
|
||||
LogInitialSyncEvents bool `json:"logInitialSyncEvents"`
|
||||
}
|
||||
|
||||
// ConnectionMonitorConfig defines the connection monitor variables to ensure
|
||||
// that there is internet connectivity
|
||||
type ConnectionMonitorConfig struct {
|
||||
|
||||
@@ -37,6 +37,25 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"syncManager": {
|
||||
"enabled": true,
|
||||
"synchronizeTicker": true,
|
||||
"synchronizeOrderbook": true,
|
||||
"synchronizeTrades": true,
|
||||
"synchronizeContinuously": true,
|
||||
"timeoutREST": 15000000000,
|
||||
"timeoutWebsocket": 60000000000,
|
||||
"numWorkers": 15,
|
||||
"fiatDisplayCurrency": "USD",
|
||||
"pairFormatDisplay": {
|
||||
"uppercase": true,
|
||||
"delimiter": "-"
|
||||
},
|
||||
"verbose": false,
|
||||
"logSyncUpdateEvents": true,
|
||||
"logSwitchProtocolEvents": true,
|
||||
"logInitialSyncEvents": true
|
||||
},
|
||||
"connectionMonitor": {
|
||||
"preferredDNSList": [
|
||||
"8.8.8.8",
|
||||
|
||||
@@ -179,6 +179,12 @@ func validateSettings(b *Engine, s *Settings, flagSet FlagSet) {
|
||||
flagSet.WithBool("currencystatemanager", &b.Settings.EnableCurrencyStateManager, b.Config.CurrencyStateManager.Enabled != nil && *b.Config.CurrencyStateManager.Enabled)
|
||||
flagSet.WithBool("gctscriptmanager", &b.Settings.EnableGCTScriptManager, b.Config.GCTScript.Enabled)
|
||||
|
||||
flagSet.WithBool("tickersync", &b.Settings.EnableTickerSyncing, b.Config.SyncManagerConfig.SynchronizeTicker)
|
||||
flagSet.WithBool("orderbooksync", &b.Settings.EnableOrderbookSyncing, b.Config.SyncManagerConfig.SynchronizeOrderbook)
|
||||
flagSet.WithBool("tradesync", &b.Settings.EnableTradeSyncing, b.Config.SyncManagerConfig.SynchronizeTrades)
|
||||
flagSet.WithBool("synccontinuously", &b.Settings.SyncContinuously, b.Config.SyncManagerConfig.SynchronizeContinuously)
|
||||
flagSet.WithBool("syncmanager", &b.Settings.EnableExchangeSyncManager, b.Config.SyncManagerConfig.Enabled)
|
||||
|
||||
if b.Settings.EnablePortfolioManager &&
|
||||
b.Settings.PortfolioManagerDelay <= 0 {
|
||||
b.Settings.PortfolioManagerDelay = PortfolioSleepDelay
|
||||
@@ -491,21 +497,27 @@ func (bot *Engine) Start() error {
|
||||
}
|
||||
|
||||
if bot.Settings.EnableExchangeSyncManager {
|
||||
exchangeSyncCfg := &SyncManagerConfig{
|
||||
SynchronizeTicker: bot.Settings.EnableTickerSyncing,
|
||||
SynchronizeOrderbook: bot.Settings.EnableOrderbookSyncing,
|
||||
SynchronizeTrades: bot.Settings.EnableTradeSyncing,
|
||||
SynchronizeContinuously: bot.Settings.SyncContinuously,
|
||||
TimeoutREST: bot.Settings.SyncTimeoutREST,
|
||||
TimeoutWebsocket: bot.Settings.SyncTimeoutWebsocket,
|
||||
NumWorkers: bot.Settings.SyncWorkersCount,
|
||||
Verbose: bot.Settings.Verbose,
|
||||
FiatDisplayCurrency: bot.Config.Currency.FiatDisplayCurrency,
|
||||
PairFormatDisplay: bot.Config.Currency.CurrencyPairFormat,
|
||||
}
|
||||
cfg := bot.Config.SyncManagerConfig
|
||||
cfg.SynchronizeTicker = bot.Settings.EnableTickerSyncing
|
||||
cfg.SynchronizeOrderbook = bot.Settings.EnableOrderbookSyncing
|
||||
cfg.SynchronizeContinuously = bot.Settings.SyncContinuously
|
||||
cfg.SynchronizeTrades = bot.Settings.EnableTradeSyncing
|
||||
cfg.Verbose = bot.Settings.Verbose || cfg.Verbose
|
||||
|
||||
if cfg.TimeoutREST != bot.Settings.SyncTimeoutREST &&
|
||||
bot.Settings.SyncTimeoutREST != config.DefaultSyncerTimeoutREST {
|
||||
cfg.TimeoutREST = bot.Settings.SyncTimeoutREST
|
||||
}
|
||||
if cfg.TimeoutWebsocket != bot.Settings.SyncTimeoutWebsocket &&
|
||||
bot.Settings.SyncTimeoutWebsocket != config.DefaultSyncerTimeoutWebsocket {
|
||||
cfg.TimeoutWebsocket = bot.Settings.SyncTimeoutWebsocket
|
||||
}
|
||||
if cfg.NumWorkers != bot.Settings.SyncWorkersCount &&
|
||||
bot.Settings.SyncWorkersCount != config.DefaultSyncerWorkers {
|
||||
cfg.NumWorkers = bot.Settings.SyncWorkersCount
|
||||
}
|
||||
if s, err := setupSyncManager(
|
||||
exchangeSyncCfg,
|
||||
&cfg,
|
||||
bot.ExchangeManager,
|
||||
&bot.Config.RemoteControl,
|
||||
bot.Settings.EnableWebsocketRoutine,
|
||||
|
||||
@@ -185,19 +185,27 @@ func (bot *Engine) SetSubsystem(subSystemName string, enable bool) error {
|
||||
case SyncManagerName:
|
||||
if enable {
|
||||
if bot.currencyPairSyncer == nil {
|
||||
exchangeSyncCfg := &SyncManagerConfig{
|
||||
SynchronizeTicker: bot.Settings.EnableTickerSyncing,
|
||||
SynchronizeOrderbook: bot.Settings.EnableOrderbookSyncing,
|
||||
SynchronizeTrades: bot.Settings.EnableTradeSyncing,
|
||||
SynchronizeContinuously: bot.Settings.SyncContinuously,
|
||||
TimeoutREST: bot.Settings.SyncTimeoutREST,
|
||||
TimeoutWebsocket: bot.Settings.SyncTimeoutWebsocket,
|
||||
NumWorkers: bot.Settings.SyncWorkersCount,
|
||||
FiatDisplayCurrency: bot.Config.Currency.FiatDisplayCurrency,
|
||||
Verbose: bot.Settings.Verbose,
|
||||
cfg := bot.Config.SyncManagerConfig
|
||||
cfg.SynchronizeTicker = bot.Settings.EnableTickerSyncing
|
||||
cfg.SynchronizeOrderbook = bot.Settings.EnableOrderbookSyncing
|
||||
cfg.SynchronizeContinuously = bot.Settings.SyncContinuously
|
||||
cfg.SynchronizeTrades = bot.Settings.EnableTradeSyncing
|
||||
cfg.Verbose = bot.Settings.Verbose || cfg.Verbose
|
||||
|
||||
if cfg.TimeoutREST != bot.Settings.SyncTimeoutREST &&
|
||||
bot.Settings.SyncTimeoutREST != config.DefaultSyncerTimeoutREST {
|
||||
cfg.TimeoutREST = bot.Settings.SyncTimeoutREST
|
||||
}
|
||||
if cfg.TimeoutWebsocket != bot.Settings.SyncTimeoutWebsocket &&
|
||||
bot.Settings.SyncTimeoutWebsocket != config.DefaultSyncerTimeoutWebsocket {
|
||||
cfg.TimeoutWebsocket = bot.Settings.SyncTimeoutWebsocket
|
||||
}
|
||||
if cfg.NumWorkers != bot.Settings.SyncWorkersCount &&
|
||||
bot.Settings.SyncWorkersCount != config.DefaultSyncerWorkers {
|
||||
cfg.NumWorkers = bot.Settings.SyncWorkersCount
|
||||
}
|
||||
bot.currencyPairSyncer, err = setupSyncManager(
|
||||
exchangeSyncCfg,
|
||||
&cfg,
|
||||
bot.ExchangeManager,
|
||||
&bot.Config.RemoteControl,
|
||||
bot.Settings.EnableWebsocketRoutine)
|
||||
|
||||
@@ -32,21 +32,15 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
createdCounter = 0
|
||||
removedCounter = 0
|
||||
// DefaultSyncerWorkers limits the number of sync workers
|
||||
DefaultSyncerWorkers = 15
|
||||
// DefaultSyncerTimeoutREST the default time to switch from REST to websocket protocols without a response
|
||||
DefaultSyncerTimeoutREST = time.Second * 15
|
||||
// DefaultSyncerTimeoutWebsocket the default time to switch from websocket to REST protocols without a response
|
||||
DefaultSyncerTimeoutWebsocket = time.Minute
|
||||
errNoSyncItemsEnabled = errors.New("no sync items enabled")
|
||||
errUnknownSyncItem = errors.New("unknown sync item")
|
||||
errCouldNotSyncNewData = errors.New("could not sync new data")
|
||||
createdCounter = 0
|
||||
removedCounter = 0
|
||||
errNoSyncItemsEnabled = errors.New("no sync items enabled")
|
||||
errUnknownSyncItem = errors.New("unknown sync item")
|
||||
errCouldNotSyncNewData = errors.New("could not sync new data")
|
||||
)
|
||||
|
||||
// setupSyncManager starts a new CurrencyPairSyncer
|
||||
func setupSyncManager(c *SyncManagerConfig, exchangeManager iExchangeManager, remoteConfig *config.RemoteControlConfig, websocketRoutineManagerEnabled bool) (*syncManager, error) {
|
||||
func setupSyncManager(c *config.SyncManagerConfig, exchangeManager iExchangeManager, remoteConfig *config.RemoteControlConfig, websocketRoutineManagerEnabled bool) (*syncManager, error) {
|
||||
if c == nil {
|
||||
return nil, fmt.Errorf("%T %w", c, common.ErrNilPointer)
|
||||
}
|
||||
@@ -62,15 +56,15 @@ func setupSyncManager(c *SyncManagerConfig, exchangeManager iExchangeManager, re
|
||||
}
|
||||
|
||||
if c.NumWorkers <= 0 {
|
||||
c.NumWorkers = DefaultSyncerWorkers
|
||||
c.NumWorkers = config.DefaultSyncerWorkers
|
||||
}
|
||||
|
||||
if c.TimeoutREST <= time.Duration(0) {
|
||||
c.TimeoutREST = DefaultSyncerTimeoutREST
|
||||
c.TimeoutREST = config.DefaultSyncerTimeoutREST
|
||||
}
|
||||
|
||||
if c.TimeoutWebsocket <= time.Duration(0) {
|
||||
c.TimeoutWebsocket = DefaultSyncerTimeoutWebsocket
|
||||
c.TimeoutWebsocket = config.DefaultSyncerTimeoutWebsocket
|
||||
}
|
||||
|
||||
if c.FiatDisplayCurrency.IsEmpty() {
|
||||
@@ -120,6 +114,11 @@ func (m *syncManager) Start() error {
|
||||
if !atomic.CompareAndSwapInt32(&m.started, 0, 1) {
|
||||
return ErrSubSystemAlreadyStarted
|
||||
}
|
||||
if !m.config.SynchronizeTicker &&
|
||||
!m.config.SynchronizeOrderbook &&
|
||||
!m.config.SynchronizeTrades {
|
||||
return errNoSyncItemsEnabled
|
||||
}
|
||||
m.shutdown = make(chan bool)
|
||||
m.initSyncWG.Add(1)
|
||||
m.inService.Done()
|
||||
@@ -196,19 +195,22 @@ func (m *syncManager) Start() error {
|
||||
}
|
||||
|
||||
if atomic.CompareAndSwapInt32(&m.initSyncStarted, 0, 1) {
|
||||
log.Debugf(log.SyncMgr,
|
||||
"Exchange CurrencyPairSyncer initial sync started. %d items to process.",
|
||||
createdCounter)
|
||||
if m.config.LogInitialSyncEvents {
|
||||
log.Debugf(log.SyncMgr,
|
||||
"Exchange CurrencyPairSyncer initial sync started. %d items to process.",
|
||||
createdCounter)
|
||||
}
|
||||
m.initSyncStartTime = time.Now()
|
||||
}
|
||||
|
||||
go func() {
|
||||
m.initSyncWG.Wait()
|
||||
if atomic.CompareAndSwapInt32(&m.initSyncCompleted, 0, 1) {
|
||||
log.Debugf(log.SyncMgr, "Exchange CurrencyPairSyncer initial sync is complete.")
|
||||
completedTime := time.Now()
|
||||
log.Debugf(log.SyncMgr, "Exchange CurrencyPairSyncer initial sync took %v [%v sync items].",
|
||||
completedTime.Sub(m.initSyncStartTime), createdCounter)
|
||||
if m.config.LogInitialSyncEvents {
|
||||
log.Debugf(log.SyncMgr, "Exchange CurrencyPairSyncer initial sync is complete.")
|
||||
log.Debugf(log.SyncMgr, "Exchange CurrencyPairSyncer initial sync took %v [%v sync items].",
|
||||
time.Since(m.initSyncStartTime), createdCounter)
|
||||
}
|
||||
|
||||
if !m.config.SynchronizeContinuously {
|
||||
log.Debugln(log.SyncMgr, "Exchange CurrencyPairSyncer stopping.")
|
||||
@@ -382,13 +384,15 @@ func (m *syncManager) WebsocketUpdate(exchangeName string, p currency.Pair, a as
|
||||
if !s.IsUsingWebsocket {
|
||||
s.IsUsingWebsocket = true
|
||||
s.IsUsingREST = false
|
||||
log.Warnf(log.SyncMgr,
|
||||
"%s %s %s: %s Websocket re-enabled, switching from rest to websocket",
|
||||
c.Exchange,
|
||||
m.FormatCurrency(c.Pair),
|
||||
strings.ToUpper(c.AssetType.String()),
|
||||
syncType,
|
||||
)
|
||||
if m.config.LogSwitchProtocolEvents {
|
||||
log.Warnf(log.SyncMgr,
|
||||
"%s %s %s: %s Websocket re-enabled, switching from rest to websocket",
|
||||
c.Exchange,
|
||||
m.FormatCurrency(c.Pair),
|
||||
strings.ToUpper(c.AssetType.String()),
|
||||
syncType,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return m.update(c, syncType, err)
|
||||
@@ -410,12 +414,14 @@ func (m *syncManager) update(c *currencyPairSyncAgent, syncType syncItemType, er
|
||||
s.HaveData = true
|
||||
if atomic.LoadInt32(&m.initSyncCompleted) != 1 && !origHadData {
|
||||
removedCounter++
|
||||
log.Debugf(log.SyncMgr, "%s %s sync complete %v [%d/%d].",
|
||||
c.Exchange,
|
||||
syncType,
|
||||
m.FormatCurrency(c.Pair),
|
||||
removedCounter,
|
||||
createdCounter)
|
||||
if m.config.LogInitialSyncEvents {
|
||||
log.Debugf(log.SyncMgr, "%s %s sync complete %v [%d/%d].",
|
||||
c.Exchange,
|
||||
syncType,
|
||||
m.FormatCurrency(c.Pair),
|
||||
removedCounter,
|
||||
createdCounter)
|
||||
}
|
||||
m.initSyncWG.Done()
|
||||
}
|
||||
|
||||
@@ -532,13 +538,15 @@ func (m *syncManager) syncTicker(c *currencyPairSyncAgent, e exchange.IBotExchan
|
||||
// Downgrade to REST
|
||||
s.IsUsingWebsocket = false
|
||||
s.IsUsingREST = true
|
||||
log.Warnf(log.SyncMgr,
|
||||
"%s %s %s: No ticker update after %s, switching from websocket to rest",
|
||||
c.Exchange,
|
||||
m.FormatCurrency(c.Pair),
|
||||
strings.ToUpper(c.AssetType.String()),
|
||||
m.config.TimeoutWebsocket,
|
||||
)
|
||||
if m.config.LogSwitchProtocolEvents {
|
||||
log.Warnf(log.SyncMgr,
|
||||
"%s %s %s: No ticker update after %s, switching from websocket to rest",
|
||||
c.Exchange,
|
||||
m.FormatCurrency(c.Pair),
|
||||
strings.ToUpper(c.AssetType.String()),
|
||||
m.config.TimeoutWebsocket,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if s.IsUsingREST && time.Since(s.LastUpdated) > m.config.TimeoutREST {
|
||||
@@ -605,13 +613,15 @@ func (m *syncManager) syncOrderbook(c *currencyPairSyncAgent, e exchange.IBotExc
|
||||
// Downgrade to REST
|
||||
s.IsUsingWebsocket = false
|
||||
s.IsUsingREST = true
|
||||
log.Warnf(log.SyncMgr,
|
||||
"%s %s %s: No orderbook update after %s, switching from websocket to rest",
|
||||
c.Exchange,
|
||||
m.FormatCurrency(c.Pair).String(),
|
||||
strings.ToUpper(c.AssetType.String()),
|
||||
m.config.TimeoutWebsocket,
|
||||
)
|
||||
if m.config.LogSwitchProtocolEvents {
|
||||
log.Warnf(log.SyncMgr,
|
||||
"%s %s %s: No orderbook update after %s, switching from websocket to rest",
|
||||
c.Exchange,
|
||||
m.FormatCurrency(c.Pair).String(),
|
||||
strings.ToUpper(c.AssetType.String()),
|
||||
m.config.TimeoutWebsocket,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if s.IsUsingREST && time.Since(s.LastUpdated) > m.config.TimeoutREST {
|
||||
@@ -691,6 +701,9 @@ func (m *syncManager) PrintTickerSummary(result *ticker.Price, protocol string,
|
||||
if m == nil || atomic.LoadInt32(&m.started) == 0 {
|
||||
return
|
||||
}
|
||||
if !m.config.SynchronizeTicker {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
if err == common.ErrNotYetImplemented {
|
||||
log.Warnf(log.SyncMgr, "Failed to get %s ticker. Error: %s",
|
||||
@@ -706,6 +719,9 @@ func (m *syncManager) PrintTickerSummary(result *ticker.Price, protocol string,
|
||||
|
||||
// ignoring error as not all tickers have volume populated and error is not actionable
|
||||
_ = stats.Add(result.ExchangeName, result.Pair, result.AssetType, result.Last, result.Volume)
|
||||
if !m.config.LogSyncUpdateEvents {
|
||||
return
|
||||
}
|
||||
|
||||
if result.Pair.Quote.IsFiatCurrency() &&
|
||||
!result.Pair.Quote.Equal(m.fiatDisplayCurrency) &&
|
||||
@@ -771,6 +787,9 @@ func (m *syncManager) PrintOrderbookSummary(result *orderbook.Base, protocol str
|
||||
if m == nil || atomic.LoadInt32(&m.started) == 0 {
|
||||
return
|
||||
}
|
||||
if !m.config.SynchronizeOrderbook {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
if result == nil {
|
||||
log.Errorf(log.OrderBook, "Failed to get %s orderbook. Error: %s",
|
||||
@@ -795,7 +814,9 @@ func (m *syncManager) PrintOrderbookSummary(result *orderbook.Base, protocol str
|
||||
err)
|
||||
return
|
||||
}
|
||||
|
||||
if !m.config.LogSyncUpdateEvents {
|
||||
return
|
||||
}
|
||||
bidsAmount, bidsValue := result.TotalBidsAmount()
|
||||
asksAmount, asksValue := result.TotalAsksAmount()
|
||||
|
||||
|
||||
@@ -20,37 +20,37 @@ func TestSetupSyncManager(t *testing.T) {
|
||||
t.Errorf("error '%v', expected '%v'", err, common.ErrNilPointer)
|
||||
}
|
||||
|
||||
_, err = setupSyncManager(&SyncManagerConfig{}, nil, nil, false)
|
||||
_, err = setupSyncManager(&config.SyncManagerConfig{}, nil, nil, false)
|
||||
if !errors.Is(err, errNoSyncItemsEnabled) {
|
||||
t.Errorf("error '%v', expected '%v'", err, errNoSyncItemsEnabled)
|
||||
}
|
||||
|
||||
_, err = setupSyncManager(&SyncManagerConfig{SynchronizeTrades: true}, nil, nil, false)
|
||||
_, err = setupSyncManager(&config.SyncManagerConfig{SynchronizeTrades: true}, nil, nil, false)
|
||||
if !errors.Is(err, errNilExchangeManager) {
|
||||
t.Errorf("error '%v', expected '%v'", err, errNilExchangeManager)
|
||||
}
|
||||
|
||||
_, err = setupSyncManager(&SyncManagerConfig{SynchronizeTrades: true}, &ExchangeManager{}, nil, false)
|
||||
_, err = setupSyncManager(&config.SyncManagerConfig{SynchronizeTrades: true}, &ExchangeManager{}, nil, false)
|
||||
if !errors.Is(err, errNilConfig) {
|
||||
t.Errorf("error '%v', expected '%v'", err, errNilConfig)
|
||||
}
|
||||
|
||||
_, err = setupSyncManager(&SyncManagerConfig{SynchronizeTrades: true}, &ExchangeManager{}, &config.RemoteControlConfig{}, true)
|
||||
_, err = setupSyncManager(&config.SyncManagerConfig{SynchronizeTrades: true}, &ExchangeManager{}, &config.RemoteControlConfig{}, true)
|
||||
if !errors.Is(err, currency.ErrCurrencyCodeEmpty) {
|
||||
t.Errorf("error '%v', expected '%v'", err, currency.ErrCurrencyCodeEmpty)
|
||||
}
|
||||
|
||||
_, err = setupSyncManager(&SyncManagerConfig{SynchronizeTrades: true, FiatDisplayCurrency: currency.BTC}, &ExchangeManager{}, &config.RemoteControlConfig{}, true)
|
||||
_, err = setupSyncManager(&config.SyncManagerConfig{SynchronizeTrades: true, FiatDisplayCurrency: currency.BTC}, &ExchangeManager{}, &config.RemoteControlConfig{}, true)
|
||||
if !errors.Is(err, currency.ErrFiatDisplayCurrencyIsNotFiat) {
|
||||
t.Errorf("error '%v', expected '%v'", err, currency.ErrFiatDisplayCurrencyIsNotFiat)
|
||||
}
|
||||
|
||||
_, err = setupSyncManager(&SyncManagerConfig{SynchronizeTrades: true, FiatDisplayCurrency: currency.USD}, &ExchangeManager{}, &config.RemoteControlConfig{}, true)
|
||||
_, err = setupSyncManager(&config.SyncManagerConfig{SynchronizeTrades: true, FiatDisplayCurrency: currency.USD}, &ExchangeManager{}, &config.RemoteControlConfig{}, true)
|
||||
if !errors.Is(err, common.ErrNilPointer) {
|
||||
t.Errorf("error '%v', expected '%v'", err, common.ErrNilPointer)
|
||||
}
|
||||
|
||||
m, err := setupSyncManager(&SyncManagerConfig{SynchronizeTrades: true, FiatDisplayCurrency: currency.USD, PairFormatDisplay: ¤cy.EMPTYFORMAT}, &ExchangeManager{}, &config.RemoteControlConfig{}, true)
|
||||
m, err := setupSyncManager(&config.SyncManagerConfig{SynchronizeTrades: true, FiatDisplayCurrency: currency.USD, PairFormatDisplay: ¤cy.EMPTYFORMAT}, &ExchangeManager{}, &config.RemoteControlConfig{}, true)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Errorf("error '%v', expected '%v'", err, nil)
|
||||
}
|
||||
@@ -61,7 +61,7 @@ func TestSetupSyncManager(t *testing.T) {
|
||||
|
||||
func TestSyncManagerStart(t *testing.T) {
|
||||
t.Parallel()
|
||||
m, err := setupSyncManager(&SyncManagerConfig{SynchronizeTrades: true, FiatDisplayCurrency: currency.USD, PairFormatDisplay: ¤cy.EMPTYFORMAT}, &ExchangeManager{}, &config.RemoteControlConfig{}, true)
|
||||
m, err := setupSyncManager(&config.SyncManagerConfig{SynchronizeTrades: true, FiatDisplayCurrency: currency.USD, PairFormatDisplay: ¤cy.EMPTYFORMAT}, &ExchangeManager{}, &config.RemoteControlConfig{}, true)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Errorf("error '%v', expected '%v'", err, nil)
|
||||
}
|
||||
@@ -112,7 +112,7 @@ func TestSyncManagerStop(t *testing.T) {
|
||||
if !errors.Is(err, nil) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
||||
}
|
||||
m, err = setupSyncManager(&SyncManagerConfig{SynchronizeTrades: true, SynchronizeContinuously: true, FiatDisplayCurrency: currency.USD, PairFormatDisplay: ¤cy.EMPTYFORMAT}, em, &config.RemoteControlConfig{}, false)
|
||||
m, err = setupSyncManager(&config.SyncManagerConfig{SynchronizeTrades: true, SynchronizeContinuously: true, FiatDisplayCurrency: currency.USD, PairFormatDisplay: ¤cy.EMPTYFORMAT}, em, &config.RemoteControlConfig{}, false)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Errorf("error '%v', expected '%v'", err, nil)
|
||||
}
|
||||
@@ -163,7 +163,7 @@ func TestPrintTickerSummary(t *testing.T) {
|
||||
if !errors.Is(err, nil) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
||||
}
|
||||
m, err = setupSyncManager(&SyncManagerConfig{SynchronizeTrades: true, SynchronizeContinuously: true, FiatDisplayCurrency: currency.USD, PairFormatDisplay: ¤cy.EMPTYFORMAT}, em, &config.RemoteControlConfig{}, false)
|
||||
m, err = setupSyncManager(&config.SyncManagerConfig{SynchronizeTrades: true, SynchronizeContinuously: true, FiatDisplayCurrency: currency.USD, PairFormatDisplay: ¤cy.EMPTYFORMAT}, em, &config.RemoteControlConfig{}, false)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Errorf("error '%v', expected '%v'", err, nil)
|
||||
}
|
||||
@@ -205,7 +205,7 @@ func TestPrintOrderbookSummary(t *testing.T) {
|
||||
if !errors.Is(err, nil) {
|
||||
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
||||
}
|
||||
m, err = setupSyncManager(&SyncManagerConfig{SynchronizeTrades: true, SynchronizeContinuously: true, FiatDisplayCurrency: currency.USD, PairFormatDisplay: ¤cy.EMPTYFORMAT}, em, &config.RemoteControlConfig{}, false)
|
||||
m, err = setupSyncManager(&config.SyncManagerConfig{SynchronizeTrades: true, SynchronizeContinuously: true, FiatDisplayCurrency: currency.USD, PairFormatDisplay: ¤cy.EMPTYFORMAT}, em, &config.RemoteControlConfig{}, false)
|
||||
if !errors.Is(err, nil) {
|
||||
t.Errorf("error '%v', expected '%v'", err, nil)
|
||||
}
|
||||
|
||||
@@ -33,20 +33,6 @@ type currencyPairSyncAgent struct {
|
||||
locks []sync.Mutex
|
||||
}
|
||||
|
||||
// SyncManagerConfig stores the currency pair synchronization manager config
|
||||
type SyncManagerConfig struct {
|
||||
SynchronizeTicker bool
|
||||
SynchronizeOrderbook bool
|
||||
SynchronizeTrades bool
|
||||
SynchronizeContinuously bool
|
||||
TimeoutREST time.Duration
|
||||
TimeoutWebsocket time.Duration
|
||||
NumWorkers int
|
||||
FiatDisplayCurrency currency.Code
|
||||
PairFormatDisplay *currency.PairFormat
|
||||
Verbose bool
|
||||
}
|
||||
|
||||
// syncManager stores the exchange currency pair syncer object
|
||||
type syncManager struct {
|
||||
initSyncCompleted int32
|
||||
@@ -65,6 +51,6 @@ type syncManager struct {
|
||||
tickerBatchLastRequested map[string]time.Time
|
||||
|
||||
remoteConfig *config.RemoteControlConfig
|
||||
config SyncManagerConfig
|
||||
config config.SyncManagerConfig
|
||||
exchangeManager iExchangeManager
|
||||
}
|
||||
|
||||
16
main.go
16
main.go
@@ -46,7 +46,7 @@ func main() {
|
||||
flag.BoolVar(&settings.EnableCommsRelayer, "enablecommsrelayer", true, "enables available communications relayer")
|
||||
flag.BoolVar(&settings.Verbose, "verbose", false, "increases logging verbosity for GoCryptoTrader")
|
||||
flag.BoolVar(&settings.EnableFuturesTracking, "enablefuturestracking", true, "tracks futures orders PNL is supported by the exchange")
|
||||
flag.BoolVar(&settings.EnableExchangeSyncManager, "syncmanager", true, "enables to exchange sync manager")
|
||||
flag.BoolVar(&settings.EnableExchangeSyncManager, "syncmanager", false, "enables to exchange sync manager")
|
||||
flag.BoolVar(&settings.EnableWebsocketRoutine, "websocketroutine", true, "enables the websocket routine for all loaded exchanges")
|
||||
flag.BoolVar(&settings.EnableCoinmarketcapAnalysis, "coinmarketcap", false, "overrides config and runs currency analysis")
|
||||
flag.BoolVar(&settings.EnableEventManager, "eventmanager", true, "enables the event manager")
|
||||
@@ -63,14 +63,14 @@ func main() {
|
||||
flag.IntVar(&settings.DispatchJobsLimit, "dispatchjobslimit", dispatch.DefaultJobsLimit, "sets the dispatch package max jobs limit")
|
||||
|
||||
// Exchange syncer settings
|
||||
flag.BoolVar(&settings.EnableTickerSyncing, "tickersync", true, "enables ticker syncing for all enabled exchanges")
|
||||
flag.BoolVar(&settings.EnableOrderbookSyncing, "orderbooksync", true, "enables orderbook syncing for all enabled exchanges")
|
||||
flag.BoolVar(&settings.EnableTradeSyncing, "tradesync", false, "enables trade syncing for all enabled exchanges")
|
||||
flag.IntVar(&settings.SyncWorkersCount, "syncworkers", engine.DefaultSyncerWorkers, "the amount of workers (goroutines) to use for syncing exchange data")
|
||||
flag.BoolVar(&settings.SyncContinuously, "synccontinuously", true, "whether to sync exchange data continuously (ticker, orderbook and trade history info")
|
||||
flag.DurationVar(&settings.SyncTimeoutREST, "synctimeoutrest", engine.DefaultSyncerTimeoutREST,
|
||||
flag.BoolVar(&settings.EnableTickerSyncing, "tickersync", false, "enables ticker syncing for all enabled exchanges, overriding false config value")
|
||||
flag.BoolVar(&settings.EnableOrderbookSyncing, "orderbooksync", false, "enables orderbook syncing for all enabled exchanges, overriding false config value")
|
||||
flag.BoolVar(&settings.EnableTradeSyncing, "tradesync", false, "enables trade syncing for all enabled exchanges, overriding false config value")
|
||||
flag.IntVar(&settings.SyncWorkersCount, "syncworkers", config.DefaultSyncerWorkers, "the amount of workers (goroutines) to use for syncing exchange data")
|
||||
flag.BoolVar(&settings.SyncContinuously, "synccontinuously", false, "whether to sync exchange data continuously (ticker, orderbook and trade history info), overriding false config value")
|
||||
flag.DurationVar(&settings.SyncTimeoutREST, "synctimeoutrest", config.DefaultSyncerTimeoutREST,
|
||||
"the amount of time before the syncer will switch from rest protocol to the streaming protocol (e.g. from REST to websocket)")
|
||||
flag.DurationVar(&settings.SyncTimeoutWebsocket, "synctimeoutwebsocket", engine.DefaultSyncerTimeoutWebsocket,
|
||||
flag.DurationVar(&settings.SyncTimeoutWebsocket, "synctimeoutwebsocket", config.DefaultSyncerTimeoutWebsocket,
|
||||
"the amount of time before the syncer will switch from the websocket protocol to REST protocol (e.g. from websocket to REST)")
|
||||
|
||||
// Forex provider settings
|
||||
|
||||
Reference in New Issue
Block a user