github.com/bitfinexcom/bitfinex-api-go@v0.0.0-20210608095005-9e0b26f200fb/tests/integration/v2/listener.go (about) 1 package tests 2 3 import ( 4 "errors" 5 "log" 6 "time" 7 8 "github.com/bitfinexcom/bitfinex-api-go/pkg/models/balanceinfo" 9 "github.com/bitfinexcom/bitfinex-api-go/pkg/models/fundinginfo" 10 "github.com/bitfinexcom/bitfinex-api-go/pkg/models/margin" 11 "github.com/bitfinexcom/bitfinex-api-go/pkg/models/notification" 12 "github.com/bitfinexcom/bitfinex-api-go/pkg/models/order" 13 "github.com/bitfinexcom/bitfinex-api-go/pkg/models/position" 14 "github.com/bitfinexcom/bitfinex-api-go/pkg/models/ticker" 15 "github.com/bitfinexcom/bitfinex-api-go/pkg/models/tradeexecution" 16 "github.com/bitfinexcom/bitfinex-api-go/pkg/models/tradeexecutionupdate" 17 "github.com/bitfinexcom/bitfinex-api-go/pkg/models/wallet" 18 "github.com/bitfinexcom/bitfinex-api-go/v2/websocket" 19 ) 20 21 type listener struct { 22 infoEvents chan *websocket.InfoEvent 23 authEvents chan *websocket.AuthEvent 24 ticks chan *ticker.Ticker 25 subscriptionEvents chan *websocket.SubscribeEvent 26 unsubscriptionEvents chan *websocket.UnsubscribeEvent 27 walletUpdates chan *wallet.Update 28 balanceUpdates chan *balanceinfo.Update 29 walletSnapshot chan *wallet.Snapshot 30 positionSnapshot chan *position.Snapshot 31 notifications chan *notification.Notification 32 positions chan *position.Update 33 tradeUpdates chan *tradeexecutionupdate.TradeExecutionUpdate 34 tradeExecutions chan *tradeexecution.TradeExecution 35 cancels chan *order.Cancel 36 marginBase chan *margin.InfoBase 37 marginUpdate chan *margin.InfoUpdate 38 funding chan *fundinginfo.FundingInfo 39 orderNew chan *order.New 40 orderUpdate chan *order.Update 41 errors chan error 42 } 43 44 func newListener() *listener { 45 return &listener{ 46 infoEvents: make(chan *websocket.InfoEvent, 10), 47 authEvents: make(chan *websocket.AuthEvent, 10), 48 ticks: make(chan *ticker.Ticker, 10), 49 subscriptionEvents: make(chan *websocket.SubscribeEvent, 10), 50 unsubscriptionEvents: make(chan *websocket.UnsubscribeEvent, 10), 51 walletUpdates: make(chan *wallet.Update, 10), 52 balanceUpdates: make(chan *balanceinfo.Update, 10), 53 walletSnapshot: make(chan *wallet.Snapshot, 10), 54 positionSnapshot: make(chan *position.Snapshot, 10), 55 errors: make(chan error, 10), 56 notifications: make(chan *notification.Notification, 10), 57 positions: make(chan *position.Update, 10), 58 tradeUpdates: make(chan *tradeexecutionupdate.TradeExecutionUpdate, 10), 59 tradeExecutions: make(chan *tradeexecution.TradeExecution, 10), 60 cancels: make(chan *order.Cancel, 10), 61 marginBase: make(chan *margin.InfoBase, 10), 62 marginUpdate: make(chan *margin.InfoUpdate, 10), 63 orderNew: make(chan *order.New, 10), 64 orderUpdate: make(chan *order.Update, 10), 65 funding: make(chan *fundinginfo.FundingInfo, 10), 66 } 67 } 68 69 func (l *listener) nextInfoEvent() (*websocket.InfoEvent, error) { 70 timeout := make(chan bool) 71 go func() { 72 time.Sleep(time.Second * 2) 73 close(timeout) 74 }() 75 select { 76 case ev := <-l.infoEvents: 77 return ev, nil 78 case <-timeout: 79 return nil, errors.New("timed out waiting for InfoEvent") 80 } 81 } 82 83 func (l *listener) nextAuthEvent() (*websocket.AuthEvent, error) { 84 timeout := make(chan bool) 85 go func() { 86 time.Sleep(time.Second * 2) 87 close(timeout) 88 }() 89 select { 90 case ev := <-l.authEvents: 91 return ev, nil 92 case <-timeout: 93 return nil, errors.New("timed out waiting for AuthEvent") 94 } 95 } 96 97 func (l *listener) nextWalletUpdate() (*wallet.Update, error) { 98 timeout := make(chan bool) 99 go func() { 100 time.Sleep(time.Second * 2) 101 close(timeout) 102 }() 103 select { 104 case ev := <-l.walletUpdates: 105 return ev, nil 106 case <-timeout: 107 return nil, errors.New("timed out waiting for WalletUpdate") 108 } 109 } 110 111 func (l *listener) nextBalanceUpdate() (*balanceinfo.Update, error) { 112 timeout := make(chan bool) 113 go func() { 114 time.Sleep(time.Second * 2) 115 close(timeout) 116 }() 117 select { 118 case ev := <-l.balanceUpdates: 119 return ev, nil 120 case <-timeout: 121 return nil, errors.New("timed out waiting for BalanceUpdate") 122 } 123 } 124 125 // func (l *listener) nextWalletSnapshot() (*wallet.Snapshot, error) { 126 // timeout := make(chan bool) 127 // go func() { 128 // time.Sleep(time.Second * 2) 129 // close(timeout) 130 // }() 131 // select { 132 // case ev := <-l.walletSnapshot: 133 // return ev, nil 134 // case <-timeout: 135 // return nil, errors.New("timed out waiting for WalletSnapshot") 136 // } 137 // } 138 139 // func (l *listener) nextPositionSnapshot() (*position.Snapshot, error) { 140 // timeout := make(chan bool) 141 // go func() { 142 // time.Sleep(time.Second * 2) 143 // close(timeout) 144 // }() 145 // select { 146 // case ev := <-l.positionSnapshot: 147 // return ev, nil 148 // case <-timeout: 149 // return nil, errors.New("timed out waiting for PositionSnapshot") 150 // } 151 // } 152 153 func (l *listener) nextSubscriptionEvent() (*websocket.SubscribeEvent, error) { 154 timeout := make(chan bool) 155 go func() { 156 time.Sleep(time.Second * 2) 157 close(timeout) 158 }() 159 select { 160 case ev := <-l.subscriptionEvents: 161 return ev, nil 162 case <-timeout: 163 return nil, errors.New("timed out waiting for SubscribeEvent") 164 } 165 } 166 167 func (l *listener) nextUnsubscriptionEvent() (*websocket.UnsubscribeEvent, error) { 168 timeout := make(chan bool) 169 go func() { 170 time.Sleep(time.Second * 2) 171 close(timeout) 172 }() 173 select { 174 case ev := <-l.unsubscriptionEvents: 175 return ev, nil 176 case <-timeout: 177 return nil, errors.New("timed out waiting for UnsubscribeEvent") 178 } 179 } 180 181 func (l *listener) nextTick() (*ticker.Ticker, error) { 182 timeout := make(chan bool) 183 go func() { 184 time.Sleep(time.Second * 2) 185 close(timeout) 186 }() 187 select { 188 case ev := <-l.ticks: 189 return ev, nil 190 case <-timeout: 191 return nil, errors.New("timed out waiting for Ticker") 192 } 193 } 194 195 // func (l *listener) nextNotification() (*notification.Notification, error) { 196 // timeout := make(chan bool) 197 // go func() { 198 // time.Sleep(time.Second * 2) 199 // close(timeout) 200 // }() 201 // select { 202 // case ev := <-l.notifications: 203 // return ev, nil 204 // case <-timeout: 205 // return nil, errors.New("timed out waiting for Notification") 206 // } 207 // } 208 209 // func (l *listener) nextTradeExecution() (*tradeexecution.TradeExecution, error) { 210 // timeout := make(chan bool) 211 // go func() { 212 // time.Sleep(time.Second * 2) 213 // close(timeout) 214 // }() 215 // select { 216 // case ev := <-l.tradeExecutions: 217 // return ev, nil 218 // case <-timeout: 219 // return nil, errors.New("timed out waiting for TradeExecution") 220 // } 221 // } 222 223 // func (l *listener) nextPositionUpdate() (*position.Update, error) { 224 // timeout := make(chan bool) 225 // go func() { 226 // time.Sleep(time.Second * 2) 227 // close(timeout) 228 // }() 229 // select { 230 // case ev := <-l.positions: 231 // return ev, nil 232 // case <-timeout: 233 // return nil, errors.New("timed out waiting for PositionUpdate") 234 // } 235 // } 236 237 // func (l *listener) nextTradeUpdate() (*tradeexecutionupdate.TradeExecutionUpdate, error) { 238 // timeout := make(chan bool) 239 // go func() { 240 // time.Sleep(time.Second * 2) 241 // close(timeout) 242 // }() 243 // select { 244 // case ev := <-l.tradeUpdates: 245 // return ev, nil 246 // case <-timeout: 247 // return nil, errors.New("timed out waiting for TradeUpdate") 248 // } 249 // } 250 251 // func (l *listener) nextOrderCancel() (*order.Cancel, error) { 252 // timeout := make(chan bool) 253 // go func() { 254 // time.Sleep(time.Second * 2) 255 // close(timeout) 256 // }() 257 // select { 258 // case ev := <-l.cancels: 259 // return ev, nil 260 // case <-timeout: 261 // return nil, errors.New("timed out waiting for OrderCancel") 262 // } 263 // } 264 265 // func (l *listener) nextMarginInfoBase() (*margin.InfoBase, error) { 266 // timeout := make(chan bool) 267 // go func() { 268 // time.Sleep(time.Second * 2) 269 // close(timeout) 270 // }() 271 // select { 272 // case ev := <-l.marginBase: 273 // return ev, nil 274 // case <-timeout: 275 // return nil, errors.New("timed out waiting for MarginInfoBase") 276 // } 277 // } 278 279 // func (l *listener) nextMarginInfoUpdate() (*margin.InfoUpdate, error) { 280 // timeout := make(chan bool) 281 // go func() { 282 // time.Sleep(time.Second * 2) 283 // close(timeout) 284 // }() 285 // select { 286 // case ev := <-l.marginUpdate: 287 // return ev, nil 288 // case <-timeout: 289 // return nil, errors.New("timed out waiting for MarginInfoUpdate") 290 // } 291 // } 292 293 // func (l *listener) nextFundingInfo() (*fundinginfo.FundingInfo, error) { 294 // timeout := make(chan bool) 295 // go func() { 296 // time.Sleep(time.Second * 2) 297 // close(timeout) 298 // }() 299 // select { 300 // case ev := <-l.funding: 301 // return ev, nil 302 // case <-timeout: 303 // return nil, errors.New("timed out waiting for FundingInfo") 304 // } 305 // } 306 307 // func (l *listener) nextOrderNew() (*order.New, error) { 308 // timeout := make(chan bool) 309 // go func() { 310 // time.Sleep(time.Second * 2) 311 // close(timeout) 312 // }() 313 // select { 314 // case ev := <-l.orderNew: 315 // return ev, nil 316 // case <-timeout: 317 // return nil, errors.New("timed out waiting for OrderNew") 318 // } 319 // } 320 321 // func (l *listener) nextOrderUpdate() (*order.Update, error) { 322 // timeout := make(chan bool) 323 // go func() { 324 // time.Sleep(time.Second * 2) 325 // close(timeout) 326 // }() 327 // select { 328 // case ev := <-l.orderUpdate: 329 // return ev, nil 330 // case <-timeout: 331 // return nil, errors.New("timed out waiting for OrderUpdate") 332 // } 333 // } 334 335 // strongly types messages and places them into a channel 336 func (l *listener) run(ch <-chan interface{}) { 337 go func() { 338 // nolint:megacheck 339 for { 340 select { 341 case msg := <-ch: 342 if msg == nil { 343 return 344 } 345 // remove threading guarantees when mulitplexing into channels 346 log.Printf("[DEBUG] WsService -> WsClient: %#v", msg) 347 switch msg.(type) { 348 case error: 349 l.errors <- msg.(error) 350 case *ticker.Ticker: 351 l.ticks <- msg.(*ticker.Ticker) 352 case *websocket.InfoEvent: 353 l.infoEvents <- msg.(*websocket.InfoEvent) 354 case *websocket.SubscribeEvent: 355 l.subscriptionEvents <- msg.(*websocket.SubscribeEvent) 356 case *websocket.UnsubscribeEvent: 357 l.unsubscriptionEvents <- msg.(*websocket.UnsubscribeEvent) 358 case *websocket.AuthEvent: 359 l.authEvents <- msg.(*websocket.AuthEvent) 360 case *wallet.Update: 361 l.walletUpdates <- msg.(*wallet.Update) 362 case *balanceinfo.Update: 363 l.balanceUpdates <- msg.(*balanceinfo.Update) 364 case *notification.Notification: 365 l.notifications <- msg.(*notification.Notification) 366 case *tradeexecutionupdate.TradeExecutionUpdate: 367 l.tradeUpdates <- msg.(*tradeexecutionupdate.TradeExecutionUpdate) 368 case *tradeexecution.TradeExecution: 369 l.tradeExecutions <- msg.(*tradeexecution.TradeExecution) 370 case *position.Update: 371 l.positions <- msg.(*position.Update) 372 case *order.Cancel: 373 l.cancels <- msg.(*order.Cancel) 374 case *margin.InfoBase: 375 l.marginBase <- msg.(*margin.InfoBase) 376 case *margin.InfoUpdate: 377 l.marginUpdate <- msg.(*margin.InfoUpdate) 378 case *order.New: 379 l.orderNew <- msg.(*order.New) 380 case *order.Update: 381 l.orderUpdate <- msg.(*order.Update) 382 case *fundinginfo.FundingInfo: 383 l.funding <- msg.(*fundinginfo.FundingInfo) 384 case *position.Snapshot: 385 l.positionSnapshot <- msg.(*position.Snapshot) 386 case *wallet.Snapshot: 387 l.walletSnapshot <- msg.(*wallet.Snapshot) 388 default: 389 log.Printf("COULD NOT TYPE MSG ^") 390 } 391 } 392 } 393 }() 394 }