github.com/jlevesy/mattermost-server@v5.3.2-0.20181003190404-7468f35cb0c8+incompatible/jobs/jobs_watcher.go (about)

     1  // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package jobs
     5  
     6  import (
     7  	"fmt"
     8  	"math/rand"
     9  	"time"
    10  
    11  	"github.com/mattermost/mattermost-server/mlog"
    12  	"github.com/mattermost/mattermost-server/model"
    13  )
    14  
    15  // Default polling interval for jobs termination.
    16  // (Defining as `var` rather than `const` allows tests to lower the interval.)
    17  var DEFAULT_WATCHER_POLLING_INTERVAL = 15000
    18  
    19  type Watcher struct {
    20  	srv     *JobServer
    21  	workers *Workers
    22  
    23  	stop            chan bool
    24  	stopped         chan bool
    25  	pollingInterval int
    26  }
    27  
    28  func (srv *JobServer) MakeWatcher(workers *Workers, pollingInterval int) *Watcher {
    29  	return &Watcher{
    30  		stop:            make(chan bool, 1),
    31  		stopped:         make(chan bool, 1),
    32  		pollingInterval: pollingInterval,
    33  		workers:         workers,
    34  		srv:             srv,
    35  	}
    36  }
    37  
    38  func (watcher *Watcher) Start() {
    39  	mlog.Debug("Watcher Started")
    40  
    41  	// Delay for some random number of milliseconds before starting to ensure that multiple
    42  	// instances of the jobserver  don't poll at a time too close to each other.
    43  	rand.Seed(time.Now().UTC().UnixNano())
    44  	<-time.After(time.Duration(rand.Intn(watcher.pollingInterval)) * time.Millisecond)
    45  
    46  	defer func() {
    47  		mlog.Debug("Watcher Finished")
    48  		watcher.stopped <- true
    49  	}()
    50  
    51  	for {
    52  		select {
    53  		case <-watcher.stop:
    54  			mlog.Debug("Watcher: Received stop signal")
    55  			return
    56  		case <-time.After(time.Duration(watcher.pollingInterval) * time.Millisecond):
    57  			watcher.PollAndNotify()
    58  		}
    59  	}
    60  }
    61  
    62  func (watcher *Watcher) Stop() {
    63  	mlog.Debug("Watcher Stopping")
    64  	watcher.stop <- true
    65  	<-watcher.stopped
    66  }
    67  
    68  func (watcher *Watcher) PollAndNotify() {
    69  	if result := <-watcher.srv.Store.Job().GetAllByStatus(model.JOB_STATUS_PENDING); result.Err != nil {
    70  		mlog.Error(fmt.Sprintf("Error occurred getting all pending statuses: %v", result.Err.Error()))
    71  	} else {
    72  		jobs := result.Data.([]*model.Job)
    73  
    74  		for _, job := range jobs {
    75  			if job.Type == model.JOB_TYPE_DATA_RETENTION {
    76  				if watcher.workers.DataRetention != nil {
    77  					select {
    78  					case watcher.workers.DataRetention.JobChannel() <- *job:
    79  					default:
    80  					}
    81  				}
    82  			} else if job.Type == model.JOB_TYPE_MESSAGE_EXPORT {
    83  				if watcher.workers.MessageExport != nil {
    84  					select {
    85  					case watcher.workers.MessageExport.JobChannel() <- *job:
    86  					default:
    87  					}
    88  				}
    89  			} else if job.Type == model.JOB_TYPE_ELASTICSEARCH_POST_INDEXING {
    90  				if watcher.workers.ElasticsearchIndexing != nil {
    91  					select {
    92  					case watcher.workers.ElasticsearchIndexing.JobChannel() <- *job:
    93  					default:
    94  					}
    95  				}
    96  			} else if job.Type == model.JOB_TYPE_ELASTICSEARCH_POST_AGGREGATION {
    97  				if watcher.workers.ElasticsearchAggregation != nil {
    98  					select {
    99  					case watcher.workers.ElasticsearchAggregation.JobChannel() <- *job:
   100  					default:
   101  					}
   102  				}
   103  			} else if job.Type == model.JOB_TYPE_LDAP_SYNC {
   104  				if watcher.workers.LdapSync != nil {
   105  					select {
   106  					case watcher.workers.LdapSync.JobChannel() <- *job:
   107  					default:
   108  					}
   109  				}
   110  			} else if job.Type == model.JOB_TYPE_MIGRATIONS {
   111  				if watcher.workers.Migrations != nil {
   112  					select {
   113  					case watcher.workers.Migrations.JobChannel() <- *job:
   114  					default:
   115  					}
   116  				}
   117  			}
   118  		}
   119  	}
   120  }