ngscopeclient / scopehal

Test and measurement hardware abstraction library and protocol decodes. This is the library only. Most users should use scopehal-apps.
BSD 3-Clause "New" or "Revised" License
216 stars 97 forks source link

CSVStreamInstrument can cause upstream sources to buffer data #890

Open Copper280z opened 2 months ago

Copper280z commented 2 months ago

In the case where a source sends data faster than CSVStreamInstrument can consume it some sources will buffer data instead of dropping it. A good example is orbcat piped to netcat.

orbcat -c 1,"CSV-DATA,%d," -c 2,"%d\r\n" |& nc -k -l localhost 2345

This causes the data shown to become stale, potentially very quickly if the source can supply a lot of data.

I think the expected behavior is that scopehal will read all the data available, then use the last valid CSV- line (of each type, data, unit, and name?) for the update.

A simple solution is to use the first valid line in the buffer, then flush the rest, though this introduces a 1 update delay and sort of breaks the concept of "most recent data point". Next best might be to read the whole buffer, then parse through it, but this seems like it isn't going to be made easy by the code that shows up in several ReadReply implementations.

    //FIXME: there *has* to be a more efficient way to do this...
    char tmp = ' ';
    string ret;
    while(true)
    {
        if(!m_socket.RecvLooped((unsigned char*)&tmp, 1))
            break;
        if( (tmp == '\n') || ( (tmp == ';') && endOnSemicolon ) )
            break;
        else
            ret += tmp;
    }

I tried using a simple while loop to empty the buffer at the instrument level, but didn't have much success. I think data was coming in faster than it could be read out byte by byte, which caused the loop to hang. The flush strategy worked fine, with the aforementioned caveats. There might be a decent way with ReadRawData, but I don't think you can get the length of bytes received for a read that timed out, so it may not be any better.