title: Golang map len() reports > 0 when map is empty
body: <p><strong>Short story:</strong></p>
  
  <p>I'm having an issue where a map that previously had data but should now be empty is reporting a <code>len()</code> of > 0 even though it appears to be empty, and I have no idea why.</p>
  
  <p><strong>Longer story:</strong></p>
  
  <p>I need to process a number of <em>devices</em> at a time. Each <em>device</em> can have a number of messages. The concurrency of Go seemed like an obvious place to begin, so I wrote up some code to handle it and it seems to be going <em>mostly</em> very well. However...</p>
  
  <p>I started a single goroutine for each <em>device</em>. In the <code>main()</code> function I have a <code>map</code> that contains each of the <em>devices</em>. When a message comes in I check to see whether the <em>device</em> already exists and if not I create it, store it in the map, and then pass the message into the device's receiving buffered channel.</p>
  
  <p>This works great, and each device is being processed nicely. However, I need the device (and its goroutine) to terminate when it doesn't receive any messages for a preset amount of time. I've done this by checking in the goroutine itself how much time has passed since the last message was received, and if the goroutine is considered <em>stale</em> then the receiving channel is closed. But how to remove from the map?</p>
  
  <p>So I passed in a pointer to the map, and I have the goroutine delete the <em>device</em> from the map and close the receiving channel before returning. The problem though is that at the end I'm finding that the <code>len()</code> function returns a value > 0, but when I output the map itself I see that it's empty.</p>
  
  <p>I've written up a toy example to try to replicate the fault, and indeed I'm seeing that <code>len()</code> is reporting > 0 when the map is apparently empty. The last time I tried it I saw 10. The time before that 14. The time before that one, 53.</p>
  
  <p>So I can replicate the fault, but I'm not sure whether the fault is with me or with Go. How is <code>len()</code> reporting > 0 when there are apparently no items in it?</p>
  
  <p>Here's an example of how I've been able to replicate. I'm using Go v1.5.1 windows/amd64</p>
  
  <p>There are two things here, as far as I'm concerned:</p>
  
  <ol>
  <li>Am I managing the goroutines properly (probably not) and</li>
  <li>Why does <code>len(m)</code> report > 0 when there are no items in it?</li>
  </ol>
  
  <p>Thanks all</p>
  
  <p><strong>Example Code:</strong></p>
  
  <pre><code>package main
  
  import (
      "log"
      "os"
      "time"
  )
  
  const (
      chBuffSize        = 100             // How large the thing's channel buffer should be
      thingIdleLifetime = time.Second * 5 // How long things can live for when idle
      thingsToMake      = 1000            // How many things and associated goroutines to make
      thingMessageCount = 10              // How many messages to send to the thing
  )
  
  // The thing that we'll be passing into a goroutine to process -----------------
  type thing struct {
      id string
      ch chan bool
  }
  
  // Go go gadget map test -------------------------------------------------------
  func main() {
      // Make all of the things!
      things := make(map[string]thing)
      for i := 0; i &lt; thingsToMake; i++ {
          t := thing{
              id: string(i),
              ch: make(chan bool, chBuffSize),
          }
          things[t.id] = t
  
          // Pass the thing into it's own goroutine
          go doSomething(t, &amp;things)
  
          // Send (thingMessageCount) messages to the thing
          go func(t thing) {
              for x := 0; x &lt; thingMessageCount; x++ {
                  t.ch &lt;- true
              }
          }(t)
      }
  
      // Check the map of things to see whether we're empty or not
      size := 0
      for {
          if size == len(things) &amp;&amp; size != thingsToMake {
              log.Println("Same number of items in map as last time")
              log.Println(things)
              os.Exit(1)
          }
          size = len(things)
          log.Printf("Map size: %d\n", size)
          time.Sleep(time.Second)
      }
  }
  
  // Func for each goroutine to run ----------------------------------------------
  //
  // Takes two arguments:
  // 1) the thing that it is working with
  // 2) a pointer to the map of things
  //
  // When this goroutine is ready to terminate, it should remove the associated
  // thing from the map of things to clean up after itself
  func doSomething(t thing, things *map[string]thing) {
      lastAccessed := time.Now()
      for {
          select {
          case &lt;-t.ch:
              // We received a message, so extend the lastAccessed time
              lastAccessed = time.Now()
          default:
              // We haven't received a message, so check if we're allowed to continue
              n := time.Now()
              d := n.Sub(lastAccessed)
              if d &gt; thingIdleLifetime {
                  // We've run for &gt;thingIdleLifetime, so close the channel, delete the
                  // associated thing from the map and return, terminating the goroutine
                  close(t.ch)
                  delete(*things, string(t.id))
                  return
              }
          }
  
          // Just sleep for a second in each loop to prevent the CPU being eaten up
          time.Sleep(time.Second)
      }
  }
  </code></pre>
  
  <p>Just to add; in my original code this is looping forever. The program is designed to listen for TCP connections and receive and process the data, so the function that is checking the map count is running in it's own goroutine. However, this example has exactly the same symptom even though the map <code>len()</code> check is in the <code>main()</code> function and it is designed to handle an initial burst of data and then break out of the loop.</p>
  
  <p><strong>UPDATE 2015/11/23 15:56 UTC</strong></p>
  
  <p>I've refactored my example below. I'm not sure if I've misunderstood @RobNapier or not but this works much better. However, if I change <code>thingsToMake</code> to a larger number, say 100000, then I get lots of errors like this:</p>
  
  <pre><code>goroutine 199734 [select]:
  main.doSomething(0xc0d62e7680, 0x4, 0xc0d64efba0, 0xc082016240)
          C:/Users/anttheknee/go/src/maptest/maptest.go:83 +0x144
  created by main.main
          C:/Users/anttheknee/go/src/maptest/maptest.go:46 +0x463
  </code></pre>
  
  <p>I'm not sure if the problem is that I'm asking Go to do too much, or if I've made a hash of understanding the solution. Any thoughts?</p>
  
  <pre><code>package main
  
  import (
      "log"
      "os"
      "time"
  )
  
  const (
      chBuffSize        = 100             // How large the thing's channel buffer should be
      thingIdleLifetime = time.Second * 5 // How long things can live for when idle
      thingsToMake      = 10000           // How many things and associated goroutines to make
      thingMessageCount = 10              // How many messages to send to the thing
  )
  
  // The thing that we'll be passing into a goroutine to process -----------------
  type thing struct {
      id   string
      ch   chan bool
      done chan string
  }
  
  // Go go gadget map test -------------------------------------------------------
  func main() {
      // Make all of the things!
      things := make(map[string]thing)
  
      // Make a channel to receive completion notification on
      doneCh := make(chan string, chBuffSize)
  
      log.Printf("Making %d things\n", thingsToMake)
      for i := 0; i &lt; thingsToMake; i++ {
          t := thing{
              id:   string(i),
              ch:   make(chan bool, chBuffSize),
              done: doneCh,
          }
          things[t.id] = t
  
          // Pass the thing into it's own goroutine
          go doSomething(t)
  
          // Send (thingMessageCount) messages to the thing
          go func(t thing) {
              for x := 0; x &lt; thingMessageCount; x++ {
                  t.ch &lt;- true
                  time.Sleep(time.Millisecond * 10)
              }
          }(t)
      }
      log.Printf("All %d things made\n", thingsToMake)
  
      // Receive on doneCh when the goroutine is complete and clean the map up
      for {
          id := &lt;-doneCh
          close(things[id].ch)
          delete(things, id)
          if len(things) == 0 {
              log.Printf("Map: %v", things)
              log.Println("All done. Exiting")
              os.Exit(0)
          }
      }
  }
  
  // Func for each goroutine to run ----------------------------------------------
  //
  // Takes two arguments:
  // 1) the thing that it is working with
  // 2) the channel to report that we're done through
  //
  // When this goroutine is ready to terminate, it should remove the associated
  // thing from the map of things to clean up after itself
  func doSomething(t thing) {
      timer := time.NewTimer(thingIdleLifetime)
      for {
          select {
          case &lt;-t.ch:
              // We received a message, so extend the timer
              timer.Reset(thingIdleLifetime)
          case &lt;-timer.C:
              // Timer returned so we need to exit now
              t.done &lt;- t.id
              return
          }
      }
  }
  </code></pre>
  
  <p><strong>UPDATE 2015/11/23 16:41 UTC</strong></p>
  
  <p>The completed code that appears to be working properly. Do feel free to let me know if there are any improvements that could be made, but this works (sleeps are deliberate to see progress as it's otherwise too fast!)</p>
  
  <pre><code>package main
  
  import (
      "log"
      "os"
      "strconv"
      "time"
  )
  
  const (
      chBuffSize        = 100             // How large the thing's channel buffer should be
      thingIdleLifetime = time.Second * 5 // How long things can live for when idle
      thingsToMake      = 100000          // How many things and associated goroutines to make
      thingMessageCount = 10              // How many messages to send to the thing
  )
  
  // The thing that we'll be passing into a goroutine to process -----------------
  type thing struct {
      id       string
      receiver chan bool
      done     chan string
  }
  
  // Go go gadget map test -------------------------------------------------------
  func main() {
      // Make all of the things!
      things := make(map[string]thing)
  
      // Make a channel to receive completion notification on
      doneCh := make(chan string, chBuffSize)
  
      log.Printf("Making %d things\n", thingsToMake)
  
      for i := 0; i &lt; thingsToMake; i++ {
          t := thing{
              id:       strconv.Itoa(i),
              receiver: make(chan bool, chBuffSize),
              done:     doneCh,
          }
          things[t.id] = t
  
          // Pass the thing into it's own goroutine
          go doSomething(t)
  
          // Send (thingMessageCount) messages to the thing
          go func(t thing) {
              for x := 0; x &lt; thingMessageCount; x++ {
                  t.receiver &lt;- true
                  time.Sleep(time.Millisecond * 100)
              }
          }(t)
      }
      log.Printf("All %d things made\n", thingsToMake)
  
      // Check the `len()` of things every second and exit when empty
      go func() {
          for {
              time.Sleep(time.Second)
              m := things
              log.Printf("Map length: %v", len(m))
              if len(m) == 0 {
                  log.Printf("Confirming empty map: %v", things)
                  log.Println("All done. Exiting")
                  os.Exit(0)
              }
          }
      }()
  
      // Receive on doneCh when the goroutine is complete and clean the map up
      for {
          id := &lt;-doneCh
          close(things[id].receiver)
          delete(things, id)
      }
  }
  
  // Func for each goroutine to run ----------------------------------------------
  //
  // When this goroutine is ready to terminate it should respond through t.done to
  // notify the caller that it has finished and can be cleaned up. It will wait
  // for `thingIdleLifetime` until it times out and terminates on it's own
  func doSomething(t thing) {
      timer := time.NewTimer(thingIdleLifetime)
      for {
          select {
          case &lt;-t.receiver:
              // We received a message, so extend the timer
              timer.Reset(thingIdleLifetime)
          case &lt;-timer.C:
              // Timer expired so we need to exit now
              t.done &lt;- t.id
              return
          }
      }
  }
  </code></pre>