-
Notifications
You must be signed in to change notification settings - Fork 820
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Kraken: Subscription improvements #1358
Conversation
d01a5f9
to
ebed7a1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR. Just some quick nits and then once done I will continue with review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM thanks for making those changes. tACK.
There are two residing issues carried over from master (out of scope).
[ERROR] | ORDER | 06/10/2023 10:51:00 | unsupported asset type
The is due to processing own trades. Could set order.Detail struct with Status: order.Filled to stop it trying to update it.
Also there is noticed that there is a cycling issues when we switch from websocket to rest on orderbooks (💩 coin liquidity issues). I think I might make an update in the future so that we do not switch over if there is an active websocket connection.
[ERROR] | WEBSOCKET | 06/10/2023 10:53:36 | exchange Kraken websocket error - Kraken - unhandled websocket data: Kraken XTZUSDT spot Reason: [orderbook data integrity compromised, rest sync timer lapse with active websocket connection]
66e0e26
to
fa504d0
Compare
Rebased against master. |
518f836
to
b3671a3
Compare
Rebased on master and pulled in the latest changes from the bitfinex PR's websockets improvements. Note: There's a failure on Bitfinex here which is fixed in it's own PR. |
1b1e3c1
to
2814efd
Compare
@shazbert This is ready for review; Please remove the label. Rebased on master already. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good:
Just some errors running instance:
[ERROR] | WEBSOCKET | 10/11/2023 13:02:35 | exchange Kraken websocket error - Kraken - unhandled websocket data: subscription not found: spot ohlc-1 XBT/USD
[ERROR] | WEBSOCKET | 10/11/2023 13:02:35 | exchange Kraken websocket error - Kraken - unhandled websocket data: subscription not found: spot book-1000 XBT/USD
Ah damn it. Okay. On it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for those changes! Just need to fix up the build/lint issues from wsProcessSpread
changes and I'm happy
@gloriousCode Build issue fixed; Ready for you |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tACK! Thanks for making those changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DM'd a maybe issue.
This should not happen in TestMain just because it's a requirement for most tests. It should just be a non-parallel early test. That allows unit tests to run quickly without calling it, and allows proper clear failures
Having SeedAssets in Setup is cruel and unusual because it calls the API. Most other interactive data seeding happens in Start. This made it so that fixing and creating unit tests for Kraken was painfully slow, particularly on flaky internet.
* Use Websocket subscriptionChannels instead of local slice * Remove ChannelID - Deprecated in docs * Simplify ping handlers and hardcodes message * Add Depth as configurable orderbook channel param * Simplify auth/non-auth channel updates * Add configurable Book depth * Add configurable Candle timeframes
* Also fixes some, but not all, of the auth and WS tests to skip without creds and pass when it has them * Couple of Drivebys for good measure to improve tests
We were using the "cancel many" facility of the Kraken api. However since that doesn't actually report errors individually, it seems saner to just multiplex over it. We were going to get N+ responses anyway. Might as well send N+ requests
Retain the .msg field of a go fmt.Errorf .msg field returned by .Error() when wrapping multiple errors. This fixes a situation where a nested stack of errors would lose formatting information, which is often used to supply identifying context. e.g. ``` err = fmt.Errorf("%w `%s`: %w", errParsingField, fieldName, parsingError) errs = common.AppendError(errs, err) ``` This isn't really an issue with our implementation; Calling Unwrap() on a fmt.Errorf() which returns a wrapErrors will lose that formatting. Our issue was that we were using just Unwrap() to bind together our chain-of-custody.
71f3cf5
to
a28851a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice! Great improvements across the board and parallelChanOp is sexy. Tested both unauth and auth functionality. Only some minor nits
assert.Len(t, k.Websocket.GetSubscriptions(), 1, "Should add 1 Subscription") | ||
|
||
subs := k.Websocket.GetSubscriptions() | ||
assert.Len(t, subs, 1, "Should have 1 subscription channel") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert.Len(t, subs, 1, "Should have 1 subscription channel") | |
require.Len(t, subs, 1, "Should have 1 subscription channel") |
Otherwise the next line will panic out of range
assert.Len(t, k.Websocket.GetSubscriptions(), 1, "Should add 1 Subscription") | ||
|
||
subs := k.Websocket.GetSubscriptions() | ||
assert.Len(t, subs, 1, "Should have 1 subscription channel") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert.Len(t, subs, 1, "Should have 1 subscription channel") | |
require.Len(t, subs, 1, "Should have 1 subscription channel") |
Because of the next line
subs := k.Websocket.GetSubscriptions() | ||
assert.Len(t, subs, 4, "Should have correct number of subscriptions") | ||
|
||
err = k.Unsubscribe(subs[:1]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also needs panic protection (TM)
`[8912,{"as":[["0.01300","850.00000000","1690230914.230506"],["0.01400","323483.99590510","1690256356.615823"],["0.01500","100287.34442717","1690219133.193345"],["0.01600","67995.78441017","1690118389.451216"],["0.01700","41776.38397740","1689676303.381189"],["0.01800","11785.76177777","1688631951.812452"],["0.01900","23700.00000000","1686935422.319042"],["0.02000","3941.17000000","1689415829.176481"],["0.02100","16598.69173066","1689420942.541943"],["0.02200","17572.51572836","1689851425.907427"]],"bs":[["0.01200","14220.66466572","1690256540.842831"],["0.01100","160223.61546438","1690256401.072463"],["0.01000","63083.48958963","1690256604.037673"],["0.00900","6750.00000000","1690252470.633938"],["0.00800","213059.49706376","1690256360.386301"],["0.00700","1000.00000000","1689869458.464975"],["0.00600","4000.00000000","1690221333.528698"],["0.00100","245000.00000000","1690051368.753455"]]},"book-10","GST/EUR"]`, | ||
`[8912,{"b":[["0.01000","60583.48958963","1690256620.206768"],["0.01000","63083.48958963","1690256620.206783"]],"c":"69619317"},"book-10","GST/EUR"]`, | ||
} | ||
|
||
func TestWsOrderbookMax10Depth(t *testing.T) { | ||
t.Parallel() | ||
for _, c := range []string{"XDG/USD", "LUNA/EUR", "GST/EUR"} { | ||
p, err := currency.NewPairFromString(c) | ||
assert.NoErrorf(t, err, "NewPairFromString %s should not error", c) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert.NoErrorf(t, err, "NewPairFromString %s should not error", c) | |
require.NoErrorf(t, err, "NewPairFromString %s should not error", c) |
Extremely low p of it occurring, but would make the successful sub untrue
Structure currently means 1 req per channel/pair for Kraken, so we could better handle failures. Currently re-structuring slightly |
Will re-open this fresh. It's too cluttered and different to just force push and pretend nothing happened. |
This should not happen in TestMain just because it's a requirement for
most tests. It should just be a non-parallel early test.
That allows unit tests to run quickly without calling it, and allows
proper clear failures
Having SeedAssets in Setup is cruel and unusual because it calls the
API. Most other interactive data seeding happens in Start.
This made it so that fixing and creating unit tests for Kraken was
painfully slow, particularly on flaky internet.
I went both ways on this N+ times. ChannelID is great, but the bottom line is that it's deprecated, and not available in auth channels. By moving away from it we futureproof, and there's no downside really. Note that with or without
Type of change
How has this been tested