exchanges/websocket: Allow configuration of orderbook publish period (#805)

* Allow configuration of orderbook publish period

For some applications that import GCT it's more interesting to be
immediately notified of an exchange orderbook update instead of
only getting notified every 10 seconds. This option allows that
to happen while keeping the previous default.

* exchanges: allow configuration of orderbook update period
This commit is contained in:
Luis Rascão
2021-10-20 01:44:24 +01:00
committed by GitHub
parent a4d792f0c5
commit a70224d123
26 changed files with 70 additions and 14 deletions

View File

@@ -31,6 +31,7 @@ func (w *Orderbook) Setup(obBufferLimit int,
sortBufferByUpdateIDs,
updateEntriesByID,
verbose bool,
publishPeriod time.Duration,
exchangeName string,
dataHandler chan interface{}) error {
if exchangeName == "" {
@@ -51,6 +52,7 @@ func (w *Orderbook) Setup(obBufferLimit int,
w.dataHandler = dataHandler
w.ob = make(map[currency.Code]map[currency.Code]map[asset.Item]*orderbookHolder)
w.verbose = verbose
w.publishPeriod = publishPeriod
return nil
}
@@ -127,6 +129,17 @@ func (w *Orderbook) Update(u *Update) error {
}
}
// a nil ticker means that a zero publish period has been requested,
// this means publish now whatever was received with no throttling
if book.ticker == nil {
go func() {
w.dataHandler <- book.ob.Retrieve()
book.ob.Publish()
}()
return nil
}
select {
case <-book.ticker.C:
// Opted to wait for receiver because we are limiting here and the sync
@@ -143,6 +156,7 @@ func (w *Orderbook) Update(u *Update) error {
book.ob.Publish()
}
}
return nil
}
@@ -252,7 +266,11 @@ func (w *Orderbook) LoadSnapshot(book *orderbook.Base) error {
}
depth.AssignOptions(book)
buffer := make([]Update, w.obBufferLimit)
ticker := time.NewTicker(timerDefault)
var ticker *time.Ticker
if w.publishPeriod != 0 {
ticker = time.NewTicker(w.publishPeriod)
}
holder = &orderbookHolder{
ob: depth,
buffer: &buffer,

View File

@@ -712,22 +712,22 @@ func TestGetOrderbook(t *testing.T) {
func TestSetup(t *testing.T) {
t.Parallel()
w := Orderbook{}
err := w.Setup(0, false, false, false, false, true, "", nil)
err := w.Setup(0, false, false, false, false, true, 0, "", nil)
if !errors.Is(err, errUnsetExchangeName) {
t.Fatalf("expected error %v but received %v", errUnsetExchangeName, err)
}
err = w.Setup(0, false, false, false, false, false, "test", nil)
err = w.Setup(0, false, false, false, false, false, 0, "test", nil)
if !errors.Is(err, errUnsetDataHandler) {
t.Fatalf("expected error %v but received %v", errUnsetDataHandler, err)
}
err = w.Setup(0, true, false, false, false, true, "test", make(chan interface{}))
err = w.Setup(0, true, false, false, false, true, 0, "test", make(chan interface{}))
if !errors.Is(err, errIssueBufferEnabledButNoLimit) {
t.Fatalf("expected error %v but received %v", errIssueBufferEnabledButNoLimit, err)
}
err = w.Setup(1337, true, true, true, true, false, "test", make(chan interface{}))
err = w.Setup(1337, true, true, true, true, false, 0, "test", make(chan interface{}))
if err != nil {
t.Fatal(err)
}
@@ -1002,7 +1002,7 @@ func TestUpdateByIDAndAction(t *testing.T) {
func TestFlushOrderbook(t *testing.T) {
t.Parallel()
w := &Orderbook{}
err := w.Setup(5, false, false, false, false, false, "test", make(chan interface{}, 2))
err := w.Setup(5, false, false, false, false, false, 0, "test", make(chan interface{}, 2))
if err != nil {
t.Fatal(err)
}

View File

@@ -9,10 +9,6 @@ import (
"github.com/thrasher-corp/gocryptotrader/exchanges/orderbook"
)
// timerDefault defines the amount of time between alerting the sync manager of
// an update.
var timerDefault = time.Second * 10
// Orderbook defines a local cache of orderbooks for amending, appending
// and deleting changes and updates the main store for a stream
type Orderbook struct {
@@ -25,6 +21,7 @@ type Orderbook struct {
exchangeName string
dataHandler chan interface{}
verbose bool
publishPeriod time.Duration
m sync.Mutex
}