Binance.Net icon indicating copy to clipboard operation
Binance.Net copied to clipboard

Why socket message processed so long?

Open vaniakurd opened this issue 2 years ago • 4 comments

Sokcet options: LogLevel = Microsoft.Extensions.Logging.LogLevel.Trace

i just wanna ask about message processed. I not sure but it seems to me that 3 ms for parse response is a lot. This logs from VS outpoot window. logs.txt

vaniakurd avatar Jul 27 '22 23:07 vaniakurd

Thanks for answer. I will test BinanceAPI for socket soon. Can u help me with other issue(#1145 ) with Ticker socket ?

vaniakurd avatar Oct 01 '22 16:10 vaniakurd

@vaniakurd, the data handlers are synchronous, i.e. you code inside the data handler await _socketClient.SpotStreams.SubscribeToKlineUpdatesAsync(.., dataHandler => { ... }) is called synchronously as soon as the message comes from the websocket.

@JKorf used Action<T> in opposed to Func<T, ValueTask> for the data handlers, so you should handle it yourself. I personally have in-memory representations / cached versions of the structures I need, e.g. local orderbook, local tradebook, positions, wallets, etc. and I'm keeping the state up to date which is not affected by backpressure. The immutable memory snapshots can be accessed on demand.

In plain English, you should be off-loading the data handlers and process the messages in a separate context (thread). In your case you're causing backpressure. Backpressure is when the websocket produces more messages than you could handle (consume). Think about it for a second, the websocket produces 1 message per second and your data handler takes 5 seconds to execute. Your consumer is always going to be late. If you run your application for a day, you'll end up working with old data. This is usually solved by the pull-based or push-based programming model. Refer to: https://www.infoq.com/articles/Async-Streams/. IAsyncEnumerable is Microsoft's way of trying to implement backpressure-able streams. Some people would rather use System.Reactive (Rx.NET) which is using the push programming model:

client
    .Streams
    .TradesStream
    .ObserveOn(TaskPoolScheduler.Default)
    .Subscribe(trade => { code1 });

Hulkstance avatar Jan 03 '23 11:01 Hulkstance

@Hulkstance, Maybe i don't understand something, but even if i write code with empty dataHendler i will see the same situation. SpotStreams.SubscribeToTickerUpdatesAsync( symb, msg =>{return;})

This code from CryptoExchange.Net:

protected virtual void HandleMessage( string data )
        {
            var timestamp = DateTime.UtcNow;
            ...
            var messageEvent = new MessageEvent( this, tokenData, ApiClient.Options.OutputOriginalData ? data : null, timestamp );
            var (handled, userProcessTime, subscription) = HandleData( messageEvent );
            ....
            var total = DateTime.UtcNow - timestamp;`
            _log.Write( LogLevel.Trace, $"Socket {SocketId}{( subscription == null ? "" : " subscription " + subscription!.Id )} message 
                     processed in { (int) total.TotalMilliseconds}
            ms, ({ (int) userProcessTime.TotalMilliseconds}
            ms user code)");
        }

I dont understand what work so slow, with emty dataHandler

vaniakurd avatar Apr 05 '23 15:04 vaniakurd