3 ms·
Edit 2: I ended up doing the translation from the Python article. ;) http://play.golang.org/p/ep8wK_UUGm http://play.golang.org/p/ep8wK_UUGm It's pretty straigh
by ericbb 14y ago
Edit 2: I ended up doing the translation from the Python article. ;) http://play.golang.org/p/ep8wK_UUGm http://play.golang.org/p/ep8wK_UUGm It's pretty straightforward I think. One subtlety is that goroutines are not values and won't be garbage collected until they return. In practice, that means that you usually want a way to signal to the goroutine that it is done and can return. In my translation, I used the mechanism of closing the "stream" channel. You can see that in the unwrapProtocol function, it uses "b, ok := <-stream", which gets a byte in b and true in ok if a byte was received and gets a zero byte and false if the channel has been closed. The main function closes the stream to signal to unwrapProtocol that it is done.
Edit 3: Notice that I forgot to close the "frames" channel. So if this were a long-running program, that goroutine running frameReceiver would be a leaked resource.
- chubot 14y agoYeah this is cool. Notice that the top comment in this article is about Ragel supporting output for Go. But you don't need it in a lot of cases since you have goroutines. One of the most well-known uses of Ragel is for Zed Shaw's mongrel HTTP parser. If you want an event-driven server, and you want to parse incrementally, you need a state machine. And writing a state machine for HTTP is a nightmare -- for C it is indeed better to generate it. But I took a look at Go's http/request.go, and it just parses in the normal "synchronous" style. Of course this is because the Go runtime already takes care of the event loop and dispatching to goroutines. I just did the same thing in Python -- I wrote a coroutine-based HTTP "framer" in a single 20-line function -- it uses ReadUntil('\r\n\r\n'), parses Content-Length, and ReadN(length). This is all done concurrently on a single thread of course, thanks to the coroutines. This seems like obviously the right way to parse network formats efficiently and scalably. So yeah I would think twice about before using state machines in Go.