14 comments

[ 4.0 ms ] story [ 56.6 ms ] thread
Awesome as always Dustin. Love reading your blog. Keep it up.
I'd be interested to see commentary on the error handling he decided on (basically: r = write(x, r) r = write(y, r) etc, with write being: func (x, ok): if (ok) { ... }
Yea that's probably an artifact of a C code. The correct way to handle this in go ( i think, i'm a beginner like everyone else ) is to pass around a request struct that contains an error channel and have the main connection handling gorutine select on this.

That's at least for bigger picture errors. On the method level you should use multiple return values to indicate erros (usually as last return value).

So r, err = write(y) { if (err!=nil) { request.errors <- err; return } }

The most important part is to stop doing the thing that isn't working.

If I communicate this to the channel and the channel is read by the current goroutine, then the channel's buffer must be large enough to handle the total number of errors that may occur in a single invocation or the goroutine will deadlock on itself.

I commented on that here: http://dustin.github.com/2009/11/12/gomemcached.html#comment...

Basically, it's about allowing me to express my sequence of writes without wrapping each one in an if block.

I could have also done something like

    return write(x) && write(y) [...]
or

    return write(x, y, ...)
but all I really want is to stop writing when a write fails and have the goroutine exit.

I've seen a couple people suggest using a channel for this. Containing the write within an object of sorts to contain that boolean would do roughly the same thing. I'd still need to somehow unwind the stack quickly to even know that that channel has something waiting on it.

Are goroutines really that lightweight that this could handle thousands of simultaneous connections? If so, go is even cooler than I thought. If not, is there epoll/kqueue support yet?
Yes, goroutines are that lightweight. Rob Pike's introductory tech talk has a demo where he runs a program w/ 100,000 communicating goroutines in 1.5 seconds on a Mac laptop. See the slides at http://golang.org/doc/go_talk-20091030.pdf, page 34.
You have to be careful how you use them. Many green-threaded runtimes convert blocking I/O to non-blocking, but it appears that Go does not. If you have N goroutines blocked on I/O, it looks like Go will use N+1 pthreads to support them; thus a goroutine-per-connection model with blocking I/O is basically the same as the old thread-per-connection model (as used by Varnish or the Apache thread MPM).

This stuff isn't entirely clear to me, so maybe someone from Go land can clarify.

I think the intent is to multiplex the goroutines on some smaller set of threads.

From the language FAQ (http://golang.org/doc/go_lang_faq.html): "The idea, which has been around for a while, is to multiplex independently executing functions - coroutines, really - onto a set of threads."

I would like to see a sibling scripting language, desgined to be embedded in Go programs, with a very similar syntax to Go and optional typing.
Exactly my thoughts too. That would be an ideal server side programming tool. E.g. imagine a webserver written in Go with long polls, and the applications on it in GoScript. Or an XMPP (Wave) server. Or a distributed Map/Reduce engine.
Has darcs just disappeared off the radar? I'm using it for all my projects, though I'm not sharing wih anyone else, so I've never come under pressure to switch.
darcs is a fine revision control system. I used to use it quite a bit. The biggest problem I ever had with darcs, in practice, was not having ghc available when I'd do an OS upgrade and thus having no ability to access my repositories.

I am a pretty huge fan of git, though (obviously) so all of my new projects and many of my older ones show up on github.

Otherwise, perhaps I'd be posting this source to http://patch-tag.com/ instead. :)