Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(BEDS-1162) Fix: don't increase mailsSent count if limit reached #1287

Open
wants to merge 2 commits into
base: staging
Choose a base branch
from

Conversation

remoterami
Copy link
Contributor

The mail sender does check the maxEmailsPerDay limit, but it increases the count anyways which results in wrong numbers being shown.

Fixed & renamed the count setter + added a getter method for clarity.

Comment on lines 425 to 429
func QueueEmailNotifications(epoch uint64, notificationsByUserID types.NotificationsPerUserId, tx *sqlx.Tx) error {
// for emails multiple notifications will be rendered to one email per user for each run
// TODO filter out ratelimited users, don't need to queue or even render emails
emails, err := RenderEmailsForUserEvents(epoch, notificationsByUserID)
if err != nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be the clean thing to do. Instead of storing rendered emails to db first and let the sender throw them away again later, doing it here with batch querying of user premium perks + email counts from redis would be a nice early out.

Copy link
Contributor

@peterbitfly peterbitfly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also include a section on how those changes were tested / validated.

@@ -78,14 +78,14 @@ func createTextMessage(msg types.Email) string {
// It will return a ratelimit-error if the configured ratelimit is exceeded.
func SendMailRateLimited(content types.TransitEmailContent, maxEmailsPerDay int64, bucket string) error {
sendThresholdReachedMail := false
count, err := db.CountSentMessage(bucket, content.UserId)
count, err := db.GetSentMessagesCount(context.Background(), bucket, content.UserId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is save, as multiple senders run at the same time, so some kind of locking needs to be implemented here.

Copy link
Contributor Author

@remoterami remoterami Jan 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. I went back to the original approach of increasing the count in redis before sending the mail, but added an upper limit using optimistic locking (see cas). I assume this should solve the issue for us.

If actual locking should be required, I would suggest integrating redis' distributed-locks (instead of some psql locking) as it's close to the data in question here and prob faster; however that'd add another dependency. ptal

@remoterami remoterami force-pushed the BEDS-1162/respect-email-threshhold branch from 5bed928 to 2ae82ab Compare January 23, 2025 12:47
@remoterami
Copy link
Contributor Author

remoterami commented Jan 23, 2025

Please also include a section on how those changes were tested / validated.

I ran some manual tests, isolating the affected methods and pointing to a local redis instance. But I could also try to setup unit testing for the notification sender if preferred.
(I'm not sure what the performance requirements are though, the best implementation could depend on the amount of users, networks, notifications etc)

@remoterami remoterami force-pushed the BEDS-1162/respect-email-threshhold branch from 2ae82ab to 927416b Compare January 23, 2025 15:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants