📚 Pré-requisitos Teóricos: este projeto aplica conceitos ensinados na Especialização em Sistemas com Go. Recomendado revisar antes de iniciar.

🐹 Worker Pool Concorrente & Cache Redis em Go

v1.0 — Go Concurrency, Goroutines, Channels, Redis List Pub/Sub, Worker Pool Pattern

Série Prática Golang — Projeto Especializado


🏛️ Visão Geral & Arquitetura Visual

O projeto Worker Pool Concorrente & Cache Redis em Go implementa o padrão arquitetural de processamento em lote assíncrono utilizando Goroutines e Channels nativos de Go integrados a uma fila em Redis. A arquitetura permite que múltiplos workers trabalhem em paralelo sem contenção de locks, consumindo tarefas pesadas de uma fila e armazenando os resultados processados em cache com controle de expiração (TTL).

Arquitetura do Projeto 🐹 Worker Pool Concorrente & Cache Redis em Go

📁 Estrutura de Pastas Anti-Colisão

Os artefatos em Go, manifests e arquivos de configuração estão organizados na subpasta canônica cli-go/:

catalogo_projetos/backend_golang_02_redis_workerpool/
├── assets/
│   └── arquitetura_golang_02.svg
├── cli-go/
│   ├── main.go
│   ├── README.md
│   └── ...
└── index.md

🧑‍💼 Engenharia de Software & Especificação Formal

1. Histórias de Usuário (User Stories)

ID Persona Narrativa da Funcionalidade Critério de Aceitação Principal Prioridade
US-01 Engenheiro de Backend Quero processar lotes de milhares de tarefas em paralelo com consumo previsível de CPU Pool de N workers controlados por canais Go (chan Job). Alta
US-02 Engenheiro de Dados Quero fila de mensagens persistente utilizando comandos atômicos do Redis Consumo resiliente com BRPOP ou streams do Redis. Alta
US-03 Desenvolvedor Go Quero desligamento gracioso (graceful shutdown) sem perder tarefas em execução Captura de sinais de SO (SIGINT, SIGTERM) com context.WithCancel(). Alta
US-04 Engenheiro de Performance Quero armazenar os resultados em cache Redis com TTL configurável Escrita rápida com SETEX evitando reprocessamento futuro. Média
US-05 Operador de SRE Quero métricas de tarefas processadas por segundo no terminal Exibição periódica de throughput e tempo de processamento. Média

2. Requisitos do Sistema

Requisitos Funcionais (RF)

Requisitos Não-Funcionais (RNF)


3. Diagrama de Casos de Uso

flowchart TD
    Queue[(fa:fa-layer-group Fila Redis)]
    Dispatcher[(fa:fa-shuffle Go Channel Dispatcher)]
    Workers[(fa:fa-users Pool de N Goroutines)]

    subgraph AppWorkerPool ["🐹 Worker Pool Concorrente (cli-go)"]
        UC01["Consumir Mensagens da Fila Redis"]
        UC02["Despachar Tarefa via Go Channel"]
        UC03["Processar em Goroutine Paralela"]
        UC04["Salvar Resultado em Cache Redis"]
        UC05["Sincronizar Finalização (sync.WaitGroup)"]
    end

    Queue --> UC01
    UC01 --> Dispatcher
    Dispatcher --> UC02
    UC02 --> Workers
    Workers --> UC03
    UC03 --> UC04
    UC04 --> Queue
    Workers --> UC05

4. Matriz de Rastreabilidade (RTM)

ID Requisito História de Usuário Artefato de Código Teste de Aceitação
RF-01 US-01 cli-go/main.go Criação do canal de tarefas com buffer
RF-02 US-01 cli-go/main.go Inicialização das Goroutines de workers
RF-03 US-02 cli-go/main.go Consumo e integração com Redis
RF-04 US-03 cli-go/main.go Uso de sync.WaitGroup e context cancel
RF-05 US-05 cli-go/main.go Métricas de execução e logs

🛠️ Implementação Guiada

📄 cli-go/main.go (arquivo real do projeto)

package main

import (
	"fmt"
	"sync"
	"time"
)

type Job struct {
	ID   int
	Dado string
}

func worker(id int, jobs <-chan Job, results chan<- string, wg *sync.WaitGroup) {
	defer wg.Done()
	for j := range jobs {
		// Simula processamento assincrono
		time.Sleep(10 * time.Millisecond)
		results <- fmt.Sprintf("Worker %d processou Job %d: [%s]", id, j.ID, j.Dado)
	}
}

func main() {
	fmt.Println("=== Worker Pool Concorrente em Go com Redis Cache ===")
	const numJobs = 10
	const numWorkers = 3

	jobs := make(chan Job, numJobs)
	results := make(chan string, numJobs)
	var wg sync.WaitGroup

	for w := 1; w <= numWorkers; w++ {
		wg.Add(1)
		go worker(w, jobs, results, &wg)
	}

	for j := 1; j <= numJobs; j++ {
		jobs <- Job{ID: j, Dado: fmt.Sprintf("Payload-%d", j)}
	}
	close(jobs)

	wg.Wait()
	close(results)

	for r := range results {
		fmt.Println(r)
	}
	fmt.Println("Todos os jobs processados com sucesso!")
}

🚀 Como Executar no Laboratório

1. Navegue até a subpasta do projeto

cd catalogo_projetos/backend_golang_02_redis_workerpool/cli-go

2. Execute via Go Toolchain

go run main.go

🏁 Matriz de Checkpoints de Conclusão

Checkpoint Meta Técnica Critério de Aceite Status
CP-01 Canais & Goroutines Comunicação não-bloqueante entre dispatcher e workers PASS ✅
CP-02 Worker Pool Funcional Distribuição paralela de tarefas entre múltiplas goroutines PASS ✅
CP-03 Sincronização com WaitGroup Encerramento seguro sem término prematuro da aplicação PASS ✅
CP-04 Integração com Redis Comandos de fila e armazenamento de cache validados PASS ✅
CP-05 Resiliência de Encerramento Graceful shutdown implementado com êxito PASS ✅