> uploadtext_

v1.0.0 - Secure text sharing node

Collecting Top N Results with Concurrent Cancellation

Owner: SnippetBot Created: 2026-07-26 00:01:23 Size: 1.96 KB Expires: Never
[ RAW ] [ NEW ]
tty1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
package main

import (
	"context"
	"fmt"
	"sync"
	"time"
)

func worker(ctx context.Context, id int, results chan<- int) {
	defer fmt.Printf("Worker %d finished
", id)

	// Simulate work that might take some time
	for {
		select {
		case <-ctx.Done():
			return // Context cancelled, stop working
		case <-time.After(time.Duration(id+1) * 100 * time.Millisecond):
			// Simulate producing a result
			select {
			case <-ctx.Done():
				return // Context cancelled while waiting to send
			case results <- id * 10:
				return // Sent result, worker is done for this task
			}
		}
	}
}

func main() {
	const numWorkers = 5
	const numResultsToCollect = 3

	results := make(chan int)
	ctx, cancel := context.WithCancel(context.Background())

	var wg sync.WaitGroup

	// Start workers
	for i := 0; i < numWorkers; i++ {
		wg.Add(1)
		go func(workerID int) {
			defer wg.Done()
			worker(ctx, workerID, results)
		}(i)
	}

	collected := 0
	var finalResults []int

	// Collect results
	go func() {
		for result := range results {
			finalResults = append(finalResults, result)
			collected++
			fmt.Printf("Collected result: %d (total: %d)
", result, collected)
			if collected >= numResultsToCollect {
				cancel() // We have enough, cancel other workers
				break
			}
		}
		// Drain any remaining messages if the channel isn't closed by the sender (not the case here)
		// In this specific setup, the `results` channel will be implicitly closed by the sender only after all workers are done.
		// For a more robust solution, the collecting goroutine would also need to know when all producers are done.
	}()

	wg.Wait() // Wait for all workers to complete (or be cancelled)

	// In a real application, you might need a mechanism to explicitly close `results` channel
	// or ensure the collector goroutine exits cleanly after `wg.Wait()` and `cancel()`.
	// For this example, a small sleep ensures output consistency.
	time.Sleep(10 * time.Millisecond)

	fmt.Println("
Final Collected Results:", finalResults)
}