mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Performance improvement for add team user when org has more than 1000 repositories (#19227)
* performance improvement for add team user when org has more than 1000 repositories * Fix bug * Fix bug
This commit is contained in:
		| @@ -15,6 +15,7 @@ import ( | |||||||
| 	"code.gitea.io/gitea/models/organization" | 	"code.gitea.io/gitea/models/organization" | ||||||
| 	repo_model "code.gitea.io/gitea/models/repo" | 	repo_model "code.gitea.io/gitea/models/repo" | ||||||
| 	user_model "code.gitea.io/gitea/models/user" | 	user_model "code.gitea.io/gitea/models/user" | ||||||
|  | 	"code.gitea.io/gitea/modules/log" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
|  |  | ||||||
| @@ -498,11 +499,6 @@ func AddTeamMember(team *organization.Team, userID int64) error { | |||||||
| 	} | 	} | ||||||
| 	defer committer.Close() | 	defer committer.Close() | ||||||
|  |  | ||||||
| 	// Get team and its repositories. |  | ||||||
| 	if err := team.GetRepositoriesCtx(ctx); err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	sess := db.GetEngine(ctx) | 	sess := db.GetEngine(ctx) | ||||||
|  |  | ||||||
| 	if err := db.Insert(ctx, &organization.TeamUser{ | 	if err := db.Insert(ctx, &organization.TeamUser{ | ||||||
| @@ -518,17 +514,51 @@ func AddTeamMember(team *organization.Team, userID int64) error { | |||||||
| 	team.NumMembers++ | 	team.NumMembers++ | ||||||
|  |  | ||||||
| 	// Give access to team repositories. | 	// Give access to team repositories. | ||||||
| 	for _, repo := range team.Repos { | 	// update exist access if mode become bigger | ||||||
| 		if err := recalculateUserAccess(ctx, repo, userID); err != nil { | 	subQuery := builder.Select("repo_id").From("team_repo"). | ||||||
| 			return err | 		Where(builder.Eq{"team_id": team.ID}) | ||||||
| 		} |  | ||||||
| 		if setting.Service.AutoWatchNewRepos { | 	if _, err := sess.Where("user_id=?", userID). | ||||||
| 			if err = repo_model.WatchRepoCtx(ctx, userID, repo.ID, true); err != nil { | 		In("repo_id", subQuery). | ||||||
| 				return err | 		And("mode < ?", team.AccessMode). | ||||||
|  | 		SetExpr("mode", team.AccessMode). | ||||||
|  | 		Update(new(Access)); err != nil { | ||||||
|  | 		return fmt.Errorf("update user accesses: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// for not exist access | ||||||
|  | 	var repoIDs []int64 | ||||||
|  | 	accessSubQuery := builder.Select("repo_id").From("access").Where(builder.Eq{"user_id": userID}) | ||||||
|  | 	if err := sess.SQL(subQuery.And(builder.NotIn("repo_id", accessSubQuery))).Find(&repoIDs); err != nil { | ||||||
|  | 		return fmt.Errorf("select id accesses: %v", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	accesses := make([]*Access, 0, 100) | ||||||
|  | 	for i, repoID := range repoIDs { | ||||||
|  | 		accesses = append(accesses, &Access{RepoID: repoID, UserID: userID, Mode: team.AccessMode}) | ||||||
|  | 		if (i%100 == 0 || i == len(repoIDs)-1) && len(accesses) > 0 { | ||||||
|  | 			if err = db.Insert(ctx, accesses); err != nil { | ||||||
|  | 				return fmt.Errorf("insert new user accesses: %v", err) | ||||||
| 			} | 			} | ||||||
|  | 			accesses = accesses[:0] | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	// watch could be failed, so run it in a goroutine | ||||||
|  | 	if setting.Service.AutoWatchNewRepos { | ||||||
|  | 		// Get team and its repositories. | ||||||
|  | 		if err := team.GetRepositoriesCtx(db.DefaultContext); err != nil { | ||||||
|  | 			log.Error("getRepositories failed: %v", err) | ||||||
|  | 		} | ||||||
|  | 		go func(repos []*repo_model.Repository) { | ||||||
|  | 			for _, repo := range repos { | ||||||
|  | 				if err = repo_model.WatchRepoCtx(db.DefaultContext, userID, repo.ID, true); err != nil { | ||||||
|  | 					log.Error("watch repo failed: %v", err) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		}(team.Repos) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	return committer.Commit() | 	return committer.Commit() | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user