Skip to content

Instantly share code, notes, and snippets.

@nelsonr
Last active May 5, 2025 22:46
Show Gist options
  • Save nelsonr/49b272f7c2a4c50a67d52dc268bd473a to your computer and use it in GitHub Desktop.
Save nelsonr/49b272f7c2a4c50a67d52dc268bd473a to your computer and use it in GitHub Desktop.
Example of sequential channels in Go
package bakery
import (
"fmt"
"time"
)
type Order = int
type Cake struct {
orderId Order
baked bool
decorated bool
packed bool
}
// Create channels
var orders = make(chan Order)
var baked = make(chan *Cake)
var decorated = make(chan *Cake)
var packed = make(chan *Cake)
// baker receives order messages and sends out cake messages
func baker(baked chan<- *Cake, orders <-chan Order) {
defer close(baked)
for order := range orders {
cake := new(Cake)
cake.orderId = order
cake.baked = true
baked <- cake
}
}
// decorator receives and sends out cake messages
func decorator(decorated chan<- *Cake, cooked <-chan *Cake) {
defer close(iced)
for cake := range cooked {
cake.decorated = true
decorated <- cake
}
}
// packer receives and sends out cake messages
func packer(packed chan<- *Cake, decorated <-chan *Cake) {
defer close(packed)
for cake := range decorated {
cake.packed = true
packed <- cake
}
}
func main() {
done := make(chan bool)
// Start workers
go baker(baked, orders)
go decorator(decorated, baked)
go packer(packed, decorated)
// Log finished cakes
go func() {
for cake := range packed {
fmt.Printf("Cake #%d is ready\n", cake.orderId)
}
done <- true
}()
// Send orders
go func() {
defer close(orders)
// Send an order every 1 second
for n := range 10 {
orders <- n + 1
time.Sleep(1 * time.Second)
}
}()
// Wait for the done message
<-done
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment