controller.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package main
  2. import (
  3. "context"
  4. "coredemo/framework"
  5. "fmt"
  6. "time"
  7. )
  8. func FooControllerHandler(ctx *framework.Context) error {
  9. // 这个 channal 负责通知结束
  10. finish := make(chan struct{}, 1)
  11. // 这个 channel 负责通知 panic 异常
  12. panicChan := make(chan interface{}, 1)
  13. durationCtx, cancel := context.WithTimeout(ctx.BaseContext(), time.Duration(5*time.Second))
  14. defer cancel()
  15. {
  16. // 增加异常处理
  17. if p := recover(); p != nil {
  18. panicChan <- p
  19. }
  20. }
  21. go func() {
  22. // 这里做具体的业务
  23. time.Sleep(10 * time.Second)
  24. ctx.Json(200, "ok")
  25. // 结束的时候通过一个 finish 通道告知父 goroutine
  26. finish <- struct{}{}
  27. }()
  28. select {
  29. // 监听 panic
  30. case <-panicChan:
  31. ctx.WriterMux().Lock()
  32. defer ctx.WriterMux().Unlock()
  33. ctx.Json(500, "panic")
  34. // 监听结束
  35. case <-finish:
  36. fmt.Println("finish")
  37. // 监听超时
  38. case <-durationCtx.Done():
  39. ctx.WriterMux().Lock()
  40. defer ctx.WriterMux().Unlock()
  41. ctx.Json(500, "time out")
  42. // 这里记得设置标记
  43. ctx.SetHasTimeout()
  44. }
  45. return ctx.Json(200, map[string]interface{}{
  46. "code": 0,
  47. })
  48. }