Connecting to ticker feed asynchronously

yoursvsr
Hi,

While browsing through the KiteConnect client code for .Net, I'm unable to comprehend why this piece of code is called synchronously, while it can be called async.

And, if I add 'await' before both the calls to _ws.ReceiveAsync and 'async' to the callback (see snippet below), would it affect in any way how the client consumes data from the ticker feed from kite , apart from the obviously intended effect of being async?

Any views or comments welcome. Thanks.
                
callback = async t =>
{
try
{
byte[] tempBuff = new byte[_bufferLength];
int offset = t.Result.Count;
bool endOfMessage = t.Result.EndOfMessage;
// if chunk has even more data yet to recieve do that synchronously
while (!endOfMessage)
{
WebSocketReceiveResult result = _ws.ReceiveAsync(new ArraySegment<byte>(tempBuff), CancellationToken.None).Result;
Array.Copy(tempBuff, 0, buffer, offset, result.Count);
offset += result.Count;
endOfMessage = result.EndOfMessage;
}
// send data to process
OnData?.Invoke(buffer, offset, t.Result.MessageType.ToString());
// Again try to receive data
await _ws.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None).ContinueWith(callback);
}
catch (Exception e)
{
if (IsConnected())
{
OnError?.Invoke("Error while recieving data. Message: " + e.Message);
}
else
{
OnError?.Invoke("Lost ticker connection.");
}
}
};
// To start the receive loop in the beginning
await _ws.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None).ContinueWith(callback);
  • trade_then
    trade_then edited August 2020
    So what happened when you tried this code?

    I apologize but i think async has cast a spell on you. and you are effectively bewitched by it.

    by the looks of it and i could be wrong but your control will never pass ahead of
    • // To start the receive loop in the beginning
      await _ws.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None).ContinueWith(callback);
    this line. because it would be stuck in endless loop.
    I could be wrong because this is based on the glance over the code you presented.
    await should return the control to previous function. but wont ever reach the next line.
    but since there is nothing after that line so you might think your code is working on account of
    control left. but actually it is stuck there for ever.
    • async or Task can be used when you don`t care for the order or events to happen.
    But for ticks we need Synchronicity and order.

    And websocket does not allow 2 simultaneous receives or sends while previous is still in progress.
    it can be
    • one recieve and
    • one send at the same time.
    but not
    • recieve
    • recieve at the same time.
    In above code you see that even ReceiveAsync is being waited for via Result
    and there is a good reason for that.

    Above code is happening Asynchronously only because it is being initiated by RecieveAsync. it is just that inside callback. order is maintained.

    putting of async in front of t => should have no effect ideally. because it is allready
    pursuing async operation. and will continue to work as it is.

    although your putting of await in front on _ws.ReceiveAsync
    is causing suspicion. try by adding Console.WriteLine( "reached 1" ) ; after that line to see if control ever reaches there.

    once again i could be wrong about all of it. because i use Tasks directly instead async.

    Thanks
    Regards

  • yoursvsr
    Hi @trade_then,

    Thanks for your patient reply.
    So what happened when you tried this code?
    I'm able to receive the ticks, but after a few minutes, the UI freezes, with or without async execution. That's why I'm trying to optimize the code and examining it from the ground up.
    I apologize but i think async has cast a spell on you. and you are effectively bewitched by it.
    I am neither a software professional nor formally trained in these things. This is my pet project I'm trying to develop during my spare time. I have a full time job that is neither related to software nor the stock market. So, as would happen with any self trained person, it should be no surprise if I pick up some bad habits on the way. I'm willing to mend my ways...:smile:

    The whole task/async-await thing is new to me and my obsession for async-await pattern stems from the fact that this is a mobile app for android (I'm using Xamarin Forms) and I want my code to run optimally efficient.
    by the looks of it and i could be wrong but your control will never pass ahead of
    // To start the receive loop in the beginning
    await _ws.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None).ContinueWith(callback);
    There's nothing ahead of this line for execution in that method. And, it kickstarts the loop with a callback and I'm receiving the ticks for about a few minutes, say 5-10 minutes after which the UI just blanks out. And the problem is not really about not being able to start it but about making it continue to work efficiently.
    But for ticks we need Synchronicity and order.
    I agree and I have now removed the async ahead of t (for the callback) and await inside the loop. I think that ensures synchronisation and order while still making the method awaitable.
    because i use Tasks directly instead async.
    Could you please give a few pointers on how to achieve seamless tick processing? I'll try to explain what I'm trying to do. Please pardon me if any of this doesn't make any sense.

    I'm subscribing to websocket with about 600 instruments in 'quote' mode. And trying to build a intraday candle from these ticks. Snippet below: I know this is far from being efficient, but I'm unable to wrap my head around this.
    private async void OnTick(Tick tickData)
    {
    await Task.Run(() => ProcessTick(tickData));
    }

    private void ProcessTick(Tick tick)
    {
    foreach (var instrument in _instruments.Where(i => i.InstrumentToken == tick.InstrumentToken))
    {
    instrument.Open = tick.Open;
    instrument.High = tick.High;
    instrument.Low = tick.Low;
    instrument.Close = tick.LastPrice;
    instrument.Volume = tick.Volume;
    if (instrument.LastIntradayCandle.Open == 0)
    {
    instrument.LastIntradayCandle.Open = tick.LastPrice;
    }
    if (instrument.LastIntradayCandle.High < tick.LastPrice)
    {
    instrument.LastIntradayCandle.High = tick.LastPrice;
    }
    if (instrument.LastIntradayCandle.Low > tick.LastPrice)
    {
    instrument.LastIntradayCandle.Low = tick.LastPrice;
    }
    instrument.LastIntradayCandle.Close = tick.LastPrice;
    }
    pic when it is working:


    pic when the list blanks out after a few minutes:


  • trade_then
    trade_then edited August 2020
    for your information i am also a hobbyist programmer not professional.

    kindly see this post. if it is of any relevance to you.
    then we can proceed further.

    i have never programmed for mobile but few things come to mind.
    Freeze could be because of limited resources on
    mobile. that too if you are aggregating data on your set.

    and remove await from _ws.ReceiveAsync outside of callback also . it serves no purpose.
    asyncing of websocket is not dependent on that.

    Thanks
    Regards


  • yoursvsr
    Hi @trade_then

    So basically the issue is about tracking too many ticks for the processing power available? I thought my smartphone is more powerful than my laptop. :smile:

    Ok, will check it out and revert.

    Thanks for your kind support. Thumbs up!
  • trade_then
    Kindly post the exact specs of your smart phone when you revert back.
    so that hardware capabilities are known.

    Thanks
    Regards
  • yoursvsr
    Hi @trade_then

    I'm glad to inform that the ticks are processed just fine. It was the android environment that is killing the websocket connection. I have subscribed to 660 instruments today and concluded this in two ways:
    1. by switching the UI to UWP (windows) which is working just fine. see pic below
    2. by uninstalling lot of unnecessary apps in the phone and switching to flight mode and reconnnecting to wifi, again working just fine...
    3. In both cases, I have compared the tick movement of SBIN with that of TradingView this morning. Though not matching tick by tick, which is sort of expected, the ticks from kite are in fact ahead of TradingView, at least by one or two ticks...
    I need to learn ways to master the android environment. That's for another day. Thanks for your help buddy.



    btw, my phone specs
    Poco F1 with Qualcomm Snapdragon 845 (2.8 GHz quad core + 1.8 GHz quad core) 64 bit 6GB RAM
  • trade_then
    trade_then edited August 2020

    Cool



    Thanks
    Regards
Sign In or Register to comment.