New output buffering
Using varnishevent to output udp datagrams as with ...
#!/bin/bash varnishevent ... >/dev/udp/$HOST/$PORT
... I ran into an issue with partial strings being received. The reason is that each UDP datagram is independent and data contained within cannot be continued in subsequent datagrams (and even if it was, that could get lost). So, for use with UDP, any datagram must contain complete records, which, in the case of varnishevent, are lines, and, consequently, records must not span
write() system calls.
Initially I thought that setting
output.bufsiz lower than the effective UDP unfragmented maximum packet size (
output.bufsiz=1428) would help, but it turns out that, as
varnishevent was based on stdio buffered output, that didn't help: except when
setvbuf(..., _IOLBF, ...) was used, stdio (at least for glibc) always fills the buffer completely before issuing a system
write(). (see https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/genops.c;h=2fec221b99729718d27cef453db2d3e0c2c56233;hb=HEAD#l379 https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/iofwrite.c;h=800341b7da546e5b7fd2005c5536f4c90037f50d;hb=HEAD#l39 )
As line buffering would lead to a significantly higher system call rate, I bit the bullet and implemented simple output buffering for varnishevent which never splits any records.