test_timeout.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package TestCode
  2. import (
  3. "fmt"
  4. "golang.org/x/net/context"
  5. "runtime"
  6. "sync"
  7. "time"
  8. )
  9. func hardWork(job interface{}) error {
  10. index := job.(int)
  11. println("Index:", index, "Start")
  12. time.Sleep(time.Second * 10)
  13. println("Index:", index, "End")
  14. return nil
  15. }
  16. func requestWork(ctx context.Context, job interface{}) error {
  17. ctx, cancel := context.WithTimeout(ctx, time.Second*2)
  18. defer cancel()
  19. done := make(chan error, 1)
  20. panicChan := make(chan interface{}, 1)
  21. go func() {
  22. defer func() {
  23. if p := recover(); p != nil {
  24. panicChan <- p
  25. }
  26. }()
  27. done <- hardWork(job)
  28. }()
  29. select {
  30. case err := <-done:
  31. return err
  32. case p := <-panicChan:
  33. panic(p)
  34. case <-ctx.Done():
  35. return ctx.Err()
  36. }
  37. }
  38. func Process() {
  39. const total = 10
  40. var wg sync.WaitGroup
  41. wg.Add(total)
  42. now := time.Now()
  43. for i := 0; i < total; i++ {
  44. go func(index int) {
  45. defer func() {
  46. if p := recover(); p != nil {
  47. fmt.Println("oops, panic")
  48. }
  49. }()
  50. defer wg.Done()
  51. requestWork(context.Background(), index)
  52. }(i)
  53. }
  54. wg.Wait()
  55. fmt.Println("elapsed:", time.Since(now))
  56. time.Sleep(time.Second * 20)
  57. fmt.Println("number of goroutines:", runtime.NumGoroutine())
  58. }