Skip to content

Commit 084a2b0

Browse files
6543guillep2k
andauthored
Code Refactor of IssueWatch related things (#10401)
* refactor * optimize * remove Iretating function LoadWatchUsers do not load Users into IW object and it is used only in api ... so move this logic * remove unessesary * Apply suggestions from code review Thx Co-Authored-By: guillep2k <[email protected]> * make Tests more robust * fix rebase * restart CI * CI no dont hit sqlites deadlock Co-authored-by: guillep2k <[email protected]>
1 parent e5944a9 commit 084a2b0

File tree

8 files changed

+66
-80
lines changed

8 files changed

+66
-80
lines changed

integrations/repofiles_update_test.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,11 +207,14 @@ func TestCreateOrUpdateRepoFileForCreate(t *testing.T) {
207207

208208
commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch)
209209
expectedFileResponse := getExpectedFileResponseForRepofilesCreate(commitID)
210-
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
211-
assert.EqualValues(t, expectedFileResponse.Commit.SHA, fileResponse.Commit.SHA)
212-
assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL)
213-
assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email)
214-
assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name)
210+
assert.NotNil(t, expectedFileResponse)
211+
if expectedFileResponse != nil {
212+
assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content)
213+
assert.EqualValues(t, expectedFileResponse.Commit.SHA, fileResponse.Commit.SHA)
214+
assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL)
215+
assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email)
216+
assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name)
217+
}
215218
})
216219
}
217220

models/issue_watch.go

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,14 @@ func getIssueWatch(e Engine, userID, issueID int64) (iw *IssueWatch, exists bool
6868
// but avoids joining with `user` for performance reasons
6969
// User permissions must be verified elsewhere if required
7070
func GetIssueWatchersIDs(issueID int64) ([]int64, error) {
71+
return getIssueWatchersIDs(x, issueID, true)
72+
}
73+
74+
func getIssueWatchersIDs(e Engine, issueID int64, watching bool) ([]int64, error) {
7175
ids := make([]int64, 0, 64)
72-
return ids, x.Table("issue_watch").
76+
return ids, e.Table("issue_watch").
7377
Where("issue_id=?", issueID).
74-
And("is_watching = ?", true).
78+
And("is_watching = ?", watching).
7579
Select("user_id").
7680
Find(&ids)
7781
}
@@ -99,39 +103,9 @@ func getIssueWatchers(e Engine, issueID int64, listOptions ListOptions) (IssueWa
99103
}
100104

101105
func removeIssueWatchersByRepoID(e Engine, userID int64, repoID int64) error {
102-
iw := &IssueWatch{
103-
IsWatching: false,
104-
}
105106
_, err := e.
106107
Join("INNER", "issue", "`issue`.id = `issue_watch`.issue_id AND `issue`.repo_id = ?", repoID).
107-
Cols("is_watching", "updated_unix").
108108
Where("`issue_watch`.user_id = ?", userID).
109-
Update(iw)
109+
Delete(new(IssueWatch))
110110
return err
111111
}
112-
113-
// LoadWatchUsers return watching users
114-
func (iwl IssueWatchList) LoadWatchUsers() (users UserList, err error) {
115-
return iwl.loadWatchUsers(x)
116-
}
117-
118-
func (iwl IssueWatchList) loadWatchUsers(e Engine) (users UserList, err error) {
119-
if len(iwl) == 0 {
120-
return []*User{}, nil
121-
}
122-
123-
var userIDs = make([]int64, 0, len(iwl))
124-
for _, iw := range iwl {
125-
if iw.IsWatching {
126-
userIDs = append(userIDs, iw.UserID)
127-
}
128-
}
129-
130-
if len(userIDs) == 0 {
131-
return []*User{}, nil
132-
}
133-
134-
err = e.In("id", userIDs).Find(&users)
135-
136-
return
137-
}

models/notification.go

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -133,72 +133,66 @@ func CreateOrUpdateIssueNotifications(issueID, commentID int64, notificationAuth
133133
}
134134

135135
func createOrUpdateIssueNotifications(e Engine, issueID, commentID int64, notificationAuthorID int64) error {
136-
issueWatches, err := getIssueWatchers(e, issueID, ListOptions{})
136+
// init
137+
toNotify := make(map[int64]struct{}, 32)
138+
notifications, err := getNotificationsByIssueID(e, issueID)
137139
if err != nil {
138140
return err
139141
}
140-
141142
issue, err := getIssueByID(e, issueID)
142143
if err != nil {
143144
return err
144145
}
145146

146-
watches, err := getWatchers(e, issue.RepoID)
147+
issueWatches, err := getIssueWatchersIDs(e, issueID, true)
147148
if err != nil {
148149
return err
149150
}
151+
for _, id := range issueWatches {
152+
toNotify[id] = struct{}{}
153+
}
150154

151-
notifications, err := getNotificationsByIssueID(e, issueID)
155+
repoWatches, err := getRepoWatchersIDs(e, issue.RepoID)
152156
if err != nil {
153157
return err
154158
}
155-
156-
alreadyNotified := make(map[int64]struct{}, len(issueWatches)+len(watches))
157-
158-
notifyUser := func(userID int64) error {
159-
// do not send notification for the own issuer/commenter
160-
if userID == notificationAuthorID {
161-
return nil
162-
}
163-
164-
if _, ok := alreadyNotified[userID]; ok {
165-
return nil
166-
}
167-
alreadyNotified[userID] = struct{}{}
168-
169-
if notificationExists(notifications, issue.ID, userID) {
170-
return updateIssueNotification(e, userID, issue.ID, commentID, notificationAuthorID)
171-
}
172-
return createIssueNotification(e, userID, issue, commentID, notificationAuthorID)
159+
for _, id := range repoWatches {
160+
toNotify[id] = struct{}{}
173161
}
174162

175-
for _, issueWatch := range issueWatches {
176-
// ignore if user unwatched the issue
177-
if !issueWatch.IsWatching {
178-
alreadyNotified[issueWatch.UserID] = struct{}{}
179-
continue
180-
}
181-
182-
if err := notifyUser(issueWatch.UserID); err != nil {
183-
return err
184-
}
163+
// dont notify user who cause notification
164+
delete(toNotify, notificationAuthorID)
165+
// explicit unwatch on issue
166+
issueUnWatches, err := getIssueWatchersIDs(e, issueID, false)
167+
if err != nil {
168+
return err
169+
}
170+
for _, id := range issueUnWatches {
171+
delete(toNotify, id)
185172
}
186173

187174
err = issue.loadRepo(e)
188175
if err != nil {
189176
return err
190177
}
191178

192-
for _, watch := range watches {
179+
// notify
180+
for userID := range toNotify {
193181
issue.Repo.Units = nil
194-
if issue.IsPull && !issue.Repo.checkUnitUser(e, watch.UserID, false, UnitTypePullRequests) {
182+
if issue.IsPull && !issue.Repo.checkUnitUser(e, userID, false, UnitTypePullRequests) {
195183
continue
196184
}
197-
if !issue.IsPull && !issue.Repo.checkUnitUser(e, watch.UserID, false, UnitTypeIssues) {
185+
if !issue.IsPull && !issue.Repo.checkUnitUser(e, userID, false, UnitTypeIssues) {
198186
continue
199187
}
200188

201-
if err := notifyUser(watch.UserID); err != nil {
189+
if notificationExists(notifications, issue.ID, userID) {
190+
if err = updateIssueNotification(e, userID, issue.ID, commentID, notificationAuthorID); err != nil {
191+
return err
192+
}
193+
continue
194+
}
195+
if err = createIssueNotification(e, userID, issue, commentID, notificationAuthorID); err != nil {
202196
return err
203197
}
204198
}

models/repo_watch.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,12 @@ func GetWatchers(repoID int64) ([]*Watch, error) {
144144
// but avoids joining with `user` for performance reasons
145145
// User permissions must be verified elsewhere if required
146146
func GetRepoWatchersIDs(repoID int64) ([]int64, error) {
147+
return getRepoWatchersIDs(x, repoID)
148+
}
149+
150+
func getRepoWatchersIDs(e Engine, repoID int64) ([]int64, error) {
147151
ids := make([]int64, 0, 64)
148-
return ids, x.Table("watch").
152+
return ids, e.Table("watch").
149153
Where("watch.repo_id=?", repoID).
150154
And("watch.mode<>?", RepoWatchModeDont).
151155
Select("user_id").

models/user.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1409,7 +1409,7 @@ func GetUserNamesByIDs(ids []int64) ([]string, error) {
14091409
}
14101410

14111411
// GetUsersByIDs returns all resolved users from a list of Ids.
1412-
func GetUsersByIDs(ids []int64) ([]*User, error) {
1412+
func GetUsersByIDs(ids []int64) (UserList, error) {
14131413
ous := make([]*User, 0, len(ids))
14141414
if len(ids) == 0 {
14151415
return ous, nil

modules/git/repo_branch.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ type Branch struct {
4848

4949
// GetHEADBranch returns corresponding branch of HEAD.
5050
func (repo *Repository) GetHEADBranch() (*Branch, error) {
51+
if repo == nil {
52+
return nil, fmt.Errorf("nil repo")
53+
}
5154
stdout, err := NewCommand("symbolic-ref", "HEAD").RunInDir(repo.Path)
5255
if err != nil {
5356
return nil, err

modules/test/context_tests.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,11 @@ func LoadRepoCommit(t *testing.T, ctx *context.Context) {
5858
defer gitRepo.Close()
5959
branch, err := gitRepo.GetHEADBranch()
6060
assert.NoError(t, err)
61-
ctx.Repo.Commit, err = gitRepo.GetBranchCommit(branch.Name)
62-
assert.NoError(t, err)
61+
assert.NotNil(t, branch)
62+
if branch != nil {
63+
ctx.Repo.Commit, err = gitRepo.GetBranchCommit(branch.Name)
64+
assert.NoError(t, err)
65+
}
6366
}
6467

6568
// LoadUser load a user into a test context.

routers/api/v1/repo/issue_subscription.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,14 @@ func GetIssueSubscribers(ctx *context.APIContext) {
190190
return
191191
}
192192

193-
users, err := iwl.LoadWatchUsers()
193+
var userIDs = make([]int64, 0, len(iwl))
194+
for _, iw := range iwl {
195+
userIDs = append(userIDs, iw.UserID)
196+
}
197+
198+
users, err := models.GetUsersByIDs(userIDs)
194199
if err != nil {
195-
ctx.Error(http.StatusInternalServerError, "LoadWatchUsers", err)
200+
ctx.Error(http.StatusInternalServerError, "GetUsersByIDs", err)
196201
return
197202
}
198203

0 commit comments

Comments
 (0)