Golang at CloudFlare
blog.cloudflare.com
blog.cloudflare.com
This is such a subtle yet profound feature. Think about it: no more dependency nightmare during deployment!
This is not necessarily true. Remember the DLL hell? Go does not support dynamic linking at all (some say this is a disadvantage), so you are forced to produce a single self-contained binary.
Depending on the nature of the development toolset, you may not be able to avoid DLL hell. E.g. you may not have the right to build the library into your code and/or the toolset may force you to link against external code libraries.
The original goal of Microsoft's DLL strategy was to save disk space (and presumably memory) but the end result was a compatibility nightmare. Retrospectively, it seems to have been both a bad technical decision (disk space turned out to be a bad thing to trade against other considerations) and badly implemented (too many DLLs went live and then broke backwards compatibility in updates). It seems like other companies managed to allow dynamic linking without creating so much fragility.
It actually broke because they didn't allow multiple versions and windows linked to the latest version at runtime.
They fixed all this with WinSXS which allows a PE file to specify a manifest i.e. a list of required versions of DLLs to load. This is all neatly explained here:
Not if you use C and glibc (most common combination of them all, most software requires glibc). Even if you compile glibc statically in your program (not an option by default at least in Ubuntu), glibc itself will load more shared objects at runtime.
Rob Pike made a good point about this in one of the Go talks [1] (I think it was the "Meet the Go team" talk) when they were talking about package management and the static linking, and how in C++ you could get massive chains of useless includes (I think is came out of a question on the speed of the Go compiler). His reasoning was that all the code you need to compile a package should be in the one package binary. You shouldn't need to worry about having other 3rd-party packages that your dependency depends on installed on the target system.
[1] http://blog.golang.org/2012/07/go-videos-from-google-io-2012...
This is not true. If you make use of cgo, the dependencies are linked dynamically.
With a bit of hacking you can do it but it isn't the most straightforward procedure, can be messy and isn't really supported by the community.
With dynamic linking it's possible for the library author to publish an API-compatible update, which when deployed fixes the issue in all programs that use this library. With static linking you need to recompile the whole program and publish the update.
For real world examples you could look at the Microsoft C run-time. When a security vulnerability is found & fixed, Microsoft pushes the dynamic link version of the update via Microsoft Update and millions of programs are no longer affected by this issue. However when you linked statically, you need to update your program as well. Many programs do not have good automatic update systems, and many programs aren't even under continued maintenance and remain forever vulnerable.
The moment the compiler starts supporting dynamic linking the same will happen to Go.
Or you can only produce statically linked exe's?
If you think of it, DLLs are a bit like separate programs that you communicate with trough the C call stack instead of another structured protocol. In Go you would spawn different processes and use something like protobuf to exchange messages.
[me@host: tmp]% cat > hello.c
#include <stdio.h>
int main(void) { printf("hello world\n"); return 0; }
[me@host: tmp]% gcc -o hello -Wall hello.c -static
[me@host: tmp]% file hello
hello: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, not stripped
[me@host: tmp]% ldd hello
not a dynamic executable
[me@host: tmp]% ./hello
hello worldAlso, Go has gtk bindings, how does that work?
Publish your app as a dynamically linked binary to an app publisher, the publisher takes your dll and mashes it with its dependencies into a single dll that they deliver to the customer.
When there is a security update in a dependent dll, a new binary can be delivered by the publisher to the customer with no need for the original author to push a button.
I'm guessing something like this exists already?
I still need to get it wired up to the GitHub API for downloads and life will be perfect. I can push to master and upload a build for download all in one fell swoop.
([1], cross compiling is not [currently?] supported with cgo)
Getting a build for the chumby from my Windows/x64 box is as easy as setting GOARCH=arm, GOARM=5 and GOOS=linux and then re-running go build. Ridiculously simpler than setting up a full gcc toolchain that targets the device, taking into account what libc is on each device, etc. Build on the Windows box, scp the output executable over and It Just Works.
It's easy to make this mistake in Go as it's trivial to make your program not only concurrent but also parallel if it utilizes more than one thread (needs runtime.GOMAXPROCS(), which will go away in the future so will be the default).
If you use goroutines, always make sure that you are not accessing data from more than one goroutine at a time unless you are using lock or atomic instructions (which would be easy in case of a counter).
The alternative is to think of passing ownership of data when transferring it over a channel. The receiver is now in charge of it and should be the only one accessing it.
I never played with Go, but I was somehow under the impression that goroutines behave like processes and thus the only way to share data being through messages.
They are not like processes, they share the same address space.
Yes, but is worth remembering Go's (concurrency) motto:
Do not communicate by sharing memory; instead, share memory by communicating.
With channels you can send values, or pointers to the shared address space, so is much more efficient, or even channels (channels of channels are a very powerful and useful concept).
There are situations where using locks or atomic instructions is the better choice. But they nearly only come up in performance critical contexts.
It would be very nice to have some kind of compile-time enforceable ownership of data regarding channels and goroutines because debugging thread-safety issues is a pita. I don't know how feasable it is to implement this though.
They might be theoretically equivalent to some degree, but in practice they are quite different, and I find reasoning about both concurrency and parallelism using goroutines and channels much more natural.
Also see this talk by Rob Pike on the origins of Go's concurrency model here: http://go-lang.cat-v.org/talks/
See also this article by Russ Cox about CSP: http://swtch.com/~rsc/thread/
And Rob Pike's latest talk about concurrency patterns at Google IO last week: http://www.youtube.com/watch?v=f6kdp27TYZs
I will update the blog post with a version that uses a channel and select to send the count.
Probably the best way to fix that is to make Count() non-destructive and have an explicit Clear function that gets called when a count has been delivered.
Like this: http://play.golang.org/p/LWVvdhwBiQ
Since this blog post is likely to be around for a while I will update the code.
case ch <- defer foo():
and only have foo() be evaluated if ch is ready for writing and also chosen amongst the cases. As the (fixed) code stands either the Sprintf() and Sum() or Count() is wasted on each iteration. I suppose in some cases you can calculate the initial values before the for-loop and then replenish them in the case: when they're used.More likely though is that Kotlin matures and eliminates most of the Java pain.
I assume you got to choose your title, and I'm interested to know why you chose that one. (For what its worth, it's a title I think personally wish more people should adopt, especially those who don't do formal engineering.) Is it a US vs UK thing?
It makes me think that the development community has a serious problem knowing the history of computer science.
What makes Go great is not the individual features, but the selection of the features and how well they work together, and also the "features" that were excluded from the language.
My comment was more oriented towards to the people that write blog entries about Go, not the developer team.
This program will get 10 IDs from the id channel, print them and terminate
0a90333b6c0f5519b6e5f7ea2d541fb1793b957d
58 bytes written
af2f87580bb3562b58f2ad076e25f76ebf8fec75
0 bytes written
4491029b704d192be5a31eb0c35dfe516274d173
58 bytes written
d97a9080d01e9a8a11d0152d3df34f1c90f5cf16
0 bytes written
130c9fda35c98c7e8922d6ea24bb873838cfdcbd
58 bytes written
0e385bcc65efb6bac8ced67639c32b374d31ae57
0 bytes written
550413e7244dd40cf3df52634bb341dc166708b2
58 bytes written
49cfddab6ff9123ad237f03176927329349e186b
0 bytes written
12abf2ab19e52065b3f7367a57f6f8ecd4968b44
58 bytes written
0755254307f5f9b90829381fa797b5f26081cd5f
0 bytes written
Why does the count alternate between 58 and 0?http://www.youtube.com/watch?v=kKQLhGZVN4A
Also many improvements for the GC are coming in Go 1.1, some of them are already merged in the main Go tree.