Live coding: Go tasks — concurrent requests, closures in goroutines, duplicate filtering, thread-safe counter, buffered channels, function timeout
sobes.tech AI
Answer from AI
In Go, it is often necessary to write concurrent code with goroutines and channels. Let's consider key points:
-
Concurrent requests — you can launch multiple goroutines, each performing a request, and collect results through a channel.
-
Closures in goroutines — it is important to correctly capture loop variables to avoid errors with shared state.
-
Filtering duplicates — you can use a map to track already encountered values.
-
Thread-safe counter — use sync.Mutex or atomic operations.
-
Buffered channels — allow sending multiple values without blocking the sender.
-
Function timeout — implemented via select with time.After.
An example that combines several of these aspects:
package main
import (
"fmt"
"sync"
"time"
"math/rand"
)
func main() {
// Buffered channel for results
results := make(chan int, 5)
var wg sync.WaitGroup
// Thread-safe counter
var mu sync.Mutex
counter := 0
// Set for filtering duplicates
seen := make(map[int]bool)
// Launch 5 concurrent goroutines
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
// Closure with copy of id
time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond)
value := id * 10
// Send result to channel with timeout
select {
case results <- value:
// Increment counter safely
mu.Lock()
counter++
mu.Unlock()
case <-time.After(300 * time.Millisecond):
fmt.Printf("Goroutine %d: timeout when sending\n", id)
}
}(i)
}
// Close channel after all goroutines finish
go func() {
wg.Wait()
close(results)
}()
// Read from channel and filter duplicates
for val := range results {
if !seen[val] {
fmt.Println("Received unique value:", val)
seen[val] = true
} else {
fmt.Println("Duplicate skipped:", val)
}
}
fmt.Println("Total unique values sent:", counter)
}
This example demonstrates:
- Launching concurrent goroutines with closure (copy of id in function parameter).
- Using a buffered channel to collect results.
- Timeout when sending to the channel.
- Thread-safe increment of the counter.
- Filtering duplicates when reading from the channel.
This approach is often used for parallel processing and result collection with time and safety controls.