|
|
|
|
|
by endymi0n
3901 days ago
|
|
Other than some quite significant performance gains, I'd say the main upside for the case of a backend API would be channels. Concurrency is dead simple in Go - and if you want to do 5 different requests to ElasticSearch in parallel and merge the results when all of them are finished (like we do for Universal Search), that's just a few lines of very readable Go. Try that with a GIL, sure, multithreaded Python and Ruby is possible, but it's not for the faint hearted and not as easy to read. Moreover, I love static deploys and cross compilation with Go. Compile your app (even to Windows!), copy it to a server, simply run it as a single binary. No dependency management, no apt-get & easy_install & pip, it just runs. |
|
For instance, look at the "Go Concurrency Patterns: Pipelines and cancellation" article: https://blog.golang.org/pipelines You'll notice the line "We introduce a new function, merge, to fan in the results" and after that, you will see how you have to write merge() yourself for every different data type that you use. Yes, you will have to repeat this same type of code, over and over, any time you want to pipeline, fanout, or merge, a new data type (unless you resort to interface{}). Furthermore, you will have to use the Go race detector to make sure you didn't actually mess something up.
I can't speak for Python or Ruby, but if you are using Node.js you can use a library like Bluebird which provides promise combinators. Then it's very easy to perform 5 requests and to handle errors and cancellation on one or more requests. You can do this and more on any arbitrary data type without writing merge() and nesting coroutine returning functions repeatedly.
So for handling async operations like dealing with APIs, I personally prefer tools like promise combinators or reactive programming (see Reactive Extensions for Javascript, also available in many other languages, or supplies in Perl 6 if you're crazy like me) over the significantly more manual approach of using typed channels in Go. I'm sure there are tasks where tight manual control of channels is important, but for the type of work I've been doing Go is simply too low level.
This article goes into more detail on the weaknesses of pipelining in Go: https://gist.github.com/kachayev/21e7fe149bc5ae0bd878