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 setlinebuf()
/ 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.