Websocket: Restructure files and types (#1859)

* Websocket: Rename stream package

* Websocket: Rename Websocket to Manager

* Websocket: Replace explicit errs with common.NilGuard

* Websocket: Move websocket_types.go to types.go

* Websocket: Minor field comment and alignment in types

* Webosocket: Rename WebsocketConnection to Connection

* Alphapoint: Make gorilla ws import explicit

Just to avoid confusion with our own packages.

* Websocket: Move stream_match to match

* Websocket: Move websocket_connection to connection

* Websocket: Move websocket.go to manager.go

* Websocket: Break out all subscription methods into subscriptions.go

* Websocket: Move connection type into its file

* Websocket: Remove PositionUpdated

Type is not used anywhere

* Kraken: Use local constant for pong

Was the only use of websocket.Pong and doesn't really feel right to
represent kraken's api resp in one of our packages

* Websocket: Move connection sub-types to connection package

* Websocket: Move manager types into manager

* Websocket: Move ConnectionWrapper into manager

* Websocket: Move websocket_test to manager_test

* Websocket: Privatise connectionWrapper

* Websocket: Remaining types into types.go

These really belong somewhere else mostly, but this will do for now

* Websocket: Tidy up connection method vars

* Gofumpt: Moving package imports around

* Websocket: Rename errDuplicateConnectionSetup

* Websocket: Fix duplicate import of gws

* Websocket: Fix gofumpt -extra

* Websocket: Standardise import of gws across other pkgs

* Kraken: Remove unused sub conf consts

These were replaced by the generic Levels and Depth fields on all subs

* Websocket: Privitise ConnectioWrapper fields

* Websocket: inline single use var WebsocketNotAuthenticatedUsingRest

* Websocket: Move documentation to template

* Bithumb: Assertify TestWsHandleData
This commit is contained in:
Gareth Kirwan
2025-04-10 08:25:02 +02:00
committed by GitHub
parent 676b2e0367
commit b4e45e9a1b
119 changed files with 3169 additions and 3056 deletions

View File

@@ -13,7 +13,7 @@ import (
"time"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
gws "github.com/gorilla/websocket"
"github.com/thrasher-corp/gocryptotrader/common"
"github.com/thrasher-corp/gocryptotrader/common/crypto"
"github.com/thrasher-corp/gocryptotrader/config"
@@ -489,13 +489,13 @@ func (c *websocketClient) read() {
for {
msgType, message, err := c.Conn.ReadMessage()
if err != nil {
if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) {
if gws.IsUnexpectedCloseError(err, gws.CloseGoingAway, gws.CloseAbnormalClosure) {
log.Errorf(log.APIServerMgr, "websocket: client disconnected, err: %s\n", err)
}
break
}
if msgType == websocket.TextMessage {
if msgType == gws.TextMessage {
var evt WebsocketEvent
err := json.Unmarshal(message, &evt)
if err != nil {
@@ -551,7 +551,7 @@ func (c *websocketClient) write() {
for {
message, ok := <-c.Send
if !ok {
err := c.Conn.WriteMessage(websocket.CloseMessage, []byte{})
err := c.Conn.WriteMessage(gws.CloseMessage, []byte{})
if err != nil {
log.Errorln(log.APIServerMgr, err)
}
@@ -559,7 +559,7 @@ func (c *websocketClient) write() {
return
}
w, err := c.Conn.NextWriter(websocket.TextMessage)
w, err := c.Conn.NextWriter(gws.TextMessage)
if err != nil {
log.Errorf(log.APIServerMgr, "websocket: failed to create new io.writeCloser: %s\n", err)
return
@@ -628,7 +628,7 @@ func (m *apiServerManager) WebsocketClientHandler(w http.ResponseWriter, r *http
return
}
upgrader := websocket.Upgrader{
upgrader := gws.Upgrader{
WriteBufferSize: 1024,
ReadBufferSize: 1024,
}

View File

@@ -6,7 +6,7 @@ import (
"sync"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
gws "github.com/gorilla/websocket"
"github.com/thrasher-corp/gocryptotrader/config"
"github.com/thrasher-corp/gocryptotrader/exchanges/account"
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
@@ -62,7 +62,7 @@ type apiServerManager struct {
// websocketClient stores information related to the websocket client
type websocketClient struct {
Hub *websocketHub
Conn *websocket.Conn
Conn *gws.Conn
Authenticated bool
authFailures int
Send chan []byte

View File

@@ -1,4 +1,4 @@
# GoCryptoTrader package Communication manager
# GoCryptoTrader package Communication Manager
<img src="/common/gctlogo.png?raw=true" width="350px" height="350px" hspace="70">
@@ -18,7 +18,7 @@ You can track ideas, planned features and what's in progress on our [GoCryptoTra
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTc5ZDE1ZTNiOGM3ZGMyMmY1NTAxYWZhODE0MWM5N2JlZDk1NDU0YTViYzk4NTk3OTRiMDQzNGQ1YTc4YmRlMTk)
## Current Features for Communication manager
## Current Features for Communication Manager
+ The communication manager subsystem is used to push events raised in GoCryptoTrader to any enabled communication system such as a Slack server
+ In order to modify the behaviour of the communication manager subsystem, you can edit the following inside your config file under `communications`:

View File

@@ -1,4 +1,4 @@
# GoCryptoTrader package Connection manager
# GoCryptoTrader package Connection Manager
<img src="/common/gctlogo.png?raw=true" width="350px" height="350px" hspace="70">
@@ -18,7 +18,7 @@ You can track ideas, planned features and what's in progress on our [GoCryptoTra
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTc5ZDE1ZTNiOGM3ZGMyMmY1NTAxYWZhODE0MWM5N2JlZDk1NDU0YTViYzk4NTk3OTRiMDQzNGQ1YTc4YmRlMTk)
## Current Features for Connection manager
## Current Features for Connection Manager
+ The connection manager subsystem is used to periodically check whether the application is connected to the internet and will provide alerts of any changes
+ In order to modify the behaviour of the connection manager subsystem, you can edit the following inside your config file under `connectionMonitor`:

View File

@@ -1,4 +1,4 @@
# GoCryptoTrader package Currency state manager
# GoCryptoTrader package Currency State Manager
<img src="/common/gctlogo.png?raw=true" width="350px" height="350px" hspace="70">
@@ -18,7 +18,7 @@ You can track ideas, planned features and what's in progress on our [GoCryptoTra
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTc5ZDE1ZTNiOGM3ZGMyMmY1NTAxYWZhODE0MWM5N2JlZDk1NDU0YTViYzk4NTk3OTRiMDQzNGQ1YTc4YmRlMTk)
## Current Features for Currency state manager
## Current Features for Currency State Manager
+ The state manager keeps currency states up to date, which include:
* Withdrawal - Determines if the currency is allowed to be withdrawn from the exchange.
* Deposit - Determines if the currency is allowed to be deposited to an exchange.

View File

@@ -1,4 +1,4 @@
# GoCryptoTrader package Database connection
# GoCryptoTrader package Database Connection
<img src="/common/gctlogo.png?raw=true" width="350px" height="350px" hspace="70">
@@ -18,7 +18,7 @@ You can track ideas, planned features and what's in progress on our [GoCryptoTra
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTc5ZDE1ZTNiOGM3ZGMyMmY1NTAxYWZhODE0MWM5N2JlZDk1NDU0YTViYzk4NTk3OTRiMDQzNGQ1YTc4YmRlMTk)
## Current Features for Database connection
## Current Features for Database Connection
+ The database connection manager subsystem is used to periodically check whether the application is connected to the database and will provide alerts of any changes
+ In order to modify the behaviour of the database connection manager subsystem, you can edit the following inside your config file under `database`:

View File

@@ -1,4 +1,4 @@
# GoCryptoTrader package Datahistory manager
# GoCryptoTrader package Datahistory Manager
<img src="/common/gctlogo.png?raw=true" width="350px" height="350px" hspace="70">

View File

@@ -1,4 +1,4 @@
# GoCryptoTrader package Event manager
# GoCryptoTrader package Event Manager
<img src="/common/gctlogo.png?raw=true" width="350px" height="350px" hspace="70">
@@ -18,7 +18,7 @@ You can track ideas, planned features and what's in progress on our [GoCryptoTra
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTc5ZDE1ZTNiOGM3ZGMyMmY1NTAxYWZhODE0MWM5N2JlZDk1NDU0YTViYzk4NTk3OTRiMDQzNGQ1YTc4YmRlMTk)
## Current Features for Event manager
## Current Features for Event Manager
+ The event manager subsystem is used to push events to communication systems such as Slack
+ The only configurable aspects of the event manager are the delays between receiving an event and pushing it and enabling verbose:

View File

@@ -1,4 +1,4 @@
# GoCryptoTrader package Exchange manager
# GoCryptoTrader package Exchange Manager
<img src="/common/gctlogo.png?raw=true" width="350px" height="350px" hspace="70">
@@ -18,7 +18,7 @@ You can track ideas, planned features and what's in progress on our [GoCryptoTra
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTc5ZDE1ZTNiOGM3ZGMyMmY1NTAxYWZhODE0MWM5N2JlZDk1NDU0YTViYzk4NTk3OTRiMDQzNGQ1YTc4YmRlMTk)
## Current Features for Exchange manager
## Current Features for Exchange Manager
+ The exchange manager subsystem is used load and store exchanges so that the engine Bot can use them to track orderbooks, submit orders etc etc
+ The exchange manager itself is not customisable, it is always enabled.
+ The exchange manager by default will load all exchanges that are enabled in your config, however, it will also load exchanges by request via GRPC commands

View File

@@ -1,4 +1,4 @@
# GoCryptoTrader package Ntp manager
# GoCryptoTrader package Ntp Manager
<img src="/common/gctlogo.png?raw=true" width="350px" height="350px" hspace="70">
@@ -18,7 +18,7 @@ You can track ideas, planned features and what's in progress on our [GoCryptoTra
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTc5ZDE1ZTNiOGM3ZGMyMmY1NTAxYWZhODE0MWM5N2JlZDk1NDU0YTViYzk4NTk3OTRiMDQzNGQ1YTc4YmRlMTk)
## Current Features for Ntp manager
## Current Features for Ntp Manager
+ The NTP manager subsystem is used highlight discrepancies between your system time and specified NTP server times
+ It is useful for debugging and understanding why a request to an exchange may be rejected
+ The NTP manager cannot update your system clock, so when it does alert you of issues, you must take it upon yourself to change your system time in the event your requests are being rejected for being too far out of sync

View File

@@ -1,4 +1,4 @@
# GoCryptoTrader package Order manager
# GoCryptoTrader package Order Manager
<img src="/common/gctlogo.png?raw=true" width="350px" height="350px" hspace="70">
@@ -18,7 +18,7 @@ You can track ideas, planned features and what's in progress on our [GoCryptoTra
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTc5ZDE1ZTNiOGM3ZGMyMmY1NTAxYWZhODE0MWM5N2JlZDk1NDU0YTViYzk4NTk3OTRiMDQzNGQ1YTc4YmRlMTk)
## Current Features for Order manager
## Current Features for Order Manager
+ The order manager subsystem stores and monitors all orders from enabled exchanges with API keys and `authenticatedSupport` enabled
+ It can be enabled or disabled via runtime command `-ordermanager=false` and defaults to true
+ All orders placed via GoCryptoTrader will be added to the order manager store

View File

@@ -1,4 +1,4 @@
# GoCryptoTrader package Portfolio manager
# GoCryptoTrader package Portfolio Manager
<img src="/common/gctlogo.png?raw=true" width="350px" height="350px" hspace="70">
@@ -18,7 +18,7 @@ You can track ideas, planned features and what's in progress on our [GoCryptoTra
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTc5ZDE1ZTNiOGM3ZGMyMmY1NTAxYWZhODE0MWM5N2JlZDk1NDU0YTViYzk4NTk3OTRiMDQzNGQ1YTc4YmRlMTk)
## Current Features for Portfolio manager
## Current Features for Portfolio Manager
+ The portfolio manager subsystem is used to synchronise and monitor wallet addresses
+ It can read addresses specified in your config file
+ If you have set API keys for an enabled exchange and enabled `authenticatedSupport`, it will store your exchange addresses

View File

@@ -1,4 +1,4 @@
# GoCryptoTrader package Subsystem types
# GoCryptoTrader package Subsystem Types
<img src="/common/gctlogo.png?raw=true" width="350px" height="350px" hspace="70">
@@ -18,7 +18,7 @@ You can track ideas, planned features and what's in progress on our [GoCryptoTra
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTc5ZDE1ZTNiOGM3ZGMyMmY1NTAxYWZhODE0MWM5N2JlZDk1NDU0YTViYzk4NTk3OTRiMDQzNGQ1YTc4YmRlMTk)
## Current Features for Subsystem types
## Current Features for Subsystem Types
+ Subsystem contains subsystems that are used at run time by an `engine.Engine`, however they can be setup and run individually.
+ Subsystems are designed to be self contained
+ All subsystems have a public `Setup(...) (..., error)` function to return a valid subsystem ready for use

View File

@@ -1,4 +1,4 @@
# GoCryptoTrader package Sync manager
# GoCryptoTrader package Sync Manager
<img src="/common/gctlogo.png?raw=true" width="350px" height="350px" hspace="70">
@@ -18,7 +18,7 @@ You can track ideas, planned features and what's in progress on our [GoCryptoTra
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTc5ZDE1ZTNiOGM3ZGMyMmY1NTAxYWZhODE0MWM5N2JlZDk1NDU0YTViYzk4NTk3OTRiMDQzNGQ1YTc4YmRlMTk)
## Current Features for Sync manager
## Current Features for Sync Manager
+ The currency pair syncer subsystem is used to keep all trades, tickers and orderbooks up to date for all enabled exchange asset currency pairs
+ It can sync data via a websocket connection or REST and will switch between them if there has been no updates
+ In order to modify the behaviour of the currency pair syncer subsystem, you can change runtime parameters as detailed below:

View File

@@ -11,9 +11,9 @@ import (
"github.com/thrasher-corp/gocryptotrader/exchanges/fill"
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
"github.com/thrasher-corp/gocryptotrader/exchanges/trade"
"github.com/thrasher-corp/gocryptotrader/internal/exchange/websocket"
"github.com/thrasher-corp/gocryptotrader/log"
)
@@ -153,7 +153,7 @@ func (m *WebsocketRoutineManager) websocketRoutine() {
// WebsocketDataReceiver handles websocket data coming from a websocket feed
// associated with an exchange
func (m *WebsocketRoutineManager) websocketDataReceiver(ws *stream.Websocket) error {
func (m *WebsocketRoutineManager) websocketDataReceiver(ws *websocket.Manager) error {
if m == nil {
return fmt.Errorf("websocket routine manager %w", ErrNilSubsystem)
}
@@ -200,7 +200,7 @@ func (m *WebsocketRoutineManager) websocketDataHandler(exchName string, data any
log.Infoln(log.WebsocketMgr, d)
case error:
return fmt.Errorf("exchange %s websocket error - %s", exchName, data)
case stream.FundingData:
case websocket.FundingData:
if m.verbose {
log.Infof(log.WebsocketMgr, "%s websocket %s %s funding updated %+v",
exchName,
@@ -244,7 +244,7 @@ func (m *WebsocketRoutineManager) websocketDataHandler(exchName string, data any
}
case order.Detail, ticker.Price, orderbook.Depth:
return errUseAPointer
case stream.KlineData:
case websocket.KlineData:
if m.verbose {
log.Infof(log.WebsocketMgr, "%s websocket %s %s kline updated %+v",
exchName,
@@ -252,7 +252,7 @@ func (m *WebsocketRoutineManager) websocketDataHandler(exchName string, data any
d.AssetType,
d)
}
case []stream.KlineData:
case []websocket.KlineData:
for x := range d {
if m.verbose {
log.Infof(log.WebsocketMgr, "%s websocket %s %s kline updated %+v",
@@ -333,7 +333,7 @@ func (m *WebsocketRoutineManager) websocketDataHandler(exchName string, data any
}
case order.ClassificationError:
return fmt.Errorf("%w %s", d.Err, d.Error())
case stream.UnhandledMessageWarning:
case websocket.UnhandledMessageWarning:
log.Warnln(log.WebsocketMgr, d.Message)
case account.Change:
if m.verbose {

View File

@@ -1,4 +1,4 @@
# GoCryptoTrader package Websocketroutine manager
# GoCryptoTrader package Websocketroutine Manager
<img src="/common/gctlogo.png?raw=true" width="350px" height="350px" hspace="70">
@@ -18,7 +18,7 @@ You can track ideas, planned features and what's in progress on our [GoCryptoTra
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTc5ZDE1ZTNiOGM3ZGMyMmY1NTAxYWZhODE0MWM5N2JlZDk1NDU0YTViYzk4NTk3OTRiMDQzNGQ1YTc4YmRlMTk)
## Current Features for Websocketroutine manager
## Current Features for Websocketroutine Manager
+ The websocket routine manager subsystem is used process websocket data in a unified manner across enabled exchanges with websocket support
+ It can help process orders to the order manager subsystem when it receives new data
+ Logs output of ticker and orderbook updates

View File

@@ -12,8 +12,8 @@ import (
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
"github.com/thrasher-corp/gocryptotrader/internal/exchange/websocket"
)
func TestWebsocketRoutineManagerSetup(t *testing.T) {
@@ -159,7 +159,7 @@ func TestWebsocketRoutineManagerHandleData(t *testing.T) {
if err == nil {
t.Error("Error not handled correctly")
}
err = m.websocketDataHandler(exchName, stream.FundingData{})
err = m.websocketDataHandler(exchName, websocket.FundingData{})
if err != nil {
t.Error(err)
}
@@ -171,7 +171,7 @@ func TestWebsocketRoutineManagerHandleData(t *testing.T) {
if !errors.Is(err, nil) {
t.Errorf("error '%v', expected '%v'", err, nil)
}
err = m.websocketDataHandler(exchName, stream.KlineData{})
err = m.websocketDataHandler(exchName, websocket.KlineData{})
if err != nil {
t.Error(err)
}
@@ -224,10 +224,9 @@ func TestWebsocketRoutineManagerHandleData(t *testing.T) {
t.Error(err)
}
err = m.websocketDataHandler(exchName, stream.UnhandledMessageWarning{
err = m.websocketDataHandler(exchName, websocket.UnhandledMessageWarning{
Message: "there's an issue here's a tissue",
},
)
})
if err != nil {
t.Error(err)
}
@@ -294,7 +293,7 @@ func TestRegisterWebsocketDataHandlerWithFunctionality(t *testing.T) {
t.Fatal("unexpected data handlers registered")
}
mock := stream.NewWebsocket()
mock := websocket.NewManager()
mock.ToRoutine = make(chan any)
m.state = readyState
err = m.websocketDataReceiver(mock)

View File

@@ -1,4 +1,4 @@
# GoCryptoTrader package Withdraw manager
# GoCryptoTrader package Withdraw Manager
<img src="/common/gctlogo.png?raw=true" width="350px" height="350px" hspace="70">
@@ -18,7 +18,7 @@ You can track ideas, planned features and what's in progress on our [GoCryptoTra
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTc5ZDE1ZTNiOGM3ZGMyMmY1NTAxYWZhODE0MWM5N2JlZDk1NDU0YTViYzk4NTk3OTRiMDQzNGQ1YTc4YmRlMTk)
## Current Features for Withdraw manager
## Current Features for Withdraw Manager
+ The withdraw manager subsystem is responsible for the processing of withdrawal requests and submitting them to exchanges
+ The withdraw manager can be interacted with via GRPC commands such as `WithdrawFiatRequest` and `WithdrawCryptoRequest`
+ Supports caching of responses to allow for quick viewing of withdrawal events via GRPC