mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-27 23:16:51 +00:00
engine/websocket: subscribe to default channels only when actually needed (#610)
* if this is required by ws routines or sync manager * restore previous subscriptions on reconnect
This commit is contained in:
@@ -474,7 +474,7 @@ func (bot *Engine) Start() error {
|
||||
}
|
||||
|
||||
if bot.Settings.EnableWebsocketRoutine {
|
||||
go WebsocketRoutine()
|
||||
go bot.WebsocketRoutine()
|
||||
}
|
||||
|
||||
if bot.Settings.EnableGCTScriptManager {
|
||||
|
||||
@@ -11,18 +11,19 @@ import (
|
||||
|
||||
var ordersSetupRan bool
|
||||
|
||||
func OrdersSetup(t *testing.T) {
|
||||
SetupTestHelpers(t)
|
||||
func OrdersSetup(t *testing.T) *Engine {
|
||||
bot := SetupTestHelpers(t)
|
||||
if !ordersSetupRan {
|
||||
err := Bot.OrderManager.Start()
|
||||
err := bot.OrderManager.Start()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !Bot.OrderManager.Started() {
|
||||
if !bot.OrderManager.Started() {
|
||||
t.Fatal("Order manager not started")
|
||||
}
|
||||
ordersSetupRan = true
|
||||
}
|
||||
return bot
|
||||
}
|
||||
|
||||
func TestOrdersGet(t *testing.T) {
|
||||
|
||||
@@ -200,16 +200,16 @@ func relayWebsocketEvent(result interface{}, event, assetType, exchangeName stri
|
||||
}
|
||||
|
||||
// WebsocketRoutine Initial routine management system for websocket
|
||||
func WebsocketRoutine() {
|
||||
if Bot.Settings.Verbose {
|
||||
func (bot *Engine) WebsocketRoutine() {
|
||||
if bot.Settings.Verbose {
|
||||
log.Debugln(log.WebsocketMgr, "Connecting exchange websocket services...")
|
||||
}
|
||||
|
||||
exchanges := Bot.GetExchanges()
|
||||
exchanges := bot.GetExchanges()
|
||||
for i := range exchanges {
|
||||
go func(i int) {
|
||||
if exchanges[i].SupportsWebsocket() {
|
||||
if Bot.Settings.Verbose {
|
||||
if bot.Settings.Verbose {
|
||||
log.Debugf(log.WebsocketMgr,
|
||||
"Exchange %s websocket support: Yes Enabled: %v\n",
|
||||
exchanges[i].GetName(),
|
||||
@@ -235,15 +235,19 @@ func WebsocketRoutine() {
|
||||
}
|
||||
|
||||
// Data handler routine
|
||||
go WebsocketDataReceiver(ws)
|
||||
go bot.WebsocketDataReceiver(ws)
|
||||
|
||||
if ws.IsEnabled() {
|
||||
err = ws.Connect()
|
||||
if err != nil {
|
||||
log.Errorf(log.WebsocketMgr, "%v\n", err)
|
||||
}
|
||||
err = ws.FlushChannels()
|
||||
if err != nil {
|
||||
log.Errorf(log.WebsocketMgr, "Failed to subscribe: %v\n", err)
|
||||
}
|
||||
}
|
||||
} else if Bot.Settings.Verbose {
|
||||
} else if bot.Settings.Verbose {
|
||||
log.Debugf(log.WebsocketMgr,
|
||||
"Exchange %s websocket support: No\n",
|
||||
exchanges[i].GetName(),
|
||||
@@ -258,7 +262,7 @@ var wg sync.WaitGroup
|
||||
|
||||
// WebsocketDataReceiver handles websocket data coming from a websocket feed
|
||||
// associated with an exchange
|
||||
func WebsocketDataReceiver(ws *stream.Websocket) {
|
||||
func (bot *Engine) WebsocketDataReceiver(ws *stream.Websocket) {
|
||||
wg.Add(1)
|
||||
defer wg.Done()
|
||||
|
||||
@@ -267,7 +271,7 @@ func WebsocketDataReceiver(ws *stream.Websocket) {
|
||||
case <-shutdowner:
|
||||
return
|
||||
case data := <-ws.ToRoutine:
|
||||
err := WebsocketDataHandler(ws.GetName(), data)
|
||||
err := bot.WebsocketDataHandler(ws.GetName(), data)
|
||||
if err != nil {
|
||||
log.Error(log.WebsocketMgr, err)
|
||||
}
|
||||
@@ -277,7 +281,7 @@ func WebsocketDataReceiver(ws *stream.Websocket) {
|
||||
|
||||
// WebsocketDataHandler is a central point for exchange websocket implementations to send
|
||||
// processed data. WebsocketDataHandler will then pass that to an appropriate handler
|
||||
func WebsocketDataHandler(exchName string, data interface{}) error {
|
||||
func (bot *Engine) WebsocketDataHandler(exchName string, data interface{}) error {
|
||||
if data == nil {
|
||||
return fmt.Errorf("routines.go - exchange %s nil data sent to websocket",
|
||||
exchName)
|
||||
@@ -289,7 +293,7 @@ func WebsocketDataHandler(exchName string, data interface{}) error {
|
||||
case error:
|
||||
return fmt.Errorf("routines.go exchange %s websocket error - %s", exchName, data)
|
||||
case stream.FundingData:
|
||||
if Bot.Settings.Verbose {
|
||||
if bot.Settings.Verbose {
|
||||
log.Infof(log.WebsocketMgr, "%s websocket %s %s funding updated %+v",
|
||||
exchName,
|
||||
FormatCurrency(d.CurrencyPair),
|
||||
@@ -297,8 +301,8 @@ func WebsocketDataHandler(exchName string, data interface{}) error {
|
||||
d)
|
||||
}
|
||||
case *ticker.Price:
|
||||
if Bot.Settings.EnableExchangeSyncManager && Bot.ExchangeCurrencyPairManager != nil {
|
||||
Bot.ExchangeCurrencyPairManager.update(exchName,
|
||||
if bot.Settings.EnableExchangeSyncManager && bot.ExchangeCurrencyPairManager != nil {
|
||||
bot.ExchangeCurrencyPairManager.update(exchName,
|
||||
d.Pair,
|
||||
d.AssetType,
|
||||
SyncItemTicker,
|
||||
@@ -307,7 +311,7 @@ func WebsocketDataHandler(exchName string, data interface{}) error {
|
||||
err := ticker.ProcessTicker(d)
|
||||
printTickerSummary(d, "websocket", err)
|
||||
case stream.KlineData:
|
||||
if Bot.Settings.Verbose {
|
||||
if bot.Settings.Verbose {
|
||||
log.Infof(log.WebsocketMgr, "%s websocket %s %s kline updated %+v",
|
||||
exchName,
|
||||
FormatCurrency(d.Pair),
|
||||
@@ -315,8 +319,8 @@ func WebsocketDataHandler(exchName string, data interface{}) error {
|
||||
d)
|
||||
}
|
||||
case *orderbook.Base:
|
||||
if Bot.Settings.EnableExchangeSyncManager && Bot.ExchangeCurrencyPairManager != nil {
|
||||
Bot.ExchangeCurrencyPairManager.update(exchName,
|
||||
if bot.Settings.EnableExchangeSyncManager && bot.ExchangeCurrencyPairManager != nil {
|
||||
bot.ExchangeCurrencyPairManager.update(exchName,
|
||||
d.Pair,
|
||||
d.AssetType,
|
||||
SyncItemOrderbook,
|
||||
@@ -324,22 +328,22 @@ func WebsocketDataHandler(exchName string, data interface{}) error {
|
||||
}
|
||||
printOrderbookSummary(d, "websocket", nil)
|
||||
case *order.Detail:
|
||||
if !Bot.OrderManager.orderStore.exists(d) {
|
||||
err := Bot.OrderManager.orderStore.Add(d)
|
||||
if !bot.OrderManager.orderStore.exists(d) {
|
||||
err := bot.OrderManager.orderStore.Add(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
od, err := Bot.OrderManager.orderStore.GetByExchangeAndID(d.Exchange, d.ID)
|
||||
od, err := bot.OrderManager.orderStore.GetByExchangeAndID(d.Exchange, d.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
od.UpdateOrderFromDetail(d)
|
||||
}
|
||||
case *order.Cancel:
|
||||
return Bot.OrderManager.Cancel(d)
|
||||
return bot.OrderManager.Cancel(d)
|
||||
case *order.Modify:
|
||||
od, err := Bot.OrderManager.orderStore.GetByExchangeAndID(d.Exchange, d.ID)
|
||||
od, err := bot.OrderManager.orderStore.GetByExchangeAndID(d.Exchange, d.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -349,7 +353,7 @@ func WebsocketDataHandler(exchName string, data interface{}) error {
|
||||
case stream.UnhandledMessageWarning:
|
||||
log.Warn(log.WebsocketMgr, d.Message)
|
||||
default:
|
||||
if Bot.Settings.Verbose {
|
||||
if bot.Settings.Verbose {
|
||||
log.Warnf(log.WebsocketMgr,
|
||||
"%s websocket Unknown type: %+v",
|
||||
exchName,
|
||||
|
||||
@@ -15,33 +15,33 @@ import (
|
||||
|
||||
func TestWebsocketDataHandlerProcess(t *testing.T) {
|
||||
ws := sharedtestvalues.NewTestWebsocket()
|
||||
go WebsocketDataReceiver(ws)
|
||||
go Bot.WebsocketDataReceiver(ws)
|
||||
ws.DataHandler <- "string"
|
||||
time.Sleep(time.Second)
|
||||
close(shutdowner)
|
||||
}
|
||||
|
||||
func TestHandleData(t *testing.T) {
|
||||
OrdersSetup(t)
|
||||
b := OrdersSetup(t)
|
||||
var exchName = "exch"
|
||||
var orderID = "testOrder.Detail"
|
||||
err := WebsocketDataHandler(exchName, errors.New("error"))
|
||||
err := b.WebsocketDataHandler(exchName, errors.New("error"))
|
||||
if err == nil {
|
||||
t.Error("Error not handled correctly")
|
||||
}
|
||||
err = WebsocketDataHandler(exchName, nil)
|
||||
err = b.WebsocketDataHandler(exchName, nil)
|
||||
if err == nil {
|
||||
t.Error("Expected nil data error")
|
||||
}
|
||||
err = WebsocketDataHandler(exchName, stream.FundingData{})
|
||||
err = b.WebsocketDataHandler(exchName, stream.FundingData{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = WebsocketDataHandler(exchName, &ticker.Price{})
|
||||
err = b.WebsocketDataHandler(exchName, &ticker.Price{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = WebsocketDataHandler(exchName, stream.KlineData{})
|
||||
err = b.WebsocketDataHandler(exchName, stream.KlineData{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -51,12 +51,12 @@ func TestHandleData(t *testing.T) {
|
||||
Amount: 1337,
|
||||
Price: 1337,
|
||||
}
|
||||
err = WebsocketDataHandler(exchName, origOrder)
|
||||
err = b.WebsocketDataHandler(exchName, origOrder)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
// Send it again since it exists now
|
||||
err = WebsocketDataHandler(exchName, &order.Detail{
|
||||
err = b.WebsocketDataHandler(exchName, &order.Detail{
|
||||
Exchange: fakePassExchange,
|
||||
ID: orderID,
|
||||
Amount: 1338,
|
||||
@@ -68,7 +68,7 @@ func TestHandleData(t *testing.T) {
|
||||
t.Error("Bad pipeline")
|
||||
}
|
||||
|
||||
err = WebsocketDataHandler(exchName, &order.Modify{
|
||||
err = b.WebsocketDataHandler(exchName, &order.Modify{
|
||||
Exchange: fakePassExchange,
|
||||
ID: orderID,
|
||||
Status: order.Active,
|
||||
@@ -80,7 +80,7 @@ func TestHandleData(t *testing.T) {
|
||||
t.Error("Expected order to be modified to Active")
|
||||
}
|
||||
|
||||
err = WebsocketDataHandler(exchName, &order.Cancel{
|
||||
err = b.WebsocketDataHandler(exchName, &order.Cancel{
|
||||
Exchange: fakePassExchange,
|
||||
ID: orderID,
|
||||
})
|
||||
@@ -91,12 +91,12 @@ func TestHandleData(t *testing.T) {
|
||||
t.Error("Expected order status to be cancelled")
|
||||
}
|
||||
// Send some gibberish
|
||||
err = WebsocketDataHandler(exchName, order.Stop)
|
||||
err = b.WebsocketDataHandler(exchName, order.Stop)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = WebsocketDataHandler(exchName, stream.UnhandledMessageWarning{
|
||||
err = b.WebsocketDataHandler(exchName, stream.UnhandledMessageWarning{
|
||||
Message: "there's an issue here's a tissue"},
|
||||
)
|
||||
if err != nil {
|
||||
@@ -108,7 +108,7 @@ func TestHandleData(t *testing.T) {
|
||||
OrderID: "one",
|
||||
Err: errors.New("lol"),
|
||||
}
|
||||
err = WebsocketDataHandler(exchName, classificationError)
|
||||
err = b.WebsocketDataHandler(exchName, classificationError)
|
||||
if err == nil {
|
||||
t.Error("Expected error")
|
||||
}
|
||||
@@ -116,14 +116,14 @@ func TestHandleData(t *testing.T) {
|
||||
t.Errorf("Problem formatting error. Expected %v Received %v", classificationError.Error(), err.Error())
|
||||
}
|
||||
|
||||
err = WebsocketDataHandler(exchName, &orderbook.Base{
|
||||
err = b.WebsocketDataHandler(exchName, &orderbook.Base{
|
||||
ExchangeName: fakePassExchange,
|
||||
Pair: currency.NewPair(currency.BTC, currency.USD),
|
||||
})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
err = WebsocketDataHandler(exchName, "this is a test string")
|
||||
err = b.WebsocketDataHandler(exchName, "this is a test string")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -529,9 +529,12 @@ func (e *ExchangeCurrencyPairSyncer) Start() {
|
||||
}
|
||||
|
||||
if !ws.IsConnected() && !ws.IsConnecting() {
|
||||
go WebsocketDataReceiver(ws)
|
||||
go Bot.WebsocketDataReceiver(ws)
|
||||
|
||||
err = ws.Connect()
|
||||
if err == nil {
|
||||
err = ws.FlushChannels()
|
||||
}
|
||||
if err != nil {
|
||||
log.Errorf(log.SyncMgr,
|
||||
"%s websocket failed to connect. Err: %s\n",
|
||||
|
||||
Reference in New Issue
Block a user