func (worker *Worker) run(h Handler, messages []*sqs.Message) {
	numMessages := len(messages)
	worker.Log.Info(fmt.Sprintf("worker: Received %d messages", numMessages))
	var wg sync.WaitGroup
	wg.Add(numMessages)
	for i := range messages {
		go func(m *sqs.Message) {
			defer wg.Done()
			if err := worker.handleMessage(m, h); err != nil {
				worker.Log.Error(err.Error())
			}
		}(messages[i])
	}
	wg.Wait()
}
poll launches goroutine per received message and wait for all message to be processed
package worker
import (
	"context"
	"fmt"
	"log"
	"sync"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/sqs"
)
type HandlerFunc func(msg *sqs.Message) error
func (f HandlerFunc) HandleMessage(msg *sqs.Message) error {
	return f(msg)
}
type Handler interface {
	HandleMessage(msg *sqs.Message) error
}
type InvalidEventError struct {
	event string
	msg   string
}
func (e InvalidEventError) Error() string {
	return fmt.Sprintf("[Invalid Event: %s] %s", e.event, e.msg)
}
func NewInvalidEventError(event, msg string) InvalidEventError {
	return InvalidEventError{event: event, msg: msg}
}
type QueueAPI interface {
	GetQueueUrl(*sqs.GetQueueUrlInput) (*sqs.GetQueueUrlOutput, error)
	QueueDeleteReceiverAPI
}
type QueueDeleteReceiverAPI interface {
	DeleteMessage(*sqs.DeleteMessageInput) (*sqs.DeleteMessageOutput, error)
	ReceiveMessage(*sqs.ReceiveMessageInput) (*sqs.ReceiveMessageOutput, error)
}
type Worker struct {
	Config    *Config
	Log       LoggerIFace
	SqsClient QueueDeleteReceiverAPI
}
type Config struct {
	MaxNumberOfMessage int64
	QueueName          string
	QueueURL           string
	WaitTimeSecond     int64
}
func New(client QueueAPI, config *Config) *Worker {
	config.populateDefaultValues()
	config.QueueURL = getQueueURL(client, config.QueueName)
	return &Worker{
		Config:    config,
		Log:       &logger{},
		SqsClient: client,
	}
}
func (worker *Worker) Start(ctx context.Context, h Handler) {
	for {
		select {
		case <-ctx.Done():
			log.Println("worker: Stopping polling because a context kill signal was sent")
			return
		default:
			worker.Log.Debug("worker: Start Polling")
			params := &sqs.ReceiveMessageInput{
				QueueUrl:            aws.String(worker.Config.QueueURL),  
				MaxNumberOfMessages: aws.Int64(worker.Config.MaxNumberOfMessage),
				AttributeNames: []*string{
					aws.String("All"),  
				},
				WaitTimeSeconds: aws.Int64(worker.Config.WaitTimeSecond),
			}
			resp, err := worker.SqsClient.ReceiveMessage(params)
			if err != nil {
				log.Println(err)
				continue
			}
			if len(resp.Messages) > 0 {
				worker.run(h, resp.Messages)
			}
		}
	}
}