github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/jobs/active_users/worker.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package active_users 5 6 import ( 7 "net/http" 8 9 "github.com/masterhung0112/hk_server/v5/app" 10 "github.com/masterhung0112/hk_server/v5/jobs" 11 tjobs "github.com/masterhung0112/hk_server/v5/jobs/interfaces" 12 "github.com/masterhung0112/hk_server/v5/model" 13 "github.com/masterhung0112/hk_server/v5/shared/mlog" 14 ) 15 16 const ( 17 JobName = "ActiveUsers" 18 ) 19 20 type Worker struct { 21 name string 22 stop chan bool 23 stopped chan bool 24 jobs chan model.Job 25 jobServer *jobs.JobServer 26 app *app.App 27 } 28 29 func init() { 30 app.RegisterJobsActiveUsersInterface(func(s *app.Server) tjobs.ActiveUsersJobInterface { 31 a := app.New(app.ServerConnector(s)) 32 return &ActiveUsersJobInterfaceImpl{a} 33 }) 34 } 35 36 type ActiveUsersJobInterfaceImpl struct { 37 App *app.App 38 } 39 40 func (m *ActiveUsersJobInterfaceImpl) MakeWorker() model.Worker { 41 worker := Worker{ 42 name: JobName, 43 stop: make(chan bool, 1), 44 stopped: make(chan bool, 1), 45 jobs: make(chan model.Job), 46 jobServer: m.App.Srv().Jobs, 47 app: m.App, 48 } 49 return &worker 50 } 51 52 func (worker *Worker) Run() { 53 mlog.Debug("Worker started", mlog.String("worker", worker.name)) 54 55 defer func() { 56 mlog.Debug("Worker finished", mlog.String("worker", worker.name)) 57 worker.stopped <- true 58 }() 59 60 for { 61 select { 62 case <-worker.stop: 63 mlog.Debug("Worker received stop signal", mlog.String("worker", worker.name)) 64 return 65 case job := <-worker.jobs: 66 mlog.Debug("Worker received a new candidate job.", mlog.String("worker", worker.name)) 67 worker.DoJob(&job) 68 } 69 } 70 } 71 72 func (worker *Worker) Stop() { 73 mlog.Debug("Worker stopping", mlog.String("worker", worker.name)) 74 worker.stop <- true 75 <-worker.stopped 76 } 77 78 func (worker *Worker) JobChannel() chan<- model.Job { 79 return worker.jobs 80 } 81 82 func (worker *Worker) DoJob(job *model.Job) { 83 if claimed, err := worker.jobServer.ClaimJob(job); err != nil { 84 mlog.Warn("Worker experienced an error while trying to claim job", 85 mlog.String("worker", worker.name), 86 mlog.String("job_id", job.Id), 87 mlog.String("error", err.Error())) 88 return 89 } else if !claimed { 90 return 91 } 92 93 count, err := worker.app.Srv().Store.User().Count(model.UserCountOptions{IncludeDeleted: false}) 94 95 if err != nil { 96 mlog.Error("Worker: Failed to get active user count", mlog.String("worker", worker.name), mlog.String("job_id", job.Id), mlog.String("error", err.Error())) 97 worker.setJobError(job, model.NewAppError("DoJob", "app.user.get_total_users_count.app_error", nil, err.Error(), http.StatusInternalServerError)) 98 return 99 } 100 101 if worker.app.Metrics() != nil { 102 worker.app.Metrics().ObserveEnabledUsers(count) 103 } 104 105 mlog.Info("Worker: Job is complete", mlog.String("worker", worker.name), mlog.String("job_id", job.Id)) 106 worker.setJobSuccess(job) 107 } 108 109 func (worker *Worker) setJobSuccess(job *model.Job) { 110 if err := worker.app.Srv().Jobs.SetJobSuccess(job); err != nil { 111 mlog.Error("Worker: Failed to set success for job", mlog.String("worker", worker.name), mlog.String("job_id", job.Id), mlog.String("error", err.Error())) 112 worker.setJobError(job, err) 113 } 114 } 115 116 func (worker *Worker) setJobError(job *model.Job, appError *model.AppError) { 117 if err := worker.app.Srv().Jobs.SetJobError(job, appError); err != nil { 118 mlog.Error("Worker: Failed to set job error", mlog.String("worker", worker.name), mlog.String("job_id", job.Id), mlog.String("error", err.Error())) 119 } 120 }