Hi! I have a simple service that has an API for searching things like log files. One of the API endpoints returns just the matching documents, while another will try to return the matching records from those documents.
Because this output could be quite large (and so that results stream) I pass io.Readers and io.Writers around so that the backend can read from the input file, filter it as needed, and write it directly to the http response without having to buffer anything. A bug was found in that if one of the log files was missing/corrupt the failure to read it would stop the entire request. To fix this, a 'return err' in a loop was changed to a log, and I thought all was well. Now, I've noticed there is a new, subtle problem: If the write to the http ResponseWriter fails, that error is logged and skipped as if it was also a transient error. I've tried to extract the smallest example showing my issue here: https://play.golang.org/p/i2VVzwAxto8 It uses net/http so you'll have to run it locally. Essentially, it works like this: $ curl localhost:8888?q=2 Doc: 1 Doc: 3 Doc: 5 Doc: 7 Doc: 9 For q=2 It will log one error in the middle: 2018/02/06 18:14:59 Error dumping document 6: Unable to read document 6 This is good, since a failure showing document 6 shouldn't prevent 7 and 9 from being output. The issue is if you hit ?q=3 and control-c curl after a few documents, the server will continue to try to output documents and log 2018/02/06 18:15:47 Error dumping document 13: write tcp [::1]:8888->[::1]:52065: write: broken pipe 2018/02/06 18:15:47 Error dumping document 15: write tcp [::1]:8888->[::1]:52065: write: broken pipe 2018/02/06 18:15:48 Error dumping document 17: write tcp [::1]:8888->[::1]:52065: write: broken pipe ... 2018/02/06 18:15:48 Error dumping document 27: write tcp [::1]:8888->[::1]:52065: write: broken pipe Which is a problem :-) The actual code in question is https://github.com/JustinAzoff/flow-indexer/blob/02a1d0f9c7d4107064e925d68cba946ab6c6e359/flowindexer/flowindexer.go#L393 https://github.com/JustinAzoff/flow-indexer/blob/02a1d0f9c7d4107064e925d68cba946ab6c6e359/backend/syslog.go#L61 The problem being that 'Dump' doesn't know the error it got back from backend.FilterIPs was related to the reading of the log file or the writing of the data to the response. What complicates things is some of the backends may potentially use exec, like this: https://github.com/JustinAzoff/flow-indexer/blob/02a1d0f9c7d4107064e925d68cba946ab6c6e359/backend/pcap.go#L56 in which case the error comes from cmd.Run. I think the answer to my problem is somewhere in: https://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully but I'm not quite sure the best way to fix this is. Something like the IsTemporary it describes is along the lines of what I need, if there was a way to write a isWriteError or isReadError or something. I was also thinking that an io.Pipe may be one way to solve this, but I'm not sure if I wouldn't end up back in the same situation with pipes. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.