servicegroup.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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. // There should not be any logic code after calling this method, because this method is a blocking one.
  33. // Also, quitting this method will close the logx output.
  34. func (sg *ServiceGroup) Start() {
  35. proc.AddShutdownListener(func() {
  36. log.Println("Shutting down...")
  37. sg.stopOnce()
  38. })
  39. sg.doStart()
  40. }
  41. func (sg *ServiceGroup) Stop() {
  42. sg.stopOnce()
  43. }
  44. func (sg *ServiceGroup) doStart() {
  45. routineGroup := threading.NewRoutineGroup()
  46. for i := range sg.services {
  47. service := sg.services[i]
  48. routineGroup.RunSafe(func() {
  49. service.Start()
  50. })
  51. }
  52. routineGroup.Wait()
  53. }
  54. func (sg *ServiceGroup) doStop() {
  55. for _, service := range sg.services {
  56. service.Stop()
  57. }
  58. }
  59. func WithStart(start func()) Service {
  60. return startOnlyService{
  61. start: start,
  62. }
  63. }
  64. func WithStarter(start Starter) Service {
  65. return starterOnlyService{
  66. Starter: start,
  67. }
  68. }
  69. type (
  70. stopper struct {
  71. }
  72. startOnlyService struct {
  73. start func()
  74. stopper
  75. }
  76. starterOnlyService struct {
  77. Starter
  78. stopper
  79. }
  80. )
  81. func (s stopper) Stop() {
  82. }
  83. func (s startOnlyService) Start() {
  84. s.start()
  85. }