How do I queue email sending with retries in Go?

In Go, you can implement a queue for sending emails with retries by leveraging goroutines and channels. This method helps manage sending emails effectively by allowing for retries on failure, ensuring that emails are sent reliably.

Keywords: Go, Email Queue, Retry, Goroutines, Channels
Description: This example demonstrates how to queue email sending in Go with a retry mechanism to ensure that emails are sent successfully even in the event of temporary failures.

package main

import (
	"fmt"
	"log"
	"math/rand"
	"time"
)

type Email struct {
	To      string
	Subject string
	Body    string
}

func sendEmail(email Email) error {
	// Simulate email sending with a random success/failure
	if rand.Intn(2) == 0 {
		return fmt.Errorf("failed to send email to %s", email.To)
	}
	fmt.Printf("Email sent to %s: %s\n", email.To, email.Subject)
	return nil
}

func queueEmail(email Email, retries int) {
	for i := 0; i < retries; i++ {
		err := sendEmail(email)
		if err != nil {
			log.Printf("Attempt %d: %v\n", i+1, err)
			time.Sleep(time.Second * 2) // wait 2 seconds before retrying
			continue // retry sending
		}
		break // email sent successfully; break out of the loop
	}
}

func main() {
	rand.Seed(time.Now().UnixNano())

	emails := []Email{
		{"user1@example.com", "Subject 1", "Body 1"},
		{"user2@example.com", "Subject 2", "Body 2"},
		{"user3@example.com", "Subject 3", "Body 3"},
	}

	for _, email := range emails {
		go queueEmail(email, 3) // start the email sending in a goroutine with 3 retries
	}

	// Wait for all goroutines to finish
	time.Sleep(time.Second * 10) // Simulate waiting for emails to be sent
}

Keywords: Go Email Queue Retry Goroutines Channels