> uploadtext_

v1.0.0 - Secure text sharing node

Adding Timeouts to Blocking Channel Operations

Owner: SnippetBot Created: 2026-07-17 00:00:28 Size: 2.45 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 79 80 81 82
package main

import (
	"fmt"
	"time"
)

// doWorkWithTimeout simulates a task that might take a variable amount of time.
// It attempts to send a result on a channel, but respects a timeout.
func doWorkWithTimeout(id int, resultCh chan<- string, timeout time.Duration) {
	fmt.Printf("Worker %d: Started work...
", id)

	// Simulate work that takes a random duration.
	sleepTime := time.Duration(id*100 + 200) * time.Millisecond // Vary sleep time based on ID
	// Make some workers intentionally slow to trigger timeout
	if id%2 == 0 {
		sleepTime += 500 * time.Millisecond 
	}
	time.Sleep(sleepTime)

	output := fmt.Sprintf("Worker %d: Work finished after %v", id, sleepTime)

	select {
	case resultCh <- output: // Try to send the result.
		fmt.Printf("Worker %d: Result sent successfully.
", id)
	case <-time.After(timeout): // If sending takes longer than the timeout.
		fmt.Printf("Worker %d: Timeout while trying to send result. Result was: %q (slept %v)
", id, output, sleepTime)
	}
}

// receiveWithTimeout attempts to receive a value from a channel with a timeout.
func receiveWithTimeout(id int, inputCh <-chan string, timeout time.Duration) (string, bool) {
	fmt.Printf("Main: Attempting to receive result for worker %d with timeout %v...
", id, timeout)

	select {
	case result := <-inputCh:
		fmt.Printf("Main: Successfully received result for worker %d: %q
", id, result)
		return result, true
	case <-time.After(timeout):
		fmt.Printf("Main: Timeout while waiting for result from worker %d
", id)
		return "", false
	}
}

func main() {
	const numWorkers = 5
	results := make(chan string, numWorkers)

	fmt.Println("Starting workers...")
	for i := 1; i <= numWorkers; i++ {
		go doWorkWithTimeout(i, results, 300*time.Millisecond) // Worker send timeout
	}

	// Give workers some time to start and potentially send results
	time.Sleep(100 * time.Millisecond)

	fmt.Println("
--- Main goroutine collecting results ---")
	for i := 1; i <= numWorkers; i++ {
		// For demonstration, we'll try to receive with a different timeout for each worker's result.
		receiveTimeout := 400 * time.Millisecond
		if i == 2 { // Make one receiver deliberately too fast
			receiveTimeout = 100 * time.Millisecond 
		}
		if i == 4 { // Make another receiver very patient
			receiveTimeout = 1 * time.Second
		}

		receiveWithTimeout(i, results, receiveTimeout)
	}

	fmt.Println("
Main goroutine finished collecting. Giving workers time to finish logging...")
	time.Sleep(1 * time.Second)
	fmt.Println("Exiting.")
}