Skip to content

Commit

Permalink
Merge remote-tracking branch 'giteaofficial/main'
Browse files Browse the repository at this point in the history
* giteaofficial/main:
  Round language stats percentage using largest remainder (go-gitea#22026)
  Support disabling database auto migration (go-gitea#22053)
  • Loading branch information
zjjhot committed Dec 8, 2022
2 parents 8eb24fd + cf27403 commit c3cda9e
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 5 deletions.
3 changes: 3 additions & 0 deletions custom/conf/app.example.ini
Expand Up @@ -403,6 +403,9 @@ LOG_SQL = false ; if unset defaults to true
;;
;; Database maximum number of open connections, default is 0 meaning no maximum
;MAX_OPEN_CONNS = 0
;;
;; Whether execute database models migrations automatically
;AUTO_MIGRATION = true

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down
1 change: 1 addition & 0 deletions docs/content/doc/advanced/config-cheat-sheet.en-us.md
Expand Up @@ -444,6 +444,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
- `MAX_OPEN_CONNS` **0**: Database maximum open connections - default is 0, meaning there is no limit.
- `MAX_IDLE_CONNS` **2**: Max idle database connections on connection pool, default is 2 - this will be capped to `MAX_OPEN_CONNS`.
- `CONN_MAX_LIFETIME` **0 or 3s**: Sets the maximum amount of time a DB connection may be reused - default is 0, meaning there is no limit (except on MySQL where it is 3s - see #6804 & #7071).
- `AUTO_MIGRATION` **true**: Whether execute database models migrations automatically.

Please see #8540 & #8273 for further discussion of the appropriate values for `MAX_OPEN_CONNS`, `MAX_IDLE_CONNS` & `CONN_MAX_LIFETIME` and their
relation to port exhaustion.
Expand Down
40 changes: 36 additions & 4 deletions models/repo/language_stats.go
Expand Up @@ -6,6 +6,7 @@ package repo
import (
"context"
"math"
"sort"
"strings"

"code.gitea.io/gitea/models/db"
Expand Down Expand Up @@ -43,29 +44,60 @@ func (stats LanguageStatList) LoadAttributes() {

func (stats LanguageStatList) getLanguagePercentages() map[string]float32 {
langPerc := make(map[string]float32)
var otherPerc float32 = 100
var otherPerc float32
var total int64

for _, stat := range stats {
total += stat.Size
}
if total > 0 {
for _, stat := range stats {
perc := float32(math.Round(float64(stat.Size)/float64(total)*1000) / 10)
perc := float32(float64(stat.Size) / float64(total) * 100)
if perc <= 0.1 {
otherPerc += perc
continue
}
otherPerc -= perc
langPerc[stat.Language] = perc
}
otherPerc = float32(math.Round(float64(otherPerc)*10) / 10)
}
if otherPerc > 0 {
langPerc["other"] = otherPerc
}
roundByLargestRemainder(langPerc, 100)
return langPerc
}

// Rounds to 1 decimal point, target should be the expected sum of percs
func roundByLargestRemainder(percs map[string]float32, target float32) {
leftToDistribute := int(target * 10)

keys := make([]string, 0, len(percs))

for k, v := range percs {
percs[k] = v * 10
floored := math.Floor(float64(percs[k]))
leftToDistribute -= int(floored)
keys = append(keys, k)
}

// Sort the keys by the largest remainder
sort.SliceStable(keys, func(i, j int) bool {
_, remainderI := math.Modf(float64(percs[keys[i]]))
_, remainderJ := math.Modf(float64(percs[keys[j]]))
return remainderI > remainderJ
})

// Increment the values in order of largest remainder
for _, k := range keys {
percs[k] = float32(math.Floor(float64(percs[k])))
if leftToDistribute > 0 {
percs[k]++
leftToDistribute--
}
percs[k] /= 10
}
}

// GetLanguageStats returns the language statistics for a repository
func GetLanguageStats(ctx context.Context, repo *Repository) (LanguageStatList, error) {
stats := make(LanguageStatList, 0, 6)
Expand Down
1 change: 1 addition & 0 deletions modules/doctor/dbversion.go
Expand Up @@ -12,6 +12,7 @@ import (
)

func checkDBVersion(ctx context.Context, logger log.Logger, autofix bool) error {
logger.Info("Expected database version: %d", migrations.ExpectedVersion())
if err := db.InitEngineWithMigration(ctx, migrations.EnsureUpToDate); err != nil {
if !autofix {
logger.Critical("Error: %v during ensure up to date", err)
Expand Down
2 changes: 2 additions & 0 deletions modules/setting/database.go
Expand Up @@ -49,6 +49,7 @@ var (
MaxOpenConns int
ConnMaxLifetime time.Duration
IterateBufferSize int
AutoMigration bool
}{
Timeout: 500,
IterateBufferSize: 50,
Expand Down Expand Up @@ -105,6 +106,7 @@ func InitDBConfig() {
Database.LogSQL = sec.Key("LOG_SQL").MustBool(true)
Database.DBConnectRetries = sec.Key("DB_RETRIES").MustInt(10)
Database.DBConnectBackoff = sec.Key("DB_RETRY_BACKOFF").MustDuration(3 * time.Second)
Database.AutoMigration = sec.Key("AUTO_MIGRATION").MustBool(true)
}

// DBConnStr returns database connection string
Expand Down
21 changes: 20 additions & 1 deletion routers/common/db.go
Expand Up @@ -12,6 +12,8 @@ import (
"code.gitea.io/gitea/models/migrations"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"

"xorm.io/xorm"
)

// InitDBEngine In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology
Expand All @@ -24,7 +26,7 @@ func InitDBEngine(ctx context.Context) (err error) {
default:
}
log.Info("ORM engine initialization attempt #%d/%d...", i+1, setting.Database.DBConnectRetries)
if err = db.InitEngineWithMigration(ctx, migrations.Migrate); err == nil {
if err = db.InitEngineWithMigration(ctx, migrateWithSetting); err == nil {
break
} else if i == setting.Database.DBConnectRetries-1 {
return err
Expand All @@ -36,3 +38,20 @@ func InitDBEngine(ctx context.Context) (err error) {
db.HasEngine = true
return nil
}

func migrateWithSetting(x *xorm.Engine) error {
if setting.Database.AutoMigration {
return migrations.Migrate(x)
}

if current, err := migrations.GetCurrentDBVersion(x); err != nil {
return err
} else if current < 0 {
// execute migrations when the database isn't initialized even if AutoMigration is false
return migrations.Migrate(x)
} else if expected := migrations.ExpectedVersion(); current != expected {
log.Fatal(`"database.AUTO_MIGRATION" is disabled, but current database version %d is not equal to the expected version %d.`+
`You can set "database.AUTO_MIGRATION" to true or migrate manually by running "gitea [--config /path/to/app.ini] migrate"`, current, expected)
}
return nil
}

0 comments on commit c3cda9e

Please sign in to comment.