From 61978aa579531d63936e13ded7831970426eca68 Mon Sep 17 00:00:00 2001 From: Rob Pike Date: Mon, 31 Jan 2011 12:46:38 -0800 Subject: [PATCH] effective go: remove non-blocking ops in leaky bucket example R=rsc CC=golang-dev https://golang.org/cl/4029048 --- doc/effective_go.html | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/doc/effective_go.html b/doc/effective_go.html index 6e3040fe3d..e30251f6ae 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. } }

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

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

-The client's non-blocking receive from freeList obtains a -buffer if one is available; otherwise the client allocates -a fresh one. -The server's non-blocking send on freeList puts b back +The client attempts to retrieve a buffer from freeList; +if none is available, it allocates a fresh one. +The server's send to freeList puts b 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 default clauses in the select +statements execute when no other case is ready, +meaning that the selects 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.