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