Orderbook/RPCServer: Fix GetOrderbook/Retrieve race condition (refactored and sped up) (#555)

* Kraken - wsProcessOrderBook, the method was returning wrong bids data

* additional  map check to prevent panic

* linter issue fix

* The RPC method GetOrderbook has a race condition and causes panic - refactored and speed up

* The method Retrieve (package orderbook) now return pointer of a copy of s.Books[exchange][p.Base.Item][p.Quote.Item][a].b

* using extra var to optomize code

* bids and asks slices filling optimisation

Co-authored-by: Vazha Bezhanishvili <vazha.bezhanishvili@elegro.eu>
This commit is contained in:
Vazha
2020-09-18 08:09:41 +03:00
committed by GitHub
parent b9aa2bcc2c
commit 73ac8b90dc
2 changed files with 39 additions and 16 deletions

View File

@@ -140,26 +140,43 @@ func (s *Service) Retrieve(exchange string, p currency.Pair, a asset.Item) (*Bas
exchange = strings.ToLower(exchange)
s.RLock()
defer s.RUnlock()
if s.Books[exchange] == nil {
if _, ok := s.Books[exchange]; !ok {
return nil, fmt.Errorf("no orderbooks for %s exchange", exchange)
}
if s.Books[exchange][p.Base.Item] == nil {
if _, ok := s.Books[exchange][p.Base.Item]; !ok {
return nil, fmt.Errorf("no orderbooks associated with base currency %s",
p.Base)
}
if s.Books[exchange][p.Base.Item][p.Quote.Item] == nil {
if _, ok := s.Books[exchange][p.Base.Item][p.Quote.Item]; !ok {
return nil, fmt.Errorf("no orderbooks associated with quote currency %s",
p.Quote)
}
if s.Books[exchange][p.Base.Item][p.Quote.Item][a] == nil {
var liveOrderBook *Book
var ok bool
if liveOrderBook, ok = s.Books[exchange][p.Base.Item][p.Quote.Item][a]; !ok {
return nil, fmt.Errorf("no orderbooks associated with asset type %s",
a)
}
return s.Books[exchange][p.Base.Item][p.Quote.Item][a].b, nil
localCopyOfAsks := make([]Item, len(s.Books[exchange][p.Base.Item][p.Quote.Item][a].b.Asks))
localCopyOfBids := make([]Item, len(s.Books[exchange][p.Base.Item][p.Quote.Item][a].b.Bids))
copy(localCopyOfBids, liveOrderBook.b.Bids)
copy(localCopyOfAsks, liveOrderBook.b.Asks)
ob := Base{
Pair: liveOrderBook.b.Pair,
Bids: localCopyOfBids,
Asks: localCopyOfAsks,
LastUpdated: liveOrderBook.b.LastUpdated,
LastUpdateID: liveOrderBook.b.LastUpdateID,
AssetType: liveOrderBook.b.AssetType,
ExchangeName: liveOrderBook.b.ExchangeName,
}
return &ob, nil
}
// TotalBidsAmount returns the total amount of bids and the total orderbook