summaryrefslogtreecommitdiffstats
path: root/app/email_batching.go
diff options
context:
space:
mode:
authorJonathan <jonfritz@gmail.com>2017-09-05 16:39:07 -0400
committerJoram Wilander <jwawilander@gmail.com>2017-09-05 16:39:07 -0400
commit016b5daa1cde1a147701aafce94f67057fbb7aa6 (patch)
treefd1e70b4790feeb6a3e26541192d5857a224d22e /app/email_batching.go
parent2977b31a3942ac0e6bd2ad1c38f2c008037c54a6 (diff)
downloadchat-016b5daa1cde1a147701aafce94f67057fbb7aa6.tar.gz
chat-016b5daa1cde1a147701aafce94f67057fbb7aa6.tar.bz2
chat-016b5daa1cde1a147701aafce94f67057fbb7aa6.zip
PLT-7444: If there is activity in Mattermost before the email batch is sent, do not send the email (#7342)
* Changed email batching short-circuit logic to look at last viewed at timestamp in channel member struct instead of in user's status struct, since the latter is only updated if the user's status is set to online * Fixed unit tests * Reduced right-hand drift * Reduced total number of store calls by loading all channel member objects for user exactly once per team that the user received notifications for
Diffstat (limited to 'app/email_batching.go')
-rw-r--r--app/email_batching.go40
1 files changed, 29 insertions, 11 deletions
diff --git a/app/email_batching.go b/app/email_batching.go
index 2e643d2b1..4b557c678 100644
--- a/app/email_batching.go
+++ b/app/email_batching.go
@@ -122,24 +122,42 @@ func (job *EmailBatchingJob) handleNewNotifications() {
}
func (job *EmailBatchingJob) checkPendingNotifications(now time.Time, handler func(string, []*batchedNotification)) {
- // look for users who've acted since pending posts were received
for userId, notifications := range job.pendingNotifications {
- schan := Srv.Store.Status().Get(userId)
- pchan := Srv.Store.Preference().Get(userId, model.PREFERENCE_CATEGORY_NOTIFICATIONS, model.PREFERENCE_NAME_EMAIL_INTERVAL)
batchStartTime := notifications[0].post.CreateAt
+ inspectedTeamNames := make(map[string]string)
+ for _, notification := range notifications {
+ // at most, we'll do one check for each team that notifications were sent for
+ if inspectedTeamNames[notification.teamName] != "" {
+ continue
+ }
+ tchan := Srv.Store.Team().GetByName(notifications[0].teamName)
+ if result := <-tchan; result.Err != nil {
+ l4g.Error("Unable to find Team id for notification", result.Err)
+ continue
+ } else if team, ok := result.Data.(*model.Team); ok {
+ inspectedTeamNames[notification.teamName] = team.Id
+ }
- // check if the user has been active and would've seen any new posts
- if result := <-schan; result.Err != nil {
- l4g.Error(utils.T("api.email_batching.check_pending_emails.status.app_error"), result.Err)
- delete(job.pendingNotifications, userId)
- continue
- } else if status := result.Data.(*model.Status); status.LastActivityAt >= batchStartTime {
- delete(job.pendingNotifications, userId)
- continue
+ // if the user has viewed any channels in this team since the notification was queued, delete
+ // all queued notifications
+ mchan := Srv.Store.Channel().GetMembersForUser(inspectedTeamNames[notification.teamName], userId)
+ if result := <-mchan; result.Err != nil {
+ l4g.Error("Unable to find ChannelMembers for user", result.Err)
+ continue
+ } else if channelMembers, ok := result.Data.(*model.ChannelMembers); ok {
+ for _, channelMember := range *channelMembers {
+ if channelMember.LastViewedAt >= batchStartTime {
+ l4g.Info("Deleted notifications for user %s", userId)
+ delete(job.pendingNotifications, userId)
+ break
+ }
+ }
+ }
}
// get how long we need to wait to send notifications to the user
var interval int64
+ pchan := Srv.Store.Preference().Get(userId, model.PREFERENCE_CATEGORY_NOTIFICATIONS, model.PREFERENCE_NAME_EMAIL_INTERVAL)
if result := <-pchan; result.Err != nil {
// use the default batching interval if an error ocurrs while fetching user preferences
interval, _ = strconv.ParseInt(model.PREFERENCE_EMAIL_INTERVAL_BATCHING_SECONDS, 10, 64)