title: How can I compute the message to be sent on a channel as late as possible?
body: <p>My scenario:</p>
  
  <ul>
  <li>I have a producer and a consumer. Both are goroutines, and they communicate through one channel.</li>
  <li>The producer is capable of (theoretically) generating a message at any time.</li>
  <li>Generating a message requires some computation.</li>
  <li>The message is somewhat time-sensitive (i.e. the older it is, the less relevant it is).</li>
  <li>The consumer reads from the channel occasionally. For the sake of this example, let's say the consumer uses a <code>time.Ticker</code> to read a message once every couple of seconds.</li>
  <li>The consumer would prefer "fresh" messages (i.e. messages that were generated as recently as possible).</li>
  </ul>
  
  <p>So, the question is: <strong>How can the producer generate a message as late as possible?</strong></p>
  
  <hr>
  
  <p>Sample code that shows the general idea:</p>
  
  <pre class="lang-golang prettyprint-override"><code>func producer() {
      for {
          select {
          ...
          case pipe &lt;- generateMsg():
              // I'd like to call generateMsg as late as possible,
              // i.e. calculate the timestamp when I know
              // that writing to the channel will not block.
          }
      }
  }
  
  func consumer() {
      for {
          select {
          ...
          case &lt;-timeTicker.C:
              // Reading from the consumer.
              msg &lt;- pipe
              ...
          }
      }
  }
  </code></pre>
  
  <p>Full code (slightly different from above) is available at the Go Playground: <a href="https://play.golang.org/p/y0oCf39AV6P" rel="nofollow noreferrer">https://play.golang.org/p/y0oCf39AV6P</a></p>
  
  <hr>
  
  <p>One idea I had was to check if writing to a channel would block. If it wouldn't block, then I can generate a message and then send it. However…</p>
  
  <ul>
  <li>I couldn't find any way to test if writing to a channel would block or not.</li>
  <li>In the general case, this is a bad idea because it introduces a racing condition if we have multiple producers. In this specific case, I only have one producer.</li>
  </ul>
  
  <hr>
  
  <p>Another (bad) idea:</p>
  
  <pre class="lang-golang prettyprint-override"><code>func producer() {
      var msg Message
      for {
          // This is BAD. DON'T DO THIS!
          select {
          case pipe &lt;- msg:
              // It may send the same message multiple times.
          default:
              msg = generateMsg()
              // It causes a busy-wait loop, high CPU usage
              // because it re-generates the message all the time.
          }
      }
  }
  </code></pre>