package main import ( "context" "fmt" "sync" "errors" "time" ) func Rpc(ctx context.Context, url string, isSuccess bool) error { result := make(chan int) err := make(chan error) if url == "http://rpc_2_url" { time.Sleep(time.Second * 5) } if url == "http://rpc_4_url" { time.Sleep(time.Second * 30) } go func() { // 进行RPC调用,并且返回是否成功,成功通过result传递成功信息,错误通过error传递错误信息 if isSuccess { result <- 1 } else { err <- errors.New("some error happen") } }() select { case <-ctx.Done(): // 其他RPC调用调用失败 fmt.Println("ctx.Done") return ctx.Err() case e := <-err: // 本RPC调用失败,返回错误信息 fmt.Println("err", url, e) return e case <-result: fmt.Println("result", url, result) // 本RPC调用成功,不返回错误信息 return nil } } func main() { ctx, cancel := context.WithCancel(context.Background()) //RPC1调用 err := Rpc(ctx, "http://rpc_1_url", true) if err != nil { fmt.Println("err11111", err) return } wg := sync.WaitGroup{} // RPC2调用 wg.Add(1) go func() { defer wg.Done() err := Rpc(ctx, "http://rpc_2_url", true) if err != nil { fmt.Println("err2", err) cancel() } }() // RPC3调用 wg.Add(1) go func() { defer wg.Done() err := Rpc(ctx, "http://rpc_3_url", false) if err != nil { fmt.Println("err3", err) cancel() } }() // RPC4调用 wg.Add(1) go func() { defer wg.Done() err := Rpc(ctx, "http://rpc_4_url", true) if err != nil { fmt.Println("err4", err) fmt.Println("RPC4 取消") cancel() } }() wg.Wait() }