package main import ( "fmt" "time" ) type Request struct { Payload string RespCh chan<- Response // Channel to send the response back } type Response struct { Data string Error error } // service processes requests from the inbound channel and sends responses. func service(inboundReqs <-chan Request) { for req := range inboundReqs { fmt.Printf("Service: Received request for '%s' ", req.Payload) // Simulate some work time.Sleep(time.Millisecond * 200) // Prepare response resp := Response{ Data: fmt.Sprintf("Processed: %s (at %s)", req.Payload, time.Now().Format("15:04:05")), } // Send response back on the dedicated response channel req.RespCh <- resp } fmt.Println("Service: Shutting down.") } func main() { const numRequests = 5 inboundRequests := make(chan Request) go service(inboundRequests) fmt.Println(" --- Client Making Requests ---") for i := 0; i < numRequests; i++ { // Each request gets its own response channel responseChannel := make(chan Response) req := Request{ Payload: fmt.Sprintf("Task-%d", i+1), RespCh: responseChannel, } inboundRequests <- req fmt.Printf("Client: Sent request for '%s', waiting for response... ", req.Payload) // Wait for response resp := <-responseChannel close(responseChannel) // Close the per-request response channel if resp.Error != nil { fmt.Printf("Client: Error processing '%s': %v ", req.Payload, resp.Error) } else { fmt.Printf("Client: Received response for '%s': %s ", req.Payload, resp.Data) } time.Sleep(time.Millisecond * 100) } close(inboundRequests) // Signal the service to shut down // Give service time to process the close signal and exit time.Sleep(time.Millisecond * 300) fmt.Println("Main: All requests processed and service stopped.") }