diff options
author | Rob Pike <r@golang.org> | 2011-01-31 12:46:38 -0800 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2011-01-31 12:46:38 -0800 |
commit | 19987cc9798a79027c8a49bd14cd7536b67803a0 (patch) | |
tree | 10061e32e101245217f4fafe22e80b4004a6216f /doc/effective_go.html | |
parent | 68aa154e467f90a651fb4058395dff4c23c5ca7d (diff) | |
download | go-19987cc9798a79027c8a49bd14cd7536b67803a0.tar.gz |
effective go: remove non-blocking ops in leaky bucket example
R=rsc
CC=golang-dev
http://codereview.appspot.com/4029048
Diffstat (limited to 'doc/effective_go.html')
-rw-r--r-- | doc/effective_go.html | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/doc/effective_go.html b/doc/effective_go.html index 6e3040fe3..e30251f6a 100644 --- a/doc/effective_go.html +++ b/doc/effective_go.html @@ -2526,39 +2526,49 @@ var serverChan = make(chan *Buffer) func client() { for { - b, ok := <-freeList // grab a buffer if available - if !ok { // if not, allocate a new one + var b *Buffer + // Grab a buffer if available; allocate if not. + select { + case b = <-freeList: + // Got one; nothing more to do. + default: + // None free, so allocate a new one. b = new(Buffer) } - load(b) // read next message from the net - serverChan <- b // send to server + load(b) // Read next message from the net. + serverChan <- b // Send to server. } } </pre> <p> -The server loop receives messages from the client, processes them, +The server loop receives each message from the client, processes it, and returns the buffer to the free list. </p> <pre> func server() { for { - b := <-serverChan // wait for work + b := <-serverChan // Wait for work. process(b) - _ = freeList <- b // reuse buffer if room + // Reuse buffer if there's room. + select { + case freeList <- b: + // Buffer on free list; nothing more to do. + default: + // Free list full, just carry on. + } } } </pre> <p> -The client's non-blocking receive from <code>freeList</code> obtains a -buffer if one is available; otherwise the client allocates -a fresh one. -The server's non-blocking send on freeList puts <code>b</code> back +The client attempts to retrieve a buffer from <code>freeList</code>; +if none is available, it allocates a fresh one. +The server's send to <code>freeList</code> puts <code>b</code> back on the free list unless the list is full, in which case the buffer is dropped on the floor to be reclaimed by the garbage collector. -(The assignment of the send operation to the blank identifier -makes it non-blocking but ignores whether -the operation succeeded.) +(The <code>default</code> clauses in the <code>select</code> +statements execute when no other case is ready, +meaning that the <code>selects</code> never block.) This implementation builds a leaky bucket free list in just a few lines, relying on the buffered channel and the garbage collector for bookkeeping. |