Skip to content
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

bybit: enable multiconnection handling across websocket endpoints #1670

Open
wants to merge 168 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
168 commits
Select commit Hold shift + click to select a range
64c24ab
gateio: Add multi asset websocket support WIP.
Jul 14, 2024
f509399
meow
Jul 14, 2024
feed04e
Add tests and shenanigans
Jul 15, 2024
31a26c0
integrate flushing and for enabling/disabling pairs from rpc shenanigans
Jul 15, 2024
e1f2f7a
some changes
Jul 15, 2024
76524cc
linter: fixes strikes again.
Jul 15, 2024
640e82e
Change name ConnectionAssociation -> ConnectionCandidate for better c…
Jul 15, 2024
3a0440d
Add subscription tests (state functional)
Jul 16, 2024
c7d2b62
glorious:nits + proxy handling
Jul 16, 2024
fc281ee
Spelling
Jul 16, 2024
eaa44ba
linter: fixerino
Jul 16, 2024
a8debf9
instead of nil, dont do nil.
Jul 16, 2024
16b0e22
clean up nils
Jul 16, 2024
32252b2
cya nils
Jul 16, 2024
7c5d9c3
don't need to set URL or check if its running
Jul 17, 2024
2f93b64
stream match update
Jul 17, 2024
dd94e4e
update tests
Jul 17, 2024
ca597f3
linter: fix
Jul 17, 2024
2e0f0ae
glorious: nits + handle context cancellations
Jul 18, 2024
2d2f872
stop ping handler routine leak
Jul 19, 2024
39191c8
* Fix bug where reader routine on error that is not a disconnection e…
Jul 19, 2024
f1c3895
Allow rollback on connect on any error across all connections
Jul 19, 2024
09bff6c
fix shadow jutsu
Jul 19, 2024
e66c9be
glorious/gk: nitters - adds in ws mock server
Jul 22, 2024
03de669
linter: fix
Jul 22, 2024
eddb58b
Merge branch 'master' into gateio_ws
Jul 23, 2024
8159b05
fix deadlock on connection as the previous channel had no reader and …
Jul 24, 2024
4f0b42f
Merge branch 'master' into gateio_ws
Jul 24, 2024
2af934e
Merge branch 'master' into stream_match
Jul 24, 2024
0e3bb31
glorious: whooops
Jul 24, 2024
f98c3aa
gk: nits
Jul 24, 2024
d89a46a
Leak issue and edge case
Jul 25, 2024
8281b88
Websocket: Add SendMessageReturnResponses
gbjk Apr 8, 2024
a38a1d1
whooooooopsie
Jul 25, 2024
77ef366
gk: nitssssss
Jul 26, 2024
6341ccf
Update exchanges/stream/stream_match.go
shazbert Jul 26, 2024
c0d1d43
Update exchanges/stream/stream_match_test.go
shazbert Jul 26, 2024
9e57e65
linter: appease the linter gods
Jul 26, 2024
51b9f17
gk: nits
Jul 26, 2024
6376a12
gk: drain brain
Jul 26, 2024
f7adad2
started
Jul 28, 2024
9905686
more changes before merge match pr
Jul 31, 2024
d275e39
Merge branch 'master' into stream_match
Jul 31, 2024
8a64da1
Merge branch 'stream_match' into ws_outbound_req
Jul 31, 2024
9bb6ef4
gateio: still building out
Jul 31, 2024
3f3da46
gateio: finish spot
Jul 31, 2024
6b9c4ad
fix up tests in gateio
Jul 31, 2024
f7af44c
Add tests for stream package
Jul 31, 2024
3ed912b
rm unused field
Jul 31, 2024
ee8a35c
glorious: nits
Aug 1, 2024
ec33bd3
Merge branch 'stream_match' into ws_outbound_req
Aug 1, 2024
cc97528
rn files, specifically set function names to asset and offload routin…
Aug 3, 2024
66a8778
linter: fix
Aug 6, 2024
f7ae6b0
Add futures websocket request support
Aug 6, 2024
4d5d681
gateio: integrate with IBOTExchange (cherry pick my nose)
Aug 7, 2024
3969969
linter: fix
Aug 7, 2024
431c047
glorious: nits
Aug 15, 2024
7110e88
add counter and update gateio
Aug 16, 2024
67bb87d
Merge branch 'common_counter' into ws_outbound_req
Aug 16, 2024
b70296c
fix collision issue
Aug 16, 2024
aa3b49f
Merge branch 'ws_outbound_req' into ws_oubtound_req_futures
Aug 16, 2024
d5bbd10
Merge branch 'master' into gateio_ws
Aug 19, 2024
d2f7c2e
Merge branch 'master' into gateio_ws
Aug 23, 2024
16d88cf
Merge branch 'master' into gateio_ws
Aug 24, 2024
9026bc8
Merge branch 'gateio_ws' into ws_outbound_req
Aug 24, 2024
9e860cf
Merge branch 'ws_outbound_req' into ws_oubtound_req_futures
Aug 24, 2024
0402bc7
Update exchanges/stream/websocket.go
shazbert Aug 30, 2024
0dfda95
glorious: nits
Aug 30, 2024
c58834e
add tests
Aug 30, 2024
d29893b
linter: fix
Aug 30, 2024
79e0eeb
Merge branch 'master' into gateio_ws
Aug 30, 2024
4f7bcd9
Merge branch 'master' into gateio_ws
Sep 2, 2024
45ff199
After merge
Sep 2, 2024
06acaac
Add error connection info
Sep 2, 2024
aa87e83
Merge branch 'gateio_ws' into ws_outbound_req
Sep 4, 2024
cf2e8d8
upgrade to upstream merge
Sep 5, 2024
e9d50e4
Merge branch 'ws_outbound_req' into ws_oubtound_req_futures
Sep 5, 2024
af986da
Fix edge case where it does not reconnect made by an already closed c…
Sep 9, 2024
1171278
stream coverage
Sep 12, 2024
4be6214
glorious: nits
Sep 12, 2024
a068ddb
Merge branch 'master' into gateio_ws
Sep 12, 2024
81cba36
glorious: nits removed asset error handling in stream package
Sep 12, 2024
bdc6954
linter: fix
Sep 13, 2024
3fe44ca
rm block
Sep 13, 2024
818584f
Add basic readme
Sep 13, 2024
289ac71
Merge branch 'master' into gateio_ws
Sep 13, 2024
dee32a4
Merge branch 'master' into gateio_ws
Sep 13, 2024
7063311
Merge branch 'master' into gateio_ws
Sep 16, 2024
0709ba3
fix asset enabled flush cycle for multi connection
Sep 16, 2024
b877b38
spella: fix
Sep 16, 2024
f7d1ec8
linter: fix
Sep 18, 2024
818432d
Merge branch 'master' into gateio_ws
Sep 18, 2024
bdc7afb
Add glorious suggestions, fix some race thing
Sep 19, 2024
3d6541e
reinstate name before any routine gets spawned
Sep 19, 2024
33c4128
stop on error in mock tests
Sep 19, 2024
ea25763
glorious: nits
Sep 19, 2024
f15374a
Merge branch 'gateio_ws' into ws_outbound_req
Sep 22, 2024
ce00326
Merge branch 'ws_outbound_req' into ws_oubtound_req_futures
Sep 22, 2024
262c6ef
Set correct price
Sep 22, 2024
ae92cd2
glorious: nits found in CI build
Sep 24, 2024
c49a75c
Add test for drain, bumped wait times as there seems to be something …
Sep 24, 2024
5551d54
mutex across shutdown and connect for protection
Sep 24, 2024
99c3c7b
lint: fix
Sep 24, 2024
f56cb78
test time withoffset, reinstate stop
Sep 24, 2024
b4bc7e2
fix whoops
Sep 24, 2024
ce4a5ce
const trafficCheckInterval; rm testmain
Sep 24, 2024
a745992
y
Sep 24, 2024
086fcc3
fix lint
Sep 24, 2024
a64e842
bump time check window
Sep 24, 2024
9e53313
stream: fix intermittant test failures while testing routines and rem…
Sep 25, 2024
10230b0
spells
Sep 25, 2024
4e02c4a
cant do what I did
Sep 25, 2024
7be80a0
protect race due to routine.
Sep 25, 2024
b51cf2f
update testURL
Sep 25, 2024
ff7ae03
use mock websocket connection instead of test URL's
Sep 25, 2024
1040153
linter: fix
Sep 25, 2024
f529bd2
remove url because its throwing errors on CI builds
Sep 25, 2024
5d0a7f7
connections drop all the time, don't need to worry about not being ab…
Sep 25, 2024
56cb431
remove another superfluous url thats not really set up for this
Sep 25, 2024
ca4999e
spawn overwatch routine when there is no errors, inline checker inste…
Sep 25, 2024
4240a0a
linter: fixerino uperino
Sep 26, 2024
c3a5bab
fix ID bug, why I do this, I don't know.
Sep 26, 2024
8d6febc
glorious: panix
Sep 30, 2024
3df82ef
Merge branch 'master' into gateio_ws
Oct 1, 2024
7ff07d1
Merge branch 'master' into gateio_ws
Oct 1, 2024
3a24640
linter: things
Oct 1, 2024
1eef208
whoops
Oct 1, 2024
261b577
Merge branch 'master' into gateio_ws
Oct 1, 2024
dbd8acd
Merge branch 'gateio_ws' into ws_outbound_req
Oct 2, 2024
b528407
dont need to make consecutive Unix() calls
Oct 2, 2024
0c5dbbf
Merge branch 'ws_outbound_req' into ws_oubtound_req_futures
Oct 2, 2024
ee1cb94
websocket: fix potential panic on error and no responses and adding w…
Oct 3, 2024
6e46e74
Merge branch 'ws_outbound_req' into ws_oubtound_req_futures
Oct 3, 2024
3bf8722
bybit: enable multiconnection handling across websocket endpoints
Oct 9, 2024
b5e75bc
rm debug lines
Oct 9, 2024
9cdac76
Merge branch 'master' into ws_outbound_req
Oct 10, 2024
e5accaf
rm json parser and handle in json package instead
Oct 10, 2024
30ed109
Merge branch 'ws_outbound_req' into ws_oubtound_req_futures
Oct 10, 2024
20d7737
in favour of json package unmarshalling
Oct 10, 2024
777ebe3
Merge branch 'ws_oubtound_req_futures' into bybit_multi_out
Oct 10, 2024
15e91f6
fix processing issues with tickers
Oct 18, 2024
6792d9b
Merge branch 'master' into bybit_multi_out
Oct 18, 2024
f124390
Merge branch 'master' into ws_outbound_req
Oct 23, 2024
d950b24
linter: fix
Oct 23, 2024
31339ed
linter: fix again
Oct 23, 2024
622c748
* change field name OutboundRequestSignature to WrapperDefinedConnect…
Oct 23, 2024
b71d3c0
spells and magic and wands
Oct 23, 2024
c7d8503
Merge branch 'ws_outbound_req' into ws_oubtound_req_futures
Oct 23, 2024
28a2340
Merge branch 'ws_oubtound_req_futures' into bybit_multi_out
Oct 23, 2024
868c711
merge: fixup
Oct 23, 2024
03674c6
linter: fix
Oct 23, 2024
290609b
spelling: fix
Oct 23, 2024
2bd207f
glorious: nits
Oct 25, 2024
511c78b
comparable check for signature
Oct 25, 2024
0a196b8
mv err var
Oct 25, 2024
f5ffe9f
Merge branch 'master' into ws_outbound_req
Nov 5, 2024
d3343a7
glorious: nits and stuff
Nov 5, 2024
800665c
Merge branch 'ws_outbound_req' into ws_oubtound_req_futures
Nov 5, 2024
f422a9f
Merge branch 'ws_oubtound_req_futures' into bybit_multi_out
Nov 6, 2024
56f483f
Merge branch 'master' into ws_outbound_req
Nov 7, 2024
2872e05
attempt to fix race
Nov 7, 2024
50e7253
Merge branch 'master' into ws_outbound_req
Nov 11, 2024
fae9556
Merge branch 'ws_outbound_req' into ws_oubtound_req_futures
Nov 11, 2024
14eb928
Merge branch 'ws_oubtound_req_futures' into bybit_multi_out
Nov 11, 2024
f8affe0
linter: fix
Nov 12, 2024
4306492
fix tests
Nov 12, 2024
8a47e0e
types/time: strict usage of time type for usage with unix timestamps
Nov 12, 2024
2c8000e
fix tests etc
Nov 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/ADD_NEW_EXCHANGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1176,7 +1176,7 @@ Please test all `pair` commands to disable and enable different assets types to
- `get` to ensure correct enabled and disabled pairs for a supported asset type.
- `disableasset` to ensure disabling of entire asset class and associated unsubscriptions.
- `enableasset` to ensure correct enabling of entire asset class and associated subscriptions.
- `disable` to ensure correct disabling of pair(s) and and associated unsubscriptions.
- `disable` to ensure correct disabling of pair(s) and associated unsubscriptions.
- `enable` to ensure correct enabling of pair(s) and associated subscriptions.
- `enableall` to ensure correct enabling of all pairs for an asset type and associated subscriptions.
- `disableall` to ensure correct disabling of all pairs for an asset type and associated unsubscriptions.
Expand Down
45 changes: 12 additions & 33 deletions engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -791,17 +791,10 @@ func (bot *Engine) LoadExchange(name string) error {

localWG.Wait()
if !bot.Settings.EnableExchangeHTTPRateLimiter {
gctlog.Warnf(gctlog.ExchangeSys,
"Loaded exchange %s rate limiting has been turned off.\n",
exch.GetName(),
)
gctlog.Warnf(gctlog.ExchangeSys, "Loaded exchange %s rate limiting has been turned off.\n", exch.GetName())
err = exch.DisableRateLimiter()
if err != nil {
gctlog.Errorf(gctlog.ExchangeSys,
"Loaded exchange %s rate limiting cannot be turned off: %s.\n",
exch.GetName(),
err,
)
gctlog.Errorf(gctlog.ExchangeSys, "Loaded exchange %s rate limiting cannot be turned off: %s.\n", exch.GetName(), err)
}
}

Expand All @@ -820,29 +813,18 @@ func (bot *Engine) LoadExchange(name string) error {
return err
}

base := exch.GetBase()
if base.API.AuthenticatedSupport ||
base.API.AuthenticatedWebsocketSupport {
assetTypes := base.GetAssetTypes(false)
var useAsset asset.Item
for a := range assetTypes {
err = base.CurrencyPairs.IsAssetEnabled(assetTypes[a])
if err != nil {
continue
}
useAsset = assetTypes[a]
break
}
err = exch.ValidateAPICredentials(context.TODO(), useAsset)
b := exch.GetBase()
if b.API.AuthenticatedSupport || b.API.AuthenticatedWebsocketSupport {
err = exch.ValidateAPICredentials(context.TODO(), asset.Spot)
if err != nil {
gctlog.Warnf(gctlog.ExchangeSys,
"%s: Cannot validate credentials, authenticated support has been disabled, Error: %s\n",
base.Name,
err)
base.API.AuthenticatedSupport = false
base.API.AuthenticatedWebsocketSupport = false
gctlog.Warnf(gctlog.ExchangeSys, "%s: Cannot validate credentials, authenticated support has been disabled, Error: %s", b.Name, err)
b.API.AuthenticatedSupport = false
b.API.AuthenticatedWebsocketSupport = false
exchCfg.API.AuthenticatedSupport = false
exchCfg.API.AuthenticatedWebsocketSupport = false
if b.Websocket != nil {
b.Websocket.SetCanUseAuthenticatedEndpoints(false)
}
}
}

Expand All @@ -854,10 +836,7 @@ func (bot *Engine) dryRunParamInteraction(param string) {
return
}

gctlog.Warnf(gctlog.Global,
"Command line argument '-%s' induces dry run mode."+
" Set -dryrun=false if you wish to override this.",
param)
gctlog.Warnf(gctlog.Global, "Command line argument '-%s' induces dry run mode. Set -dryrun=false if you wish to override this.", param)

if !bot.Settings.EnableDryRun {
bot.Settings.EnableDryRun = true
Expand Down
2 changes: 1 addition & 1 deletion exchanges/bybit/bybit.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ import (
// Bybit is the overarching type across this package
type Bybit struct {
exchange.Base

// AccountType holds information about whether the account to which the api key belongs is a unified margin account or not.
// 0: unified, and 1: for normal account
AccountType uint8
Counter common.Counter
}

const (
Expand Down
70 changes: 16 additions & 54 deletions exchanges/bybit/bybit_inverse_websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,81 +2,43 @@ package bybit

import (
"context"
"net/http"
"errors"

"github.com/gorilla/websocket"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
)

// WsInverseConnect connects to inverse websocket feed
func (by *Bybit) WsInverseConnect() error {
if !by.Websocket.IsEnabled() || !by.IsEnabled() || !by.IsAssetWebsocketSupported(asset.CoinMarginedFutures) {
return stream.ErrWebsocketNotEnabled
}
by.Websocket.Conn.SetURL(inversePublic)
var dialer websocket.Dialer
err := by.Websocket.Conn.Dial(&dialer, http.Header{})
if err != nil {
return err
}
by.Websocket.Conn.SetupPingHandler(request.Unset, stream.PingHandler{
MessageType: websocket.TextMessage,
Message: []byte(`{"op": "ping"}`),
Delay: bybitWebsocketTimer,
})

by.Websocket.Wg.Add(1)
go by.wsReadData(asset.CoinMarginedFutures, by.Websocket.Conn)
return nil
}

// GenerateInverseDefaultSubscriptions generates default subscription
func (by *Bybit) GenerateInverseDefaultSubscriptions() (subscription.List, error) {
var subscriptions subscription.List
var channels = []string{chanOrderbook, chanPublicTrade, chanPublicTicker}
pairs, err := by.GetEnabledPairs(asset.CoinMarginedFutures)
if err != nil {
if errors.Is(err, asset.ErrNotEnabled) {
return nil, nil
}
return nil, err
}

var subscriptions subscription.List
for z := range pairs {
for x := range channels {
subscriptions = append(subscriptions,
&subscription.Subscription{
Channel: channels[x],
Pairs: currency.Pairs{pairs[z]},
Asset: asset.CoinMarginedFutures,
})
for _, channel := range []string{chanOrderbook, chanPublicTrade, chanPublicTicker} {
subscriptions = append(subscriptions, &subscription.Subscription{
Channel: channel,
Pairs: currency.Pairs{pairs[z]},
Asset: asset.CoinMarginedFutures,
})
}
}
return subscriptions, nil
}

// InverseSubscribe sends a subscription message to linear public channels.
func (by *Bybit) InverseSubscribe(channelSubscriptions subscription.List) error {
return by.handleInversePayloadSubscription("subscribe", channelSubscriptions)
func (by *Bybit) InverseSubscribe(ctx context.Context, conn stream.Connection, channelSubscriptions subscription.List) error {
return by.handleSubscriptionNonTemplate(ctx, conn, asset.CoinMarginedFutures, "subscribe", channelSubscriptions)
}

// InverseUnsubscribe sends an unsubscription messages through linear public channels.
func (by *Bybit) InverseUnsubscribe(channelSubscriptions subscription.List) error {
return by.handleInversePayloadSubscription("unsubscribe", channelSubscriptions)
}

func (by *Bybit) handleInversePayloadSubscription(operation string, channelSubscriptions subscription.List) error {
payloads, err := by.handleSubscriptions(operation, channelSubscriptions)
if err != nil {
return err
}
for a := range payloads {
// The options connection does not send the subscription request id back with the subscription notification payload
// therefore the code doesn't wait for the response to check whether the subscription is successful or not.
err = by.Websocket.Conn.SendJSONMessage(context.TODO(), request.Unset, payloads[a])
if err != nil {
return err
}
}
return nil
func (by *Bybit) InverseUnsubscribe(ctx context.Context, conn stream.Connection, channelSubscriptions subscription.List) error {
return by.handleSubscriptionNonTemplate(ctx, conn, asset.CoinMarginedFutures, "unsubscribe", channelSubscriptions)
}
92 changes: 18 additions & 74 deletions exchanges/bybit/bybit_linear_websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,99 +2,43 @@ package bybit

import (
"context"
"net/http"
"errors"

"github.com/gorilla/websocket"
"github.com/thrasher-corp/gocryptotrader/currency"
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
"github.com/thrasher-corp/gocryptotrader/exchanges/request"
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
"github.com/thrasher-corp/gocryptotrader/exchanges/subscription"
)

// WsLinearConnect connects to linear a websocket feed
func (by *Bybit) WsLinearConnect() error {
if !by.Websocket.IsEnabled() || !by.IsEnabled() || !by.IsAssetWebsocketSupported(asset.LinearContract) {
return stream.ErrWebsocketNotEnabled
}
by.Websocket.Conn.SetURL(linearPublic)
var dialer websocket.Dialer
err := by.Websocket.Conn.Dial(&dialer, http.Header{})
// GenerateLinearDefaultSubscriptions generates default subscription
func (by *Bybit) GenerateLinearDefaultSubscriptions(a asset.Item) (subscription.List, error) {
pairs, err := by.GetEnabledPairs(a)
if err != nil {
return err
}
by.Websocket.Conn.SetupPingHandler(request.Unset, stream.PingHandler{
MessageType: websocket.TextMessage,
Message: []byte(`{"op": "ping"}`),
Delay: bybitWebsocketTimer,
})

by.Websocket.Wg.Add(1)
go by.wsReadData(asset.LinearContract, by.Websocket.Conn)
if by.IsWebsocketAuthenticationSupported() {
err = by.WsAuth(context.TODO())
if err != nil {
by.Websocket.DataHandler <- err
by.Websocket.SetCanUseAuthenticatedEndpoints(false)
if errors.Is(err, asset.ErrNotEnabled) {
return nil, nil
}
return nil, err
}
return nil
}

// GenerateLinearDefaultSubscriptions generates default subscription
func (by *Bybit) GenerateLinearDefaultSubscriptions() (subscription.List, error) {
var subscriptions subscription.List
var channels = []string{chanOrderbook, chanPublicTrade, chanPublicTicker}
pairs, err := by.GetEnabledPairs(asset.USDTMarginedFutures)
if err != nil {
return nil, err
}
linearPairMap := map[asset.Item]currency.Pairs{
asset.USDTMarginedFutures: pairs,
}
usdcPairs, err := by.GetEnabledPairs(asset.USDCMarginedFutures)
if err != nil {
return nil, err
}
linearPairMap[asset.USDCMarginedFutures] = usdcPairs
pairs = append(pairs, usdcPairs...)
for a := range linearPairMap {
for p := range linearPairMap[a] {
for x := range channels {
subscriptions = append(subscriptions,
&subscription.Subscription{
Channel: channels[x],
Pairs: currency.Pairs{pairs[p]},
Asset: a,
})
}
for _, pair := range pairs {
for _, channel := range []string{chanOrderbook, chanPublicTrade, chanPublicTicker} {
subscriptions = append(subscriptions, &subscription.Subscription{
Channel: channel,
Pairs: currency.Pairs{pair},
Asset: a,
})
}
}
return subscriptions, nil
}

// LinearSubscribe sends a subscription message to linear public channels.
func (by *Bybit) LinearSubscribe(channelSubscriptions subscription.List) error {
return by.handleLinearPayloadSubscription("subscribe", channelSubscriptions)
func (by *Bybit) LinearSubscribe(ctx context.Context, conn stream.Connection, channelSubscriptions subscription.List) error {
return by.handleSubscriptionNonTemplate(ctx, conn, asset.USDTMarginedFutures, "subscribe", channelSubscriptions)
}

// LinearUnsubscribe sends an unsubscription messages through linear public channels.
func (by *Bybit) LinearUnsubscribe(channelSubscriptions subscription.List) error {
return by.handleLinearPayloadSubscription("unsubscribe", channelSubscriptions)
}

func (by *Bybit) handleLinearPayloadSubscription(operation string, channelSubscriptions subscription.List) error {
payloads, err := by.handleSubscriptions(operation, channelSubscriptions)
if err != nil {
return err
}
for a := range payloads {
// The options connection does not send the subscription request id back with the subscription notification payload
// therefore the code doesn't wait for the response to check whether the subscription is successful or not.
err = by.Websocket.Conn.SendJSONMessage(context.TODO(), request.Unset, payloads[a])
if err != nil {
return err
}
}
return nil
func (by *Bybit) LinearUnsubscribe(ctx context.Context, conn stream.Connection, channelSubscriptions subscription.List) error {
return by.handleSubscriptionNonTemplate(ctx, conn, asset.USDTMarginedFutures, "unsubscribe", channelSubscriptions)
}
Loading
Loading