package main
import (
"context"
"fmt"
"time"
)
func BufferedChannelExample() {
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
fmt.Println(<-ch)
fmt.Println(<-ch)
fmt.Println(<-ch)
}
func CloseChannelExample() {
ch := make(chan int, 5)
go func() {
for i := 0; i < 5; i++ {
ch <- i
}
close(ch)
}()
for val := range ch {
fmt.Println("Received:", val)
}
}
func SelectExample() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
time.Sleep(100 * time.Millisecond)
ch1 <- "message from channel 1"
}()
go func() {
time.Sleep(200 * time.Millisecond)
ch2 <- "message from channel 2"
}()
select {
case msg := <-ch1:
fmt.Println(msg)
case msg := <-ch2:
fmt.Println(msg)
case <-time.After(150 * time.Millisecond):
fmt.Println("timeout")
}
}
func FanOutFanIn() {
input := make(chan int)
output1 := make(chan int)
output2 := make(chan int)
go func() {
for i := 0; i < 10; i++ {
input <- i
}
close(input)
}()
worker := func(in <-chan int, out chan<- int, factor int) {
for val := range in {
out <- val * factor
}
close(out)
}
go worker(input, output1, 2)
go worker(input, output2, 3)
for val := range output1 {
fmt.Println("Worker 1:", val)
}
}
func PipelinePattern() {
generator := func(nums ...int) <-chan int {
out := make(chan int)
go func() {
for _, n := range nums {
out <- n
}
close(out)
}()
return out
}
square := func(in <-chan int) <-chan int {
out := make(chan int)
go func() {
for n := range in {
out <- n * n
}
close(out)
}()
return out
}
printer := func(in <-chan int) {
for n := range in {
fmt.Println(n)
}
}
nums := generator(2, 3, 4, 5)
squared := square(nums)
printer(squared)
}
func ContextCancellation() {
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.Sleep(2 * time.Second)
cancel()
}()
select {
case <-ctx.Done():
fmt.Println("Cancelled:", ctx.Err())
case <-time.After(3 * time.Second):
fmt.Println("Completed normally")
}
}
func ContextTimeout() {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
select {
case <-time.After(2 * time.Second):
fmt.Println("Slow operation completed")
case <-ctx.Done():
fmt.Println("Timed out:", ctx.Err())
}
}
func ContextWithValue() {
type key string
ctx := context.WithValue(context.Background(), key("userID"), "12345")
if val := ctx.Value(key("userID")); val != nil {
fmt.Println("User ID:", val)
}
}
func NonBlockingSend(ch chan<- int, val int) bool {
select {
case ch <- val:
return true
default:
return false
}
}
func NonBlockingRecv(ch <-chan int) (int, bool) {
select {
case val := <-ch:
return val, true
default:
return 0, false
}
}
func TickerExample() {
ticker := time.NewTicker(500 * time.Millisecond)
defer ticker.Stop()
done := make(chan bool)
go func() {
time.Sleep(2 * time.Second)
done <- true
}()
for {
select {
case <-done:
fmt.Println("Done!")
return
case t := <-ticker.C:
fmt.Println("Tick at", t)
}
}
}
func Debounce(input <-chan string, duration time.Duration) <-chan string {
output := make(chan string)
go func() {
var timer *time.Timer
var last string
for msg := range input {
last = msg
if timer != nil {
timer.Stop()
}
timer = time.AfterFunc(duration, func() {
output <- last
})
}
close(output)
}()
return output
}
func main() {
BufferedChannelExample()
CloseChannelExample()
SelectExample()
}