github.com/haalcala/mattermost-server-change-repo@v0.0.0-20210713015153-16753fbeee5f/jobs/export_delete/worker.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package export_delete
     5  
     6  import (
     7  	"path/filepath"
     8  	"time"
     9  
    10  	"github.com/mattermost/mattermost-server/v5/app"
    11  	"github.com/mattermost/mattermost-server/v5/jobs"
    12  	tjobs "github.com/mattermost/mattermost-server/v5/jobs/interfaces"
    13  	"github.com/mattermost/mattermost-server/v5/mlog"
    14  	"github.com/mattermost/mattermost-server/v5/model"
    15  )
    16  
    17  func init() {
    18  	app.RegisterJobsExportDeleteInterface(func(a *app.App) tjobs.ExportDeleteInterface {
    19  		return &ExportDeleteInterfaceImpl{a}
    20  	})
    21  }
    22  
    23  type ExportDeleteInterfaceImpl struct {
    24  	app *app.App
    25  }
    26  
    27  type ExportDeleteWorker struct {
    28  	name        string
    29  	stopChan    chan struct{}
    30  	stoppedChan chan struct{}
    31  	jobsChan    chan model.Job
    32  	jobServer   *jobs.JobServer
    33  	app         *app.App
    34  }
    35  
    36  func (i *ExportDeleteInterfaceImpl) MakeWorker() model.Worker {
    37  	return &ExportDeleteWorker{
    38  		name:        "ExportDelete",
    39  		stopChan:    make(chan struct{}),
    40  		stoppedChan: make(chan struct{}),
    41  		jobsChan:    make(chan model.Job),
    42  		jobServer:   i.app.Srv().Jobs,
    43  		app:         i.app,
    44  	}
    45  }
    46  
    47  func (w *ExportDeleteWorker) JobChannel() chan<- model.Job {
    48  	return w.jobsChan
    49  }
    50  
    51  func (w *ExportDeleteWorker) Run() {
    52  	mlog.Debug("Worker started", mlog.String("worker", w.name))
    53  
    54  	defer func() {
    55  		mlog.Debug("Worker finished", mlog.String("worker", w.name))
    56  		close(w.stoppedChan)
    57  	}()
    58  
    59  	for {
    60  		select {
    61  		case <-w.stopChan:
    62  			mlog.Debug("Worker received stop signal", mlog.String("worker", w.name))
    63  			return
    64  		case job := <-w.jobsChan:
    65  			mlog.Debug("Worker received a new candidate job.", mlog.String("worker", w.name))
    66  			w.doJob(&job)
    67  		}
    68  	}
    69  }
    70  
    71  func (w *ExportDeleteWorker) Stop() {
    72  	mlog.Debug("Worker stopping", mlog.String("worker", w.name))
    73  	close(w.stopChan)
    74  	<-w.stoppedChan
    75  }
    76  
    77  func (w *ExportDeleteWorker) doJob(job *model.Job) {
    78  	if claimed, err := w.jobServer.ClaimJob(job); err != nil {
    79  		mlog.Warn("Worker experienced an error while trying to claim job",
    80  			mlog.String("worker", w.name),
    81  			mlog.String("job_id", job.Id),
    82  			mlog.String("error", err.Error()))
    83  		return
    84  	} else if !claimed {
    85  		return
    86  	}
    87  
    88  	exportPath := *w.app.Config().ExportSettings.Directory
    89  	retentionTime := time.Duration(*w.app.Config().ExportSettings.RetentionDays) * 24 * time.Hour
    90  	exports, appErr := w.app.ListDirectory(exportPath)
    91  	if appErr != nil {
    92  		w.setJobError(job, appErr)
    93  		return
    94  	}
    95  
    96  	var hasErrs bool
    97  	for i := range exports {
    98  		filename := filepath.Base(exports[i])
    99  		modTime, appErr := w.app.FileModTime(filepath.Join(exportPath, filename))
   100  		if appErr != nil {
   101  			mlog.Debug("Worker: Failed to get file modification time",
   102  				mlog.Err(appErr), mlog.String("export", exports[i]))
   103  			hasErrs = true
   104  			continue
   105  		}
   106  
   107  		if time.Now().After(modTime.Add(retentionTime)) {
   108  			// remove file data from storage.
   109  			if appErr := w.app.RemoveFile(exports[i]); appErr != nil {
   110  				mlog.Debug("Worker: Failed to remove file",
   111  					mlog.Err(appErr), mlog.String("export", exports[i]))
   112  				hasErrs = true
   113  				continue
   114  			}
   115  		}
   116  	}
   117  
   118  	if hasErrs {
   119  		mlog.Warn("Worker: errors occurred")
   120  	}
   121  
   122  	mlog.Info("Worker: Job is complete", mlog.String("worker", w.name), mlog.String("job_id", job.Id))
   123  	w.setJobSuccess(job)
   124  }
   125  
   126  func (w *ExportDeleteWorker) setJobSuccess(job *model.Job) {
   127  	if err := w.app.Srv().Jobs.SetJobSuccess(job); err != nil {
   128  		mlog.Error("Worker: Failed to set success for job", mlog.String("worker", w.name), mlog.String("job_id", job.Id), mlog.String("error", err.Error()))
   129  		w.setJobError(job, err)
   130  	}
   131  }
   132  
   133  func (w *ExportDeleteWorker) setJobError(job *model.Job, appError *model.AppError) {
   134  	if err := w.app.Srv().Jobs.SetJobError(job, appError); err != nil {
   135  		mlog.Error("Worker: Failed to set job error", mlog.String("worker", w.name), mlog.String("job_id", job.Id), mlog.String("error", err.Error()))
   136  	}
   137  }