Skip to content

Commit

Permalink
Kraken: Improvements to cancelOrders tracking
Browse files Browse the repository at this point in the history
This just tackles the anonymous type usage, and a few occurrences of pointers not being used efficiently.
Overall the whole pattern needs redoing with a
`SendMessageGatherResponses` in websocket replacing the unencapsulated
map storage we use right now.
For another day ...
  • Loading branch information
gbjk committed Nov 2, 2023
1 parent bbcac7e commit 2814efd
Showing 1 changed file with 24 additions and 30 deletions.
54 changes: 24 additions & 30 deletions exchanges/kraken/kraken_websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,15 @@ var defaultSubscribedChannels = []string{
}
var authenticatedChannels = []string{krakenWsOwnTrades, krakenWsOpenOrders}

var cancelOrdersStatusMutex sync.Mutex
var cancelOrdersStatus = make(map[int64]*struct {
type cancelOrdersStatus struct {
Total int // total count of orders in wsCancelOrders request
Successful int // numbers of Successfully canceled orders in wsCancelOrders request
Unsuccessful int // numbers of Unsuccessfully canceled orders in wsCancelOrders request
Error string // if at least one of requested order return fail, store error here
})
}

var cancelOrdersTrackersMutex sync.Mutex
var cancelOrdersTracker = make(map[int64]*cancelOrdersStatus)

// WsConnect initiates a websocket connection
func (k *Kraken) WsConnect() error {
Expand Down Expand Up @@ -173,23 +175,22 @@ func (k *Kraken) wsReadData(comms chan stream.Response) {
}
}

// awaitForCancelOrderResponses used to wait until all responses will received for appropriate CancelOrder request
// success param = was the response from Kraken successful or not
// isAwaitingCancelOrderResponses adds to the status tracker for a cancelOrders request
// returns true if there are more cancel responses due
func isAwaitingCancelOrderResponses(requestID int64, success bool) bool {
cancelOrdersStatusMutex.Lock()
if stat, ok := cancelOrdersStatus[requestID]; ok {
cancelOrdersTrackersMutex.Lock()
defer cancelOrdersTrackersMutex.Unlock()
if s, ok := cancelOrdersTracker[requestID]; ok {
if success {
cancelOrdersStatus[requestID].Successful++
s.Successful++
} else {
cancelOrdersStatus[requestID].Unsuccessful++
s.Unsuccessful++
}

if stat.Successful+stat.Unsuccessful != stat.Total {
cancelOrdersStatusMutex.Unlock()
if s.Successful+s.Unsuccessful != s.Total {
return true
}
}
cancelOrdersStatusMutex.Unlock()
return false
}

Expand Down Expand Up @@ -256,13 +257,13 @@ func (k *Kraken) wsHandleData(respRaw []byte) error {
success := true
if status.Status == "error" {
success = false
cancelOrdersStatusMutex.Lock()
if _, ok := cancelOrdersStatus[status.RequestID]; ok {
if cancelOrdersStatus[status.RequestID].Error == "" { // save the first error, if any
cancelOrdersStatus[status.RequestID].Error = status.ErrorMessage
cancelOrdersTrackersMutex.Lock()
if s, ok := cancelOrdersTracker[status.RequestID]; ok {
if s.Error == "" { // save the first error, if any
s.Error = status.ErrorMessage
}
}
cancelOrdersStatusMutex.Unlock()
cancelOrdersTrackersMutex.Unlock()
}

if isAwaitingCancelOrderResponses(status.RequestID, success) {
Expand Down Expand Up @@ -1414,28 +1415,21 @@ func (k *Kraken) wsCancelOrders(orderIDs []string) error {
RequestID: id,
}

cancelOrdersStatus[id] = &struct {
Total int
Successful int
Unsuccessful int
Error string
}{
Total: len(orderIDs),
}
cancelOrdersTracker[id] = &cancelOrdersStatus{Total: len(orderIDs)}

defer delete(cancelOrdersStatus, id)
defer delete(cancelOrdersTracker, id)

_, err := k.Websocket.AuthConn.SendMessageReturnResponse(id, request)
if err != nil {
return err
}

successful := cancelOrdersStatus[id].Successful
successful := cancelOrdersTracker[id].Successful

if cancelOrdersStatus[id].Error != "" || len(orderIDs) != successful { // strange Kraken logic ...
if cancelOrdersTracker[id].Error != "" || len(orderIDs) != successful { // strange Kraken logic ...
var reason string
if cancelOrdersStatus[id].Error != "" {
reason = fmt.Sprintf(" Reason: %s", cancelOrdersStatus[id].Error)
if cancelOrdersTracker[id].Error != "" {
reason = fmt.Sprintf(" Reason: %s", cancelOrdersTracker[id].Error)
}
return fmt.Errorf("%s cancelled %d out of %d orders.%s",
k.Name, successful, len(orderIDs), reason)
Expand Down

0 comments on commit 2814efd

Please sign in to comment.