From c8599c47d0614544c3da3d843c3ea3930c12575f Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 1 Feb 2024 17:24:30 +0800 Subject: [PATCH 1/7] Some performance optimization on dashboard and issues page --- models/activities/action.go | 1 + models/activities/action_list.go | 60 ++++++++++++++++++++++++-------- models/issues/issue_list.go | 10 ++++++ models/repo/repo_list.go | 35 +++++++++++++++++++ routers/web/feed/convert.go | 11 ++++-- routers/web/repo/repo.go | 6 +++- 6 files changed, 105 insertions(+), 18 deletions(-) diff --git a/models/activities/action.go b/models/activities/action.go index 15bd9a52acc5c..37cc810bf3e4c 100644 --- a/models/activities/action.go +++ b/models/activities/action.go @@ -325,6 +325,7 @@ func (a *Action) getCommentHTMLURL(ctx context.Context) string { if err != nil { return "#" } + issue.Repo = a.Repo if err = issue.LoadRepo(ctx); err != nil { return "#" diff --git a/models/activities/action_list.go b/models/activities/action_list.go index 3d74397c69297..a29b5afffe186 100644 --- a/models/activities/action_list.go +++ b/models/activities/action_list.go @@ -8,6 +8,7 @@ import ( "fmt" "code.gitea.io/gitea/models/db" + issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" @@ -24,7 +25,7 @@ func (actions ActionList) getUserIDs() []int64 { return userIDs.Values() } -func (actions ActionList) loadUsers(ctx context.Context) (map[int64]*user_model.User, error) { +func (actions ActionList) LoadActUsers(ctx context.Context) (map[int64]*user_model.User, error) { if len(actions) == 0 { return nil, nil } @@ -52,7 +53,7 @@ func (actions ActionList) getRepoIDs() []int64 { return repoIDs.Values() } -func (actions ActionList) loadRepositories(ctx context.Context) error { +func (actions ActionList) LoadRepositories(ctx context.Context) error { if len(actions) == 0 { return nil } @@ -75,22 +76,26 @@ func (actions ActionList) loadRepoOwner(ctx context.Context, userMap map[int64]* userMap = make(map[int64]*user_model.User) } + userIDs := make([]int64, 0, len(actions)) for _, action := range actions { if action.Repo == nil { continue } - repoOwner, ok := userMap[action.Repo.OwnerID] - if !ok { - repoOwner, err = user_model.GetUserByID(ctx, action.Repo.OwnerID) - if err != nil { - if user_model.IsErrUserNotExist(err) { - continue - } - return err - } - userMap[repoOwner.ID] = repoOwner + if _, ok := userMap[action.Repo.OwnerID]; !ok { + userIDs = append(userIDs, action.Repo.OwnerID) + } + } + + if err := db.GetEngine(ctx). + In("id", userIDs). + Find(&userMap); err != nil { + return fmt.Errorf("find user: %w", err) + } + + for _, action := range actions { + if action.Repo != nil { + action.Repo.Owner = userMap[action.Repo.OwnerID] } - action.Repo.Owner = repoOwner } return nil @@ -98,14 +103,39 @@ func (actions ActionList) loadRepoOwner(ctx context.Context, userMap map[int64]* // loadAttributes loads all attributes func (actions ActionList) loadAttributes(ctx context.Context) error { - userMap, err := actions.loadUsers(ctx) + userMap, err := actions.LoadActUsers(ctx) if err != nil { return err } - if err := actions.loadRepositories(ctx); err != nil { + if err := actions.LoadRepositories(ctx); err != nil { return err } return actions.loadRepoOwner(ctx, userMap) } + +func (actions ActionList) LoadComments(ctx context.Context) error { + if len(actions) == 0 { + return nil + } + + commentIDs := make([]int64, 0, len(actions)) + for _, action := range actions { + if action.CommentID > 0 { + commentIDs = append(commentIDs, action.CommentID) + } + } + + commentsMap := make(map[int64]*issues_model.Comment, len(commentIDs)) + if err := db.GetEngine(ctx).In("id", commentIDs).Find(&commentsMap); err != nil { + return fmt.Errorf("find comment: %w", err) + } + + for _, action := range actions { + if action.CommentID > 0 { + action.Comment = commentsMap[action.CommentID] + } + } + return nil +} diff --git a/models/issues/issue_list.go b/models/issues/issue_list.go index a932ac2554369..0fb8447ff75a7 100644 --- a/models/issues/issue_list.go +++ b/models/issues/issue_list.go @@ -476,6 +476,16 @@ func (issues IssueList) loadTotalTrackedTimes(ctx context.Context) (err error) { } trackedTimes := make(map[int64]int64, len(issues)) + reposMap := make(map[int64]*repo_model.Repository, len(issues)) + for _, issue := range issues { + reposMap[issue.RepoID] = issue.Repo + } + repos := repo_model.RepositoryListOfMap(reposMap) + + if err := repos.LoadUnits(ctx); err != nil { + return err + } + ids := make([]int64, 0, len(issues)) for _, issue := range issues { if issue.Repo.IsTimetrackerEnabled(ctx) { diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go index 533ca5251fecf..f71b74f50d3a2 100644 --- a/models/repo/repo_list.go +++ b/models/repo/repo_list.go @@ -62,6 +62,41 @@ func RepositoryListOfMap(repoMap map[int64]*Repository) RepositoryList { return RepositoryList(ValuesRepository(repoMap)) } +func (repos RepositoryList) LoadUnits(ctx context.Context) error { + if len(repos) == 0 { + return nil + } + + // Load units. + units := make([]*RepoUnit, 0, len(repos)*6) + if err := db.GetEngine(ctx). + In("repo_id", repos.IDs()). + Find(&units); err != nil { + return fmt.Errorf("find units: %w", err) + } + + unitsMap := make(map[int64][]*RepoUnit, len(repos)) + for _, unit := range units { + if !unit.Type.UnitGlobalDisabled() { + unitsMap[unit.RepoID] = append(unitsMap[unit.RepoID], unit) + } + } + + for _, repo := range repos { + repo.Units = unitsMap[repo.ID] + } + + return nil +} + +func (repos RepositoryList) IDs() []int64 { + repoIDs := make([]int64, len(repos)) + for i := range repos { + repoIDs[i] = repos[i].ID + } + return repoIDs +} + // LoadAttributes loads the attributes for the given RepositoryList func (repos RepositoryList) LoadAttributes(ctx context.Context) error { if len(repos) == 0 { diff --git a/routers/web/feed/convert.go b/routers/web/feed/convert.go index 6dbc2c2cbcf11..1d649aaa5a351 100644 --- a/routers/web/feed/convert.go +++ b/routers/web/feed/convert.go @@ -70,9 +70,16 @@ func renderMarkdown(ctx *context.Context, act *activities_model.Action, content // feedActionsToFeedItems convert gitea's Action feed to feeds Item func feedActionsToFeedItems(ctx *context.Context, actions activities_model.ActionList) (items []*feeds.Item, err error) { + if _, err := actions.LoadActUsers(ctx); err != nil { + return nil, err + } + if err := actions.LoadRepositories(ctx); err != nil { + return nil, err + } + if err := actions.LoadComments(ctx); err != nil { + return nil, err + } for _, act := range actions { - act.LoadActUser(ctx) - var content, desc, title string link := &feeds.Link{Href: act.GetCommentHTMLURL(ctx)} diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index b64db914060f4..401e07b510fdd 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -510,9 +510,13 @@ func InitiateDownload(ctx *context.Context) { // SearchRepo repositories via options func SearchRepo(ctx *context.Context) { + page := ctx.FormInt("page") + if page <= 0 { + page = 1 + } opts := &repo_model.SearchRepoOptions{ ListOptions: db.ListOptions{ - Page: ctx.FormInt("page"), + Page: page, PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")), }, Actor: ctx.Doer, From 4ff52b0ccf9dc612ed12d0198d0d520ec23e3024 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 1 Feb 2024 20:00:36 +0800 Subject: [PATCH 2/7] Fix bug --- models/activities/action_list.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/models/activities/action_list.go b/models/activities/action_list.go index a29b5afffe186..677924722133a 100644 --- a/models/activities/action_list.go +++ b/models/activities/action_list.go @@ -77,12 +77,14 @@ func (actions ActionList) loadRepoOwner(ctx context.Context, userMap map[int64]* } userIDs := make([]int64, 0, len(actions)) + userSet := make(container.Set[int64], len(actions)) for _, action := range actions { if action.Repo == nil { continue } - if _, ok := userMap[action.Repo.OwnerID]; !ok { + if _, ok := userMap[action.Repo.OwnerID]; !ok && !userSet.Contains(action.Repo.OwnerID) { userIDs = append(userIDs, action.Repo.OwnerID) + userSet.Add(action.Repo.OwnerID) } } From 45dcf4eb2d2dcbea975161f7c88df6068dde7ec0 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Thu, 1 Feb 2024 20:05:01 +0800 Subject: [PATCH 3/7] Fix bug --- models/activities/action_list.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/models/activities/action_list.go b/models/activities/action_list.go index 677924722133a..220535c9b7a1a 100644 --- a/models/activities/action_list.go +++ b/models/activities/action_list.go @@ -76,20 +76,18 @@ func (actions ActionList) loadRepoOwner(ctx context.Context, userMap map[int64]* userMap = make(map[int64]*user_model.User) } - userIDs := make([]int64, 0, len(actions)) userSet := make(container.Set[int64], len(actions)) for _, action := range actions { if action.Repo == nil { continue } - if _, ok := userMap[action.Repo.OwnerID]; !ok && !userSet.Contains(action.Repo.OwnerID) { - userIDs = append(userIDs, action.Repo.OwnerID) + if _, ok := userMap[action.Repo.OwnerID]; !ok { userSet.Add(action.Repo.OwnerID) } } if err := db.GetEngine(ctx). - In("id", userIDs). + In("id", userSet.Values()). Find(&userMap); err != nil { return fmt.Errorf("find user: %w", err) } From 9e1244aa4da74a533bbc93f9d9983b8a1abc5249 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 2 Feb 2024 15:56:01 +0800 Subject: [PATCH 4/7] more performance optimiaztion --- models/activities/action.go | 98 ++++++++++++++++---------------- models/activities/action_list.go | 76 ++++++++++++++++++++++--- models/repo/repo.go | 3 + modules/util/slice.go | 8 +++ routers/web/feed/convert.go | 9 --- 5 files changed, 128 insertions(+), 66 deletions(-) diff --git a/models/activities/action.go b/models/activities/action.go index 37cc810bf3e4c..bfe000982543a 100644 --- a/models/activities/action.go +++ b/models/activities/action.go @@ -148,6 +148,7 @@ type Action struct { Repo *repo_model.Repository `xorm:"-"` CommentID int64 `xorm:"INDEX"` Comment *issues_model.Comment `xorm:"-"` + Issue *issues_model.Issue `xorm:"-"` // get the issue id from content IsDeleted bool `xorm:"NOT NULL DEFAULT false"` RefName string IsPrivate bool `xorm:"NOT NULL DEFAULT false"` @@ -290,11 +291,6 @@ func (a *Action) GetRepoAbsoluteLink(ctx context.Context) string { return setting.AppURL + url.PathEscape(a.GetRepoUserName(ctx)) + "/" + url.PathEscape(a.GetRepoName(ctx)) } -// GetCommentHTMLURL returns link to action comment. -func (a *Action) GetCommentHTMLURL(ctx context.Context) string { - return a.getCommentHTMLURL(ctx) -} - func (a *Action) loadComment(ctx context.Context) (err error) { if a.CommentID == 0 || a.Comment != nil { return nil @@ -303,7 +299,8 @@ func (a *Action) loadComment(ctx context.Context) (err error) { return err } -func (a *Action) getCommentHTMLURL(ctx context.Context) string { +// GetCommentHTMLURL returns link to action comment. +func (a *Action) GetCommentHTMLURL(ctx context.Context) string { if a == nil { return "#" } @@ -311,35 +308,19 @@ func (a *Action) getCommentHTMLURL(ctx context.Context) string { if a.Comment != nil { return a.Comment.HTMLURL(ctx) } - if len(a.GetIssueInfos()) == 0 { - return "#" - } - // Return link to issue - issueIDString := a.GetIssueInfos()[0] - issueID, err := strconv.ParseInt(issueIDString, 10, 64) - if err != nil { - return "#" - } - issue, err := issues_model.GetIssueByID(ctx, issueID) - if err != nil { + if err := a.LoadIssue(ctx); err != nil || a.Issue == nil { return "#" } - issue.Repo = a.Repo - - if err = issue.LoadRepo(ctx); err != nil { + if err := a.Issue.LoadRepo(ctx); err != nil { return "#" } - return issue.HTMLURL() + return a.Issue.HTMLURL() } // GetCommentLink returns link to action comment. func (a *Action) GetCommentLink(ctx context.Context) string { - return a.getCommentLink(ctx) -} - -func (a *Action) getCommentLink(ctx context.Context) string { if a == nil { return "#" } @@ -347,26 +328,15 @@ func (a *Action) getCommentLink(ctx context.Context) string { if a.Comment != nil { return a.Comment.Link(ctx) } - if len(a.GetIssueInfos()) == 0 { - return "#" - } - // Return link to issue - issueIDString := a.GetIssueInfos()[0] - issueID, err := strconv.ParseInt(issueIDString, 10, 64) - if err != nil { - return "#" - } - issue, err := issues_model.GetIssueByID(ctx, issueID) - if err != nil { + if err := a.LoadIssue(ctx); err != nil || a.Issue == nil { return "#" } - - if err = issue.LoadRepo(ctx); err != nil { + if err := a.Issue.LoadRepo(ctx); err != nil { return "#" } - return issue.Link() + return a.Issue.Link() } // GetBranch returns the action's repository branch. @@ -394,33 +364,61 @@ func (a *Action) GetCreate() time.Time { return a.CreatedUnix.AsTime() } +func (a *Action) IsIssueEvent() bool { + return a.OpType.InActions("comment_issue", "approve_pull_request", "reject_pull_request", "comment_pull", "merge_pull_request") +} + // GetIssueInfos returns a list of issues associated with // the action. func (a *Action) GetIssueInfos() []string { return strings.SplitN(a.Content, "|", 3) } +func (a *Action) getIssueIndex() int64 { + infos := a.GetIssueInfos() + if len(infos) == 0 { + return 0 + } + index, _ := strconv.ParseInt(infos[0], 10, 64) + return index +} + +func (a *Action) LoadIssue(ctx context.Context) error { + if a.Issue != nil { + return nil + } + if index := a.getIssueIndex(); index > 0 { + issue, err := issues_model.GetIssueByIndex(ctx, a.RepoID, index) + if err != nil { + return err + } + a.Issue = issue + a.Issue.Repo = a.Repo + } + return nil +} + // GetIssueTitle returns the title of first issue associated with the action. func (a *Action) GetIssueTitle(ctx context.Context) string { - index, _ := strconv.ParseInt(a.GetIssueInfos()[0], 10, 64) - issue, err := issues_model.GetIssueByIndex(ctx, a.RepoID, index) - if err != nil { + if err := a.LoadIssue(ctx); err != nil { log.Error("GetIssueByIndex: %v", err) return "500 when get issue" } - return issue.Title + return a.Issue.Title } // GetIssueContent returns the content of first issue associated with // this action. func (a *Action) GetIssueContent(ctx context.Context) string { - index, _ := strconv.ParseInt(a.GetIssueInfos()[0], 10, 64) - issue, err := issues_model.GetIssueByIndex(ctx, a.RepoID, index) - if err != nil { - log.Error("GetIssueByIndex: %v", err) - return "500 when get issue" + if index := a.getIssueIndex(); index > 0 { + issue, err := issues_model.GetIssueByIndex(ctx, a.RepoID, index) + if err != nil { + log.Error("GetIssueByIndex: %v", err) + return "500 when get issue" + } + return issue.Content } - return issue.Content + return "" } // GetFeedsOptions options for retrieving feeds @@ -460,7 +458,7 @@ func GetFeeds(ctx context.Context, opts GetFeedsOptions) (ActionList, int64, err return nil, 0, fmt.Errorf("FindAndCount: %w", err) } - if err := ActionList(actions).loadAttributes(ctx); err != nil { + if err := ActionList(actions).LoadAttributes(ctx); err != nil { return nil, 0, fmt.Errorf("LoadAttributes: %w", err) } diff --git a/models/activities/action_list.go b/models/activities/action_list.go index 220535c9b7a1a..fdf0f35d4f457 100644 --- a/models/activities/action_list.go +++ b/models/activities/action_list.go @@ -6,12 +6,16 @@ package activities import ( "context" "fmt" + "strconv" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" + "code.gitea.io/gitea/modules/util" + + "xorm.io/builder" ) // ActionList defines a list of actions @@ -64,11 +68,11 @@ func (actions ActionList) LoadRepositories(ctx context.Context) error { if err != nil { return fmt.Errorf("find repository: %w", err) } - for _, action := range actions { action.Repo = repoMaps[action.RepoID] } - return nil + repos := repo_model.RepositoryList(util.ValuesOfMap(repoMaps)) + return repos.LoadUnits(ctx) } func (actions ActionList) loadRepoOwner(ctx context.Context, userMap map[int64]*user_model.User) (err error) { @@ -101,18 +105,23 @@ func (actions ActionList) loadRepoOwner(ctx context.Context, userMap map[int64]* return nil } -// loadAttributes loads all attributes -func (actions ActionList) loadAttributes(ctx context.Context) error { +// LoadAttributes loads all attributes +func (actions ActionList) LoadAttributes(ctx context.Context) error { + // the load sequence cannot be changed because of the dependencies userMap, err := actions.LoadActUsers(ctx) if err != nil { return err } - if err := actions.LoadRepositories(ctx); err != nil { return err } - - return actions.loadRepoOwner(ctx, userMap) + if err := actions.loadRepoOwner(ctx, userMap); err != nil { + return err + } + if err := actions.LoadIssues(ctx); err != nil { + return err + } + return actions.LoadComments(ctx) } func (actions ActionList) LoadComments(ctx context.Context) error { @@ -135,6 +144,59 @@ func (actions ActionList) LoadComments(ctx context.Context) error { for _, action := range actions { if action.CommentID > 0 { action.Comment = commentsMap[action.CommentID] + if action.Comment != nil { + action.Comment.Issue = action.Issue + } + } + } + return nil +} + +func (actions ActionList) LoadIssues(ctx context.Context) error { + if len(actions) == 0 { + return nil + } + + conditions := builder.NewCond() + issueNum := 0 + for _, action := range actions { + if action.IsIssueEvent() { + infos := action.GetIssueInfos() + if len(infos) == 0 { + continue + } + index, _ := strconv.ParseInt(infos[0], 10, 64) + if index > 0 { + conditions = conditions.Or(builder.Eq{ + "repo_id": action.RepoID, + "`index`": index, + }) + issueNum++ + } + } + } + if !conditions.IsValid() { + return nil + } + + issuesMap := make(map[string]*issues_model.Issue, issueNum) + issues := make([]*issues_model.Issue, 0, issueNum) + if err := db.GetEngine(ctx).Where(conditions).Find(&issues); err != nil { + return fmt.Errorf("find issue: %w", err) + } + for _, issue := range issues { + issuesMap[fmt.Sprintf("%d-%d", issue.RepoID, issue.Index)] = issue + } + + for _, action := range actions { + if !action.IsIssueEvent() { + continue + } + if index := action.getIssueIndex(); index > 0 { + if issue, ok := issuesMap[fmt.Sprintf("%d-%d", action.RepoID, index)]; ok { + action.Issue = issue + action.Issue.Repo = action.Repo + } } } return nil diff --git a/models/repo/repo.go b/models/repo/repo.go index 13493ba6e80e6..f71f06b7746c8 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -519,6 +519,9 @@ func (repo *Repository) GetBaseRepo(ctx context.Context) (err error) { return nil } + if repo.BaseRepo != nil { + return nil + } repo.BaseRepo, err = GetRepositoryByID(ctx, repo.ForkID) return err } diff --git a/modules/util/slice.go b/modules/util/slice.go index a7073fedee8b1..926900f76287d 100644 --- a/modules/util/slice.go +++ b/modules/util/slice.go @@ -53,3 +53,11 @@ func Sorted[S ~[]E, E cmp.Ordered](values S) S { slices.Sort(values) return values } + +func ValuesOfMap[K comparable, V any](m map[K]V) []V { + values := make([]V, 0, len(m)) + for _, v := range m { + values = append(values, v) + } + return values +} diff --git a/routers/web/feed/convert.go b/routers/web/feed/convert.go index 1d649aaa5a351..c175a0d282c05 100644 --- a/routers/web/feed/convert.go +++ b/routers/web/feed/convert.go @@ -70,15 +70,6 @@ func renderMarkdown(ctx *context.Context, act *activities_model.Action, content // feedActionsToFeedItems convert gitea's Action feed to feeds Item func feedActionsToFeedItems(ctx *context.Context, actions activities_model.ActionList) (items []*feeds.Item, err error) { - if _, err := actions.LoadActUsers(ctx); err != nil { - return nil, err - } - if err := actions.LoadRepositories(ctx); err != nil { - return nil, err - } - if err := actions.LoadComments(ctx); err != nil { - return nil, err - } for _, act := range actions { var content, desc, title string From 490a11f4aaeeca8dbb14cf25f21100af7c274c0f Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 19 Feb 2024 16:13:18 +0800 Subject: [PATCH 5/7] Fix bug --- models/activities/action.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/models/activities/action.go b/models/activities/action.go index bfe000982543a..80912f65b8fb7 100644 --- a/models/activities/action.go +++ b/models/activities/action.go @@ -402,7 +402,10 @@ func (a *Action) LoadIssue(ctx context.Context) error { func (a *Action) GetIssueTitle(ctx context.Context) string { if err := a.LoadIssue(ctx); err != nil { log.Error("GetIssueByIndex: %v", err) - return "500 when get issue" + return "<500 when get issue>" + } + if a.Issue == nil { + return "" } return a.Issue.Title } From 46b1480f791a93ddf5ff307228a0dde79424b59d Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Mon, 19 Feb 2024 16:18:02 +0800 Subject: [PATCH 6/7] More refactoring --- models/activities/action.go | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/models/activities/action.go b/models/activities/action.go index 80912f65b8fb7..e55a96691da8e 100644 --- a/models/activities/action.go +++ b/models/activities/action.go @@ -401,7 +401,7 @@ func (a *Action) LoadIssue(ctx context.Context) error { // GetIssueTitle returns the title of first issue associated with the action. func (a *Action) GetIssueTitle(ctx context.Context) string { if err := a.LoadIssue(ctx); err != nil { - log.Error("GetIssueByIndex: %v", err) + log.Error("LoadIssue: %v", err) return "<500 when get issue>" } if a.Issue == nil { @@ -410,18 +410,16 @@ func (a *Action) GetIssueTitle(ctx context.Context) string { return a.Issue.Title } -// GetIssueContent returns the content of first issue associated with -// this action. +// GetIssueContent returns the content of first issue associated with this action. func (a *Action) GetIssueContent(ctx context.Context) string { - if index := a.getIssueIndex(); index > 0 { - issue, err := issues_model.GetIssueByIndex(ctx, a.RepoID, index) - if err != nil { - log.Error("GetIssueByIndex: %v", err) - return "500 when get issue" - } - return issue.Content + if err := a.LoadIssue(ctx); err != nil { + log.Error("LoadIssue: %v", err) + return "<500 when get issue>" + } + if a.Issue == nil { + return "" } - return "" + return a.Issue.Content } // GetFeedsOptions options for retrieving feeds From edf7a7801c5a4af126e5b958dae1cdb02e49144b Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 8 Mar 2024 17:06:27 +0800 Subject: [PATCH 7/7] Add a comment for ValuesOfMap --- modules/util/slice.go | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/util/slice.go b/modules/util/slice.go index 926900f76287d..f00e84bf06e9b 100644 --- a/modules/util/slice.go +++ b/modules/util/slice.go @@ -54,6 +54,7 @@ func Sorted[S ~[]E, E cmp.Ordered](values S) S { return values } +// TODO: Replace with "maps.Values" once available func ValuesOfMap[K comparable, V any](m map[K]V) []V { values := make([]V, 0, len(m)) for _, v := range m {