Skip to content

Instantly share code, notes, and snippets.

@garukun
Last active April 14, 2023 09:47
Show Gist options
  • Save garukun/2acb859dbaaf4a8888e7 to your computer and use it in GitHub Desktop.
Save garukun/2acb859dbaaf4a8888e7 to your computer and use it in GitHub Desktop.
Go example regarding channels and backpressure
// https://play.golang.org/p/z2eYKhyoIk
package main
import "fmt"
import "time"
import "sync"
// Blocking detection for when pushing on filled buffered channel by using default.
func main() {
ch1 := make(chan int, 2)
ch1 <- 1
ch1 <- 2
var wg sync.WaitGroup
wg.Add(1)
// Simple goroutine to drain the channel after a second.
go func() {
time.Sleep(time.Second)
fmt.Println("Draining channel!")
for range ch1 {}
wg.Done()
}()
for {
select {
// Imagine that we want to send ch1 some work, and at the
// same time know about the channels backpressure.
case ch1 <- 3:
close(ch1)
wg.Wait()
fmt.Println("Done!")
return
default:
fmt.Println("No more room on channel, wait a little.")
time.Sleep(time.Duration(100) * time.Millisecond)
}
}
}
// https://play.golang.org/p/BaNEsD1hSu
package main
import "fmt"
import "time"
// Multiple workers draining work from the same channel. This could be used to
// handle fast -> slow process.
func main() {
work := make(chan int)
// Spawn 10 workers
for i := 0; i < 10; i++ {
go doWork(i, work)
}
// Generate some work.
for i := 0; i < 100; i++ {
work <- i
}
close(work)
// Sleep little to allow the last bit of work to finish in the goroutine.
time.Sleep(time.Second)
}
func doWork(id int, work <-chan int) {
fmt.Printf("Worker %d started.\n", id)
for i := range work {
fmt.Printf("Work on %d by %d\n", i, id)
time.Sleep(time.Duration(100) * time.Millisecond)
}
fmt.Printf("Worker %d finsihed.\n", id)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment