0

For example when the incoming data stream on the STDIN can have pauses, gaps in it for a few minutes, meanwhile no data is sent, because actual data is still being prepeared, or isn't currently available for some reason.

I would like to write a CLI app in Ruby which reads its own STDIN and writes the data without any modification to its own STDOUT. However it must maintain an internal buffer, which prevents the situation, when there are no incoming data. In this case it should turn to its internal buffer, and provide outgoing data to STDOUT from that buffer, for example 64-1024 bytes per second or even less, until the internal buffer runs out.

I would like to use this filter in the following manner:

producer_app | filter | consumer_app

Without the buffering it is simple:

bufsize=64*1024
while data=STDIN.read(bufsize) do
  STDOUT.write(data)
end

Unfortunately when there is no data on the STDIN for let's say a minute, then the STDIN.read(bufsize) call simply blocks (the further execution), for a minute, which is not good in my case, because consumer_app immediatley closes, exits, when it can't read any data for 20 seconds (it uploads data to a server, which closes the connection, when there is no data to be read for 20 seconds).

I think it should use STDIN.read_nonblock() call somehow, for example:

data=STDIN.read_nonblock(bufsize) rescue nil

returns nil into the "data" variable, when there is no data to read, else it returns some data, which size in bytes is <= than bufsize.

Of course we can assume, that incoming data stream byte count in total is greater than the above mentioned internal buffer size.

Konstantin
  • 2,983
  • 3
  • 33
  • 55
  • What's the problem with the `read_nonblock` solution you found? – Kimmo Lehto Feb 22 '19 at 06:56
  • I don't have a solution, I just guess that method should be used. – Konstantin Feb 22 '19 at 07:10
  • @Kimmo Lehto I was able to write this producer_app script, to ease the testing and experimenting. It pauses periodically for a given seconds: https://pastebin.com/dg294bqK – Konstantin Feb 22 '19 at 07:51
  • To test the data flow maintaining app: "producer_app|tee random_data.bin|maintain|pv > random_data2.bin" And then "md5sum random_data.bin; md5sum random_data2.bin". pv is the Linux filter which shows the kb/s. – Konstantin Feb 22 '19 at 08:13

0 Answers0