mirror of
https://github.com/hanzoai/forge.git
synced 2026-10-30 15:00:39 +00:00
Source files keep their SPDX-License-Identifier and Hanzo copyright line; the Gitea, Gogs and LFS Test Server copyrights they used to repeat now live once in NOTICE, alongside LICENSE. The header lint accepts any copyright line above the SPDX line, so it no longer demands an upstream one. Co-authored-by: Hanzo Dev <[email protected]>
89 lines
2.3 KiB
Go
89 lines
2.3 KiB
Go
// Copyright 2026 Hanzo AI, Inc. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package stats
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/hanzoai/git/models/db"
|
|
repo_model "github.com/hanzoai/git/models/repo"
|
|
"github.com/hanzoai/git/modules/graceful"
|
|
"github.com/hanzoai/git/modules/log"
|
|
)
|
|
|
|
// Indexer defines an interface to index repository stats
|
|
// TODO: this indexer is quite different from the others, maybe this package should be moved out from module/indexer
|
|
type Indexer interface {
|
|
Index(id int64) error
|
|
Close()
|
|
}
|
|
|
|
// indexer represents a indexer instance
|
|
var indexer Indexer
|
|
|
|
// Init initialize the repo indexer
|
|
func Init() error {
|
|
indexer = &DBIndexer{}
|
|
|
|
if err := initStatsQueue(); err != nil {
|
|
return err
|
|
}
|
|
|
|
go populateRepoIndexer(graceful.GetManager().ShutdownContext())
|
|
|
|
return nil
|
|
}
|
|
|
|
// populateRepoIndexer populate the repo indexer with pre-existing data. This
|
|
// should only be run when the indexer is created for the first time.
|
|
func populateRepoIndexer(ctx context.Context) {
|
|
log.Info("Populating the repo stats indexer with existing repositories")
|
|
|
|
isShutdown := graceful.GetManager().IsShutdown()
|
|
|
|
exist, err := db.IsTableNotEmpty("repository")
|
|
if err != nil {
|
|
log.Fatal("System error: %v", err)
|
|
} else if !exist {
|
|
return
|
|
}
|
|
|
|
var maxRepoID int64
|
|
if maxRepoID, err = db.GetMaxID("repository"); err != nil {
|
|
log.Fatal("System error: %v", err)
|
|
}
|
|
|
|
// start with the maximum existing repo ID and work backwards, so that we
|
|
// don't include repos that are created after the forge starts; such repos will
|
|
// already be added to the indexer, and we don't need to add them again.
|
|
for maxRepoID > 0 {
|
|
select {
|
|
case <-isShutdown:
|
|
log.Info("Repository Stats Indexer population shutdown before completion")
|
|
return
|
|
default:
|
|
}
|
|
ids, err := repo_model.GetUnindexedRepos(ctx, repo_model.RepoIndexerTypeStats, maxRepoID, 0, 50)
|
|
if err != nil {
|
|
log.Error("populateRepoIndexer: %v", err)
|
|
return
|
|
} else if len(ids) == 0 {
|
|
break
|
|
}
|
|
for _, id := range ids {
|
|
select {
|
|
case <-isShutdown:
|
|
log.Info("Repository Stats Indexer population shutdown before completion")
|
|
return
|
|
default:
|
|
}
|
|
if err := statsQueue.Push(id); err != nil {
|
|
log.Error("statsQueue.Push: %v", err)
|
|
}
|
|
maxRepoID = id - 1
|
|
}
|
|
}
|
|
log.Info("Done (re)populating the repo stats indexer with existing repositories")
|
|
}
|