Pizza Shop
A pizza shop simulation using the producer-consumer pattern. The kitchen (producer) takes orders and attempts to make pizzas — some succeed, some fail. The front counter (consumer) delivers results.
package main
import (
"fmt"
"math/rand"
"time"
)
const totalOrders = 10
type PizzaOrder struct {
number int
message string
success bool
}
// Producer: the kitchen takes orders and attempts to make pizzas
func kitchen(orders chan<- PizzaOrder) {
defer close(orders) // kitchen closes when done — producer closes the channel
for i := 1; i <= totalOrders; i++ {
delay := rand.Intn(3) + 1
fmt.Printf("Order #%d received, making pizza (%ds)...\n", i, delay)
time.Sleep(time.Duration(delay) * time.Second) // simulate cooking
// random chance of failure
switch rnd := rand.Intn(12) + 1; {
case rnd <= 2:
orders <- PizzaOrder{i, fmt.Sprintf("❌ Order #%d: ran out of ingredients!", i), false}
case rnd <= 4:
orders <- PizzaOrder{i, fmt.Sprintf("❌ Order #%d: the cook burned the pizza!", i), false}
default:
orders <- PizzaOrder{i, fmt.Sprintf("✅ Order #%d is ready!", i), true}
}
}
}
// Consumer: the front counter delivers results to customers
func main() {
orders := make(chan PizzaOrder)
go kitchen(orders) // producer runs in background
var made, failed int
for order := range orders { // consumer reads until channel closes
fmt.Println(order.message)
if order.success {
made++
} else {
failed++
}
}
fmt.Println("-----------------")
fmt.Printf("Made: %d, Failed: %d, Total: %d\n", made, failed, made+failed)
}The kitchen (producer) sends pizza orders through the channel and closes it when done. The main function (consumer) ranges over the channel until it closes. Clean separation — the producer doesn't know about the consumer, they only share the channel.