How to properly read from FIFO:

1
cat <>fifo

Stéphane Chazelas on StackExchange shared some really good explanation here, especially on the strange behavior of using tail -f fifo to read.

Like cat, tail will wait for a process to open a file for writing. But here, since you didn't specify a -n +1 to copy from the beginning, tail will need to wait until eof to find out what the last 10 lines were, so you won't see anything until the writing end is closed.

After that, tail will not close its fd to the pipe which means the pipe instance won't be destroyed, ... That read() will return with eof ... until some other process opens the file again for writing.

Another answer also by Stéphane is at here. This one let me realize that dd can also be used for reading fifos (more flexible):

1
dd bs=64k if="$my_named_pipe" iflag=nonblock status=noxfer

Another flexible reading approach is socat.

Side note - someone else mentioned that UDP can be used for "non-blocking" data transfer: one end can send/receive data without the other end present. This could be quite convenient/easy to work with.