The problem is not with non-blocking IO; it's with your choice of tail
.
This prints out each line with a colon (all of them):
while true; do date; sleep 1; done | grep :
The problem with tail
is that it goes to the last 10 ten lines and then starts following. But in your case, it never reaches the end, so it can't print the last ten.