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.

▶ Open Go Playground

Copy the code above and paste to run

© 2026 ByteLearn.dev. Free courses for developers. · Privacy