// ConsumeMessages consumes messages in SQS queue. // It returns the number of consumed message in success. func (c *Consumer) ConsumeMessages() (int64, error) { messages, err := c.queue.ReceiveMessage( option.MaxNumberOfMessages(10), option.UseAllAttribute(), ) if err != nil { return 0, err } var n int64 succeededReceiptHandles := make([]*string, 0, len(messages)) for _, m := range messages { duration, relayTo, err := extractDelayd2MessageAttributes(m) if err != nil { log.Printf("consumer: %s: unable to extract attributes. skipping.", *m.MessageId) continue } err = c.driver.Enqueue(*m.MessageId, duration, relayTo, *m.Body) if err != nil && err != ErrMessageDuplicated { log.Printf("consumer: %s: %s: unable to enqueue this message. skipping", *m.MessageId, err) continue } if err == ErrMessageDuplicated { // delete immediately if duplicated log.Printf("consumer: %s: %s", *m.MessageId, err) } succeededReceiptHandles = append(succeededReceiptHandles, m.ReceiptHandle) n++ } if len(succeededReceiptHandles) > 0 { if err := c.queue.DeleteMessageBatch(succeededReceiptHandles...); err != nil { log.Printf("consumer: unable to delete messages in batch but continuing since messages will appear again: %s", err) } } return n, nil }
func (c *BenchCommand) Recv(args []string) int { var config BenchRecvConfig if err := envconfig.Process("delayd2", &config); err != nil { c.Ui.Error(fmt.Sprintf("Unable to get configuration from envvars: %s", err)) return 1 } cmdFlags := flag.NewFlagSet("batch recv", flag.ContinueOnError) cmdFlags.IntVar(&config.NumberOfMessages, "n", 1000, "number of messages") if err := cmdFlags.Parse(args); err != nil { c.Ui.Error(c.Help()) return 1 } sqsSvc := sqs.New(session.New()) q, err := queue.New(sqsSvc, config.QueueName) if err != nil { c.Ui.Error(fmt.Sprintf("Unable to initialize SQS connection: %s", err)) return 1 } log.Print("bench: --- Configuration ---") log.Printf("bench: Number of messages to receive: %d", config.NumberOfMessages) log.Printf("bench: DELAYD2_QUEUE_NAME=%s", config.QueueName) errCh := make(chan error) log.Print("bench: starting") go func() { payloads := map[string]struct{}{} for { log.Printf("%d messages processed", len(payloads)) if len(payloads) >= config.NumberOfMessages { break } messages, err := q.ReceiveMessage( option.MaxNumberOfMessages(10), option.UseAllAttribute(), ) // continue even if we get an error if err != nil { log.Printf("unable to receive messages but continuing...: %s", err) continue } recipientHandles := make([]*string, 0, 10) for _, m := range messages { payloads[*m.Body] = struct{}{} recipientHandles = append(recipientHandles, m.ReceiptHandle) } if err := q.DeleteMessageBatch(recipientHandles...); err != nil { log.Printf("unable to delete message but continuing...: %s", err) } } log.Printf("%d messages received", config.NumberOfMessages) errCh <- nil }() select { case <-errCh: if err != nil { c.Ui.Error(fmt.Sprintf("Unable to receive messages: %s", err)) return 1 } log.Print("bench: done.") case <-c.ShutdownCh: log.Fatal("signal received.") } return 0 }