'Missing messages from websocket server using select

I'm currently developing a connector for Binance futures.

I'm using websocket-client package for the websocket part.

It seems to work well but during the tests I realized that I'm missing messages from the server for some events.

For example when placing a market order (executed immediately) I should receive 3 messages as follow

[05-24-2022_15-47-37] [MESSAGE] {"e":"ORDER_TRADE_UPDATE","T":1653400057646,"E":1653400057647,"o":{"s":"BNBUSDT","c":"lcIIReoYWBLCGf5qTMQq3C","S":"BUY","o":"MARKET","f":"GTC","q":"0.10","p":"0","ap":"0","sp":"0","x":"NEW","X":"NEW","i":260992023,"l":"0","z":"0","L":"0","T":1653400057646,"t":0,"b":"0","a":"0","m":false,"R":false,"wt":"CONTRACT_PRICE","ot":"MARKET","ps":"BOTH","cp":false,"rp":"0","pP":false,"si":0,"ss":0}}
[05-24-2022_15-47-37] [MESSAGE] {"e":"ACCOUNT_UPDATE","T":1653400057646,"E":1653400057648,"a":{"B":[{"a":"USDT","wb":"2952.41531094","cw":"2952.41531094","bc":"0"}],"P":[{"s":"BNBUSDT","pa":"0.10","ep":"321.52000","cr":"-0.00520000","up":"-0.04996561","mt":"cross","iw":"0","ps":"BOTH","ma":"USDT"}],"m":"ORDER"}}
[05-24-2022_15-47-37] [MESSAGE] {"e":"ORDER_TRADE_UPDATE","T":1653400057646,"E":1653400057648,"o":{"s":"BNBUSDT","c":"lcIIReoYWBLCGf5qTMQq3C","S":"BUY","o":"MARKET","f":"GTC","q":"0.10","p":"0","ap":"321.52000","sp":"0","x":"TRADE","X":"FILLED","i":260992023,"l":"0.10","z":"0.10","L":"321.520","n":"0.01286080","N":"USDT","T":1653400057646,"t":36714569,"b":"0","a":"0","m":false,"R":false,"wt":"CONTRACT_PRICE","ot":"MARKET","ps":"BOTH","cp":false,"rp":"0","pP":false,"si":0,"ss":0}}

But I only receive the first two messages.

By digging into my code, I went back to a really simple implementation of the receiving function thread.

def __on_user_data(self):
    while True:
        message = self.__user_data_websocket.recv()
        log(f"[MESSAGE] {message}")

With this code, I successfully receive all the messages, however if I use my initial code, I miss messages.

def __on_user_data(self):
    while not self.__user_data_thread.is_stopped():
        has_data = select.select([self.__user_data_websocket], [], [], 1)
        if has_data[0]:
            message = self.__user_data_websocket.recv()
            log(f"[MESSAGE] {message}")

So the issue seems to come from the fact that I’m using passive waiting with select.

I'm using a custom Thread class to be able to stop the thread by sending an event with threading.Event, in order to handle disconnection, unsubscribing, etc...

That's why I don't want to use a blocking recv call, because it would lock the thread and I wouldn't be able to stop it when I want to.

What I don't understand is why the select misses data arrival when recv doesn't.

Could the issue come from buffering ? Or messages arriving to fast ?

I never had issues with using select and sockets, but I never did it in Python yet so maybe there is some configuration I'm not aware of.

What am I doing wrong here ?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source