servicegroup.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package service
  2. import (
  3. "log"
  4. "github.com/tal-tech/go-zero/core/proc"
  5. "github.com/tal-tech/go-zero/core/syncx"
  6. "github.com/tal-tech/go-zero/core/threading"
  7. )
  8. type (
  9. Starter interface {
  10. Start()
  11. }
  12. Stopper interface {
  13. Stop()
  14. }
  15. Service interface {
  16. Starter
  17. Stopper
  18. }
  19. ServiceGroup struct {
  20. services []Service
  21. stopOnce func()
  22. }
  23. )
  24. func NewServiceGroup() *ServiceGroup {
  25. sg := new(ServiceGroup)
  26. sg.stopOnce = syncx.Once(sg.doStop)
  27. return sg
  28. }
  29. func (sg *ServiceGroup) Add(service Service) {
  30. sg.services = append(sg.services, service)
  31. }
  32. // Start starts the ServiceGroup.
  33. // There should not be any logic code after calling this method, because this method is a blocking one.
  34. // Also, quitting this method will close the logx output.
  35. func (sg *ServiceGroup) Start() {
  36. proc.AddShutdownListener(func() {
  37. log.Println("Shutting down...")
  38. sg.stopOnce()
  39. })
  40. sg.doStart()
  41. }
  42. func (sg *ServiceGroup) Stop() {
  43. sg.stopOnce()
  44. }
  45. func (sg *ServiceGroup) doStart() {
  46. routineGroup := threading.NewRoutineGroup()
  47. for i := range sg.services {
  48. service := sg.services[i]
  49. routineGroup.RunSafe(func() {
  50. service.Start()
  51. })
  52. }
  53. routineGroup.Wait()
  54. }
  55. func (sg *ServiceGroup) doStop() {
  56. for _, service := range sg.services {
  57. service.Stop()
  58. }
  59. }
  60. func WithStart(start func()) Service {
  61. return startOnlyService{
  62. start: start,
  63. }
  64. }
  65. func WithStarter(start Starter) Service {
  66. return starterOnlyService{
  67. Starter: start,
  68. }
  69. }
  70. type (
  71. stopper struct {
  72. }
  73. startOnlyService struct {
  74. start func()
  75. stopper
  76. }
  77. starterOnlyService struct {
  78. Starter
  79. stopper
  80. }
  81. )
  82. func (s stopper) Stop() {
  83. }
  84. func (s startOnlyService) Start() {
  85. s.start()
  86. }