(1) I find error handling just too tedious to get right (Edit: "I find error handling _in Go_ just too tedious...")
(1) I find error handling just too tedious to get right (Edit: "I find error handling _in Go_ just too tedious...")
The Go version may in fact be faster, but I don't think that's necessarily fair either: if the Go version adds features to be more comparable to nginx it would definitely slow down.
Good point. That is often how alternative parallel implementations are started. A small example is written. Benchmarks are published. The new project is hailed as better than predecessor. Many jump ship. Request for features comes in. New features starts to slow down the product. Someone new comes, writes a simple benchmark and so on.
* Are they relevant. Does this represent the expected production workload. You could find this is 10x better than nginx at some feature but that feature is just not interesting to you then benchmarks are not that interesting
* Does the speed difference matter? Does it matter if the page loads 1ms faster when it was only 20ms before.
* Does it scale. This kind of relates to first question but it looks at abnormal amounts of traffic (Slashdot effects). Either from an attack or just becoming popular too quickly. If simply adds a server with more CPUs would that let Go server scale better than nginx? It might even though nginx could probably process sequential requests faster.
A recent issue where one of our developers ate an exception cost us 12 days of developer time. Another historical issue where the error handling and return codes weren't understood and handled correctly threw 500mb of stack dumps a minute and took our logging system out.
Spent the time to get it right :)
I added an edit to my comment to avoid the implication you picked up on!
Go even has exceptions, it just doesn't usually use them.
Can you explain what you think the problem is with supporting exceptions?
You raise a good point though, in that there is a valid question of "how would you introduce exceptions into the language / runtime". I think the answer is that the err return value can become implicit. Throwing an exception is the equivalent of "return _, err". Invoking a function that can throw an exception is done by not checking the err return; if an exception is thrown/returned and not checked then it is immediately rethrown (return _,err) in an implicit method. try/catch should be easy to introduce, although the semantics of e.g. "defer" could be tricky.
Exceptions propagate up the call stack within a goroutine, and then, if not recovered within the goroutine that raised them, crash the whole program.
(I cheated a bit -- that's how go already handles exceptions, which it calls "panics". The difference between go and, say, Java is that the core and standard library don't panic as much as Java's throws exceptions, leaving the decision to panic to user code more often.)