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  }