@@ -42,75 +42,80 @@ func mailIssueCommentToParticipants(ctx *mailCommentContext, mentions []int64) e
42
42
}
43
43
44
44
// Enough room to avoid reallocations
45
- unfiltered := make ([] int64 , 1 , 64 )
45
+ toNotify := make (map [ int64 ] struct {} , 64 )
46
46
47
47
// =========== Original poster ===========
48
- unfiltered [ 0 ] = ctx .Issue .PosterID
48
+ toNotify [ ctx .Issue .PosterID ] = struct {}{}
49
49
50
50
// =========== Assignees ===========
51
51
ids , err := models .GetAssigneeIDsByIssue (ctx .Issue .ID )
52
52
if err != nil {
53
53
return fmt .Errorf ("GetAssigneeIDsByIssue(%d): %v" , ctx .Issue .ID , err )
54
54
}
55
- unfiltered = append (unfiltered , ids ... )
55
+ for _ , id := range ids {
56
+ toNotify [id ] = struct {}{}
57
+ }
56
58
57
59
// =========== Participants (i.e. commenters, reviewers) ===========
58
60
ids , err = models .GetParticipantsIDsByIssueID (ctx .Issue .ID )
59
61
if err != nil {
60
62
return fmt .Errorf ("GetParticipantsIDsByIssueID(%d): %v" , ctx .Issue .ID , err )
61
63
}
62
- unfiltered = append (unfiltered , ids ... )
64
+ for _ , id := range ids {
65
+ toNotify [id ] = struct {}{}
66
+ }
63
67
64
68
// =========== Issue watchers ===========
65
69
ids , err = models .GetIssueWatchersIDs (ctx .Issue .ID )
66
70
if err != nil {
67
71
return fmt .Errorf ("GetIssueWatchersIDs(%d): %v" , ctx .Issue .ID , err )
68
72
}
69
- unfiltered = append (unfiltered , ids ... )
73
+ for _ , id := range ids {
74
+ toNotify [id ] = struct {}{}
75
+ }
70
76
71
77
// =========== Repo watchers ===========
72
78
// Make repo watchers last, since it's likely the list with the most users
73
79
ids , err = models .GetRepoWatchersIDs (ctx .Issue .RepoID )
74
80
if err != nil {
75
81
return fmt .Errorf ("GetRepoWatchersIDs(%d): %v" , ctx .Issue .RepoID , err )
76
82
}
77
- unfiltered = append ( ids , unfiltered ... )
78
-
79
- visited := make ( map [ int64 ] bool , len ( unfiltered ) + len ( mentions ) + 1 )
83
+ for _ , id := range ids {
84
+ toNotify [ id ] = struct {}{}
85
+ }
80
86
81
87
// Avoid mailing the doer
82
- visited [ctx .Doer .ID ] = true
83
-
84
- if err = mailIssueCommentBatch (ctx , unfiltered , visited , false ); err != nil {
85
- return fmt .Errorf ("mailIssueCommentBatch(): %v" , err )
86
- }
88
+ delete (toNotify , ctx .Doer .ID )
87
89
88
90
// =========== Mentions ===========
89
- if err = mailIssueCommentBatch (ctx , mentions , visited , true ); err != nil {
91
+ for _ , m := range mentions {
92
+ delete (toNotify , m )
93
+ }
94
+ if err = mailIssueCommentBatch (ctx , mentions , true ); err != nil {
90
95
return fmt .Errorf ("mailIssueCommentBatch() mentions: %v" , err )
91
96
}
92
97
98
+ notify := make ([]int64 , len (toNotify ))
99
+ for id := range toNotify {
100
+ notify = append (notify , id )
101
+ }
102
+ if err = mailIssueCommentBatch (ctx , notify , false ); err != nil {
103
+ return fmt .Errorf ("mailIssueCommentBatch(): %v" , err )
104
+ }
93
105
return nil
94
106
}
95
107
96
- func mailIssueCommentBatch (ctx * mailCommentContext , ids []int64 , visited map [ int64 ] bool , fromMention bool ) error {
108
+ func mailIssueCommentBatch (ctx * mailCommentContext , ids []int64 , fromMention bool ) error {
97
109
const batchSize = 100
98
110
for i := 0 ; i < len (ids ); i += batchSize {
99
- var last int
111
+ job := make ([] int64 , batchSize )
100
112
if i + batchSize < len (ids ) {
101
- last = i + batchSize
113
+ job = ids [ i : i + batchSize ]
102
114
} else {
103
- last = len (ids )
104
- }
105
- unique := make ([]int64 , 0 , last - i )
106
- for j := i ; j < last ; j ++ {
107
- id := ids [j ]
108
- if _ , ok := visited [id ]; ! ok {
109
- unique = append (unique , id )
110
- visited [id ] = true
111
- }
115
+ job = ids [i :]
112
116
}
113
- recipients , err := models .GetMaileableUsersByIDs (unique )
117
+
118
+ recipients , err := models .GetMaileableUsersByIDs (job )
114
119
if err != nil {
115
120
return err
116
121
}
0 commit comments