code.gitea.io/gitea@v1.19.3/modules/indexer/stats/indexer.go (about)

     1  // Copyright 2020 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package stats
     5  
     6  import (
     7  	"code.gitea.io/gitea/models/db"
     8  	repo_model "code.gitea.io/gitea/models/repo"
     9  	"code.gitea.io/gitea/modules/graceful"
    10  	"code.gitea.io/gitea/modules/log"
    11  )
    12  
    13  // Indexer defines an interface to index repository stats
    14  type Indexer interface {
    15  	Index(id int64) error
    16  	Close()
    17  }
    18  
    19  // indexer represents a indexer instance
    20  var indexer Indexer
    21  
    22  // Init initialize the repo indexer
    23  func Init() error {
    24  	indexer = &DBIndexer{}
    25  
    26  	if err := initStatsQueue(); err != nil {
    27  		return err
    28  	}
    29  
    30  	go populateRepoIndexer()
    31  
    32  	return nil
    33  }
    34  
    35  // populateRepoIndexer populate the repo indexer with pre-existing data. This
    36  // should only be run when the indexer is created for the first time.
    37  func populateRepoIndexer() {
    38  	log.Info("Populating the repo stats indexer with existing repositories")
    39  
    40  	isShutdown := graceful.GetManager().IsShutdown()
    41  
    42  	exist, err := db.IsTableNotEmpty("repository")
    43  	if err != nil {
    44  		log.Fatal("System error: %v", err)
    45  	} else if !exist {
    46  		return
    47  	}
    48  
    49  	var maxRepoID int64
    50  	if maxRepoID, err = db.GetMaxID("repository"); err != nil {
    51  		log.Fatal("System error: %v", err)
    52  	}
    53  
    54  	// start with the maximum existing repo ID and work backwards, so that we
    55  	// don't include repos that are created after gitea starts; such repos will
    56  	// already be added to the indexer, and we don't need to add them again.
    57  	for maxRepoID > 0 {
    58  		select {
    59  		case <-isShutdown:
    60  			log.Info("Repository Stats Indexer population shutdown before completion")
    61  			return
    62  		default:
    63  		}
    64  		ids, err := repo_model.GetUnindexedRepos(repo_model.RepoIndexerTypeStats, maxRepoID, 0, 50)
    65  		if err != nil {
    66  			log.Error("populateRepoIndexer: %v", err)
    67  			return
    68  		} else if len(ids) == 0 {
    69  			break
    70  		}
    71  		for _, id := range ids {
    72  			select {
    73  			case <-isShutdown:
    74  				log.Info("Repository Stats Indexer population shutdown before completion")
    75  				return
    76  			default:
    77  			}
    78  			if err := statsQueue.Push(id); err != nil {
    79  				log.Error("statsQueue.Push: %v", err)
    80  			}
    81  			maxRepoID = id - 1
    82  		}
    83  	}
    84  	log.Info("Done (re)populating the repo stats indexer with existing repositories")
    85  }