
Golang at CloudFlare - jgrahamc
http://blog.cloudflare.com/go-at-cloudflare
======
riobard
_Another reason Go has been helpful is that is generates a single executable
that can be distributed to our clients. There's no complex dependency chain or
layout of shared libraries to worry about._

This is such a subtle yet profound feature. Think about it: no more dependency
nightmare during deployment!

~~~
Strom
Static linking is easily available with C/C++ as well. The main trade-off is
how critical bugs in some library your program uses can be solved.

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.

~~~
jkn
Static linking is not easily available with C/C++ in the general case. Some
libraries support it, some important ones like Glibc and GTK+ do not.

~~~
pjmlp
The only reason this is not an issue with Go is that the language is too young
and the reference compiler only supports static linking fot the time being.

The moment the compiler starts supporting dynamic linking the same will happen
to Go.

~~~
4ad
Static linking of Go code is a conscious design decision, not some artifact of
toolchain immaturity. It will never change.

~~~
reddit_clone
On a related note, using Go can one develop DLLs that can be dynamically
consumed from other applications?

Or you can only produce statically linked exe's?

~~~
zimbatm
Only exes at the time being. Go is the main loop and needs to have control of
the execution flow for concurrency.

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.

------
eis
The code presented is not thread safe. It reads and writes to Counter.c from
two different goroutines.

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.

~~~
jgrahamc
Darn. I just knew that when I was extracting some showable bits of code from
Railgun and making simple examples that I'd mess something up. The third Gist
in there isn't anything like the Railgun code (it was just showing the use of
the Counter object) and, as you point out, it is not thread safe.

I will update the blog post with a version that uses a channel and select to
send the count.

~~~
ralph
Hi John, <https://gist.github.com/3039932> has problems; w.Count() is
evaluated every time around the for-loop even if the result isn't sent down
the count channel. See <http://play.golang.org/p/pbCX13my0q> where I've
altered lines 60-62 yet there's still only "29 bytes written".

~~~
jgrahamc
Yes, that's correct. It does look a bit odd doesn't it. As you say it's
because the w.Count() gets evaluated by the select each time around the loop
and so the count gets reset to 0.

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.

~~~
ralph
It's almost like sometimes it would have handy to do

    
    
        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.

------
lenkite
Now if only google supported Golang as a first class development language on
the Android platform...I would divorce and drop Java in a heartbeat.. _sigh_

~~~
cageface
I'd really like to see that too.

More likely though is that Kotlin matures and eliminates most of the Java
pain.

------
crb
John, I have a question for you. I didn't know you worked at Cloudflare, so I
looked up the "people" page last night, and I'm intrigued that while there are
many "engineers", you are the only "programmer".

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?

~~~
eastdakota
John proposed the title and I thought it was great. He wrote a blog post about
it:

<http://blog.jgc.org/2012/02/programmer.html>

------
pjmlp
Although I like Go as a possible replacement for C, it always amazes me when
people describe Go features, as if they were new and not already available in
several languages, that for whatever reason are not currently mainstream.

It makes me think that the development community has a serious problem knowing
the history of computer science.

~~~
luriel
If you watch the "Meet the Go team" talk from Google IO, they explicitly
mention that almost nothing in Go is particularly new, and most of its ideas
have been around for decades: <http://www.youtube.com/watch?v=sln-gJaURzk>

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.

~~~
pjmlp
Yeah I know that and was please to hear it.

My comment was more oriented towards to the people that write blog entries
about Go, not the developer team.

------
brown9-2
When I run the second example on play.golang.org, the output I get is:

    
    
        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?

~~~
jgrahamc
That's left as an exercise for the reader. Look at the channel synchronization
and follow the code for both routines (the main and the goroutine). I'll admit
in this case that it looks pretty deterministic, but in other cases it could
be a different pattern.

------
zimbatm
I wonder how predictable Go is when scaling up. Are there any weird
optimizations to do or surprising memory growth ?

~~~
stonemetal
The GC may not be up to snuff. <http://news.ycombinator.net/item?id=3805302>

~~~
luriel
There was a question specifically about the GC during the "Go In Production"
panel at Google IO, and everyone found that the GC was up to snuff, specially
on 64bit systems:

<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.

