refactor: make db iterate context aware (#27710)

the iteration will run until finished atm.

this changes it by checking if if the context got canceled before each
run of a loop sequence is executed

[View this pull with now
whitespace](https://github.com/go-gitea/gitea/pull/27710/files?diff=unified&w=1)
This commit is contained in:
6543 2023-10-21 04:05:29 +02:00 committed by GitHub
parent 510d07506e
commit b2f828db5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 30 deletions

View File

@ -17,22 +17,27 @@ func Iterate[Bean any](ctx context.Context, cond builder.Cond, f func(ctx contex
batchSize := setting.Database.IterateBufferSize batchSize := setting.Database.IterateBufferSize
sess := GetEngine(ctx) sess := GetEngine(ctx)
for { for {
beans := make([]*Bean, 0, batchSize) select {
if cond != nil { case <-ctx.Done():
sess = sess.Where(cond) return ctx.Err()
} default:
if err := sess.Limit(batchSize, start).Find(&beans); err != nil { beans := make([]*Bean, 0, batchSize)
return err if cond != nil {
} sess = sess.Where(cond)
if len(beans) == 0 { }
return nil if err := sess.Limit(batchSize, start).Find(&beans); err != nil {
}
start += len(beans)
for _, bean := range beans {
if err := f(ctx, bean); err != nil {
return err return err
} }
if len(beans) == 0 {
return nil
}
start += len(beans)
for _, bean := range beans {
if err := f(ctx, bean); err != nil {
return err
}
}
} }
} }
} }

View File

@ -37,24 +37,29 @@ func deleteOrphanedRepos(ctx context.Context) (int64, error) {
adminUser := &user_model.User{IsAdmin: true} adminUser := &user_model.User{IsAdmin: true}
for { for {
var ids []int64 select {
if err := e.Table("`repository`"). case <-ctx.Done():
Join("LEFT", "`user`", "repository.owner_id=user.id"). return deleted, ctx.Err()
Where(builder.IsNull{"`user`.id"}). default:
Select("`repository`.id").Limit(batchSize).Find(&ids); err != nil { var ids []int64
return deleted, err if err := e.Table("`repository`").
} Join("LEFT", "`user`", "repository.owner_id=user.id").
Where(builder.IsNull{"`user`.id"}).
// if we don't get ids we have deleted them all Select("`repository`.id").Limit(batchSize).Find(&ids); err != nil {
if len(ids) == 0 {
return deleted, nil
}
for _, id := range ids {
if err := repo_service.DeleteRepositoryDirectly(ctx, adminUser, id, true); err != nil {
return deleted, err return deleted, err
} }
deleted++
// if we don't get ids we have deleted them all
if len(ids) == 0 {
return deleted, nil
}
for _, id := range ids {
if err := repo_service.DeleteRepositoryDirectly(ctx, adminUser, id, true); err != nil {
return deleted, err
}
deleted++
}
} }
} }
} }