added batch processing and other fixes

This commit is contained in:
karthikbhandary2
2026-03-07 16:34:32 +05:30
parent a5092e5aa7
commit 20e3fe40d7
3 changed files with 117 additions and 21 deletions
+41 -14
View File
@@ -514,49 +514,76 @@ func DeleteOrgRepos(ctx *context.APIContext) {
// required: true
// responses:
// "202":
// description: Deletion started
// "$ref": "#/responses/empty"
// "204":
// description: No repositories to delete
// "$ref": "#/responses/empty"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
org := ctx.Org.Organization
repos, err := repo_model.GetOrgRepositories(ctx, org.ID)
orgID := org.ID
doer := ctx.Doer
// Check if org has any repos
count, err := db.GetEngine(ctx).Where("owner_id = ?", orgID).Count(new(repo_model.Repository))
if err != nil {
ctx.APIErrorInternal(err)
return
}
if len(repos) == 0 {
if count == 0 {
ctx.Status(http.StatusNoContent)
return
}
doer := ctx.Doer
// Start deletion in background with detached context
go func() {
defer func() {
if r := recover(); r != nil {
log.Error("Panic during org repo deletion: %v", r)
desc := fmt.Sprintf("Panic during org repo deletion for org ID %d: %v", orgID, r)
if noticeErr := system_model.CreateNotice(graceful.GetManager().HammerContext(), system_model.NoticeRepository, desc); noticeErr != nil {
log.Error("Failed to create notice for panic: %v", noticeErr)
}
}
}()
// Use HammerContext so deletion continues even if client disconnects
bgCtx := graceful.GetManager().HammerContext()
for _, repo := range repos {
if err := repo_service.DeleteRepository(bgCtx, doer, repo, true); err != nil {
desc := fmt.Sprintf("Failed to delete repository %s (ID: %d) in org %s: %v", repo.Name, repo.ID, org.Name, err)
const batchSize = 50
for {
repos := make([]*repo_model.Repository, 0, batchSize)
// Always fetch from offset 0 since we're deleting as we go
err := db.GetEngine(bgCtx).Where("owner_id = ?", orgID).
Limit(batchSize, 0).
Find(&repos)
if err != nil {
desc := fmt.Sprintf("Failed to fetch repositories for org ID %d: %v", orgID, err)
if noticeErr := system_model.CreateNotice(bgCtx, system_model.NoticeRepository, desc); noticeErr != nil {
log.Error("Failed to create notice for repo deletion failure: %v", noticeErr)
log.Error("Failed to create notice for repo fetch failure: %v", noticeErr)
}
break
}
// exit the loop when there are no more repos to delete
if len(repos) == 0 {
break
}
for _, repo := range repos {
if err := repo_service.DeleteRepository(bgCtx, doer, repo, true); err != nil {
desc := fmt.Sprintf("Failed to delete repository %s (ID: %d) in org ID %d: %v", repo.Name, repo.ID, orgID, err)
if noticeErr := system_model.CreateNotice(bgCtx, system_model.NoticeRepository, desc); noticeErr != nil {
log.Error("Failed to create notice for repo deletion failure: %v", noticeErr)
}
} else {
log.Info("Successfully deleted repository %s (ID: %d) in org ID %d", repo.Name, repo.ID, orgID)
}
} else {
log.Info("Successfully deleted repository %s (ID: %d) in org %s", repo.Name, repo.ID, org.Name)
}
}
log.Info("Completed deletion of %d repositories in org %s", len(repos), org.Name)
log.Info("Completed deletion of repositories in org ID %d", orgID)
}()
ctx.Status(http.StatusAccepted)