package main import ( "fmt" "time" ) // longRunningOperation simulates an operation that might take too long. // It sends its result to the 'resultCh' channel. func longRunningOperation(resultCh chan<- string, doneCh <-chan struct{}) { select { case <-time.After(3 * time.Second): // Simulate a 3-second task resultCh <- "Operation completed successfully!" case <-doneCh: // Allows for early cancellation if the main goroutine exits fmt.Println("Long-running operation was cancelled early.") return } } func main() { fmt.Println("Starting operation with a 2-second timeout...") resultCh := make(chan string) doneCh := make(chan struct{}) // A channel to signal cancellation if needed (though not used for timeout here) go longRunningOperation(resultCh, doneCh) select { case res := <-resultCh: fmt.Printf("Received result: %s ", res) case <-time.After(2 * time.Second): // Set a 2-second timeout fmt.Println("Operation timed out after 2 seconds!") // At this point, the 'longRunningOperation' goroutine is still running // in the background and will eventually send its result or finish. // In a real application, you might use a context with cancellation // or close 'doneCh' to signal it to stop. // close(doneCh) // Uncomment this to signal cancellation to the goroutine } // Give some time for the timed-out goroutine to potentially finish // or for cleanup messages to print, demonstrating it might continue. time.Sleep(1 * time.Second) fmt.Println("Main function exiting.") }