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  }