title: How to timeout RabbitMQConsumer if it didn`t receive response
body: <p>I got code that consumes messages from RabbitMQ queue. It should fail if it doesn`t received message for some time.</p>
  
  <pre><code>msgs, err := ch.Consume(
          c.ResponseQueue, // queue
          "",              // consumer
          false,           // auto-ack
          false,           // exclusive
          false,           // no-local
          false,           // no-wait
          nil,             // args
      )
      failOnError(err, "Failed to register a consumer")
  
  ...
  
  loop:
      for timeout := time.After(time.Second); ; {
          select {
          case &lt;-timeout:
              log.Printf("Failed to receive response for action %+v\n Payload: %+v\nError: %+v\n", action, body, err)
              return errors.New("Failed to receive response for action")
          default:
              for d := range msgs {
                  if corrID == d.CorrelationId {
                      err = json.Unmarshal([]byte(uncompress(d.Body)), &amp;v)
                      if err != nil {
                          return err
                      }
                      ch.Ack(d.DeliveryTag, false)
                      break loop
                  }
              }
          }
      }
  </code></pre>
  
  <p>I took consume code from RabbitMQ manual and tried some advices for implementing timeout. I know how to do it in Java, but can`t repeat it in Golang.</p>
  
  <p>Thanks in advance.</p>
  
  <p><strong>Update:</strong></p>
  
  <p>Changed select to this:</p>
  
  <pre><code>c1 := make(chan error, 1)
      go func() {
          for d := range msgs {
              if corrID == d.CorrelationId {
                  err = json.Unmarshal([]byte(uncompress(d.Body)), &amp;v)
                  if err != nil {
                      c1 &lt;- err
                  }
                  ch.Ack(d.DeliveryTag, false)
                  c1 &lt;- nil
              }
          }
      }()
  
      select {
      case &lt;-time.After(defaultTimeout * time.Second):
          log.Printf("Failed to receive response for action %+v\n Payload: %+v\nError: %+v\n", action, body, err)
          return errors.New("Failed to receive response in time for action")
      case err := &lt;-c1:
          failOnError(err, "Failed to process response")
      }
      return err
  </code></pre>
  
  <p>Now it works as expected - if it doesn`t receive message with proper corellationId it will fail with timeout. Thanks for help everyone.</p>