provider.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. package worker
  2. import (
  3. "os"
  4. "sync"
  5. "sync/atomic"
  6. "time"
  7. )
  8. // mirror provider is the wrapper of mirror jobs
  9. type providerType uint8
  10. const (
  11. _WorkingDirKey = "working_dir"
  12. _LogDirKey = "log_dir"
  13. _LogFileKey = "log_file"
  14. )
  15. // A mirrorProvider instance
  16. type mirrorProvider interface {
  17. // name
  18. Name() string
  19. // run mirror job in background
  20. Run() error
  21. // run mirror job in background
  22. Start() error
  23. // Wait job to finish
  24. Wait() error
  25. // terminate mirror job
  26. Terminate() error
  27. // job hooks
  28. IsRunning() bool
  29. Hooks() []jobHook
  30. Interval() time.Duration
  31. WorkingDir() string
  32. LogDir() string
  33. LogFile() string
  34. // enter context
  35. EnterContext() *Context
  36. // exit context
  37. ExitContext() *Context
  38. // return context
  39. Context() *Context
  40. }
  41. type baseProvider struct {
  42. sync.Mutex
  43. ctx *Context
  44. name string
  45. interval time.Duration
  46. cmd *cmdJob
  47. isRunning atomic.Value
  48. logFile *os.File
  49. hooks []jobHook
  50. }
  51. func (p *baseProvider) Name() string {
  52. return p.name
  53. }
  54. func (p *baseProvider) EnterContext() *Context {
  55. p.ctx = p.ctx.Enter()
  56. return p.ctx
  57. }
  58. func (p *baseProvider) ExitContext() *Context {
  59. p.ctx, _ = p.ctx.Exit()
  60. return p.ctx
  61. }
  62. func (p *baseProvider) Context() *Context {
  63. return p.ctx
  64. }
  65. func (p *baseProvider) Interval() time.Duration {
  66. return p.interval
  67. }
  68. func (p *baseProvider) WorkingDir() string {
  69. if v, ok := p.ctx.Get(_WorkingDirKey); ok {
  70. if s, ok := v.(string); ok {
  71. return s
  72. }
  73. }
  74. panic("working dir is impossible to be non-exist")
  75. }
  76. func (p *baseProvider) LogDir() string {
  77. if v, ok := p.ctx.Get(_LogDirKey); ok {
  78. if s, ok := v.(string); ok {
  79. return s
  80. }
  81. }
  82. panic("log dir is impossible to be unavailable")
  83. }
  84. func (p *baseProvider) LogFile() string {
  85. if v, ok := p.ctx.Get(_LogFileKey); ok {
  86. if s, ok := v.(string); ok {
  87. return s
  88. }
  89. }
  90. panic("log dir is impossible to be unavailable")
  91. }
  92. func (p *baseProvider) AddHook(hook jobHook) {
  93. p.hooks = append(p.hooks, hook)
  94. }
  95. func (p *baseProvider) Hooks() []jobHook {
  96. return p.hooks
  97. }
  98. func (p *baseProvider) setLogFile() error {
  99. if p.LogFile() == "/dev/null" {
  100. p.cmd.SetLogFile(nil)
  101. return nil
  102. }
  103. if p.logFile == nil {
  104. logFile, err := os.OpenFile(p.LogFile(), os.O_WRONLY|os.O_CREATE, 0644)
  105. if err != nil {
  106. logger.Error("Error opening logfile %s: %s", p.LogFile(), err.Error())
  107. return err
  108. }
  109. p.logFile = logFile
  110. }
  111. p.cmd.SetLogFile(p.logFile)
  112. return nil
  113. }
  114. func (p *baseProvider) Run() error {
  115. panic("Not Implemented")
  116. }
  117. func (p *baseProvider) Start() error {
  118. panic("Not Implemented")
  119. }
  120. func (p *baseProvider) IsRunning() bool {
  121. isRunning, _ := p.isRunning.Load().(bool)
  122. return isRunning
  123. }
  124. func (p *baseProvider) Wait() error {
  125. defer func() {
  126. p.Lock()
  127. p.isRunning.Store(false)
  128. if p.logFile != nil {
  129. p.logFile.Close()
  130. p.logFile = nil
  131. }
  132. p.Unlock()
  133. }()
  134. return p.cmd.Wait()
  135. }
  136. func (p *baseProvider) Terminate() error {
  137. logger.Debug("terminating provider: %s", p.Name())
  138. if !p.IsRunning() {
  139. return nil
  140. }
  141. p.Lock()
  142. if p.logFile != nil {
  143. p.logFile.Close()
  144. p.logFile = nil
  145. }
  146. p.Unlock()
  147. err := p.cmd.Terminate()
  148. p.isRunning.Store(false)
  149. return err
  150. }