-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: add a cleanup job for email events (#1924)
* add a cleanup job for email events * made worker configurable and 5 min period
- Loading branch information
1 parent
c356db7
commit e5aa390
Showing
7 changed files
with
174 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package db | ||
|
||
import "time" | ||
|
||
type MockDatabaseClient struct { | ||
CalledInsertEmailSentByTenant bool | ||
CalledCountEmailSentByTenantFrom bool | ||
CalledCleanupEmailSentByTenant bool | ||
|
||
InsertEmailSentByTenantFunc func(tenantID string) error | ||
CountEmailSentByTenantFromFunc func(tenantID string, from time.Time) (int64, error) | ||
CleanupEmailSentByTenantFunc func(before time.Time) (int64, error) | ||
} | ||
|
||
func (m *MockDatabaseClient) InsertEmailSentByTenant(tenantID string) error { | ||
m.CalledInsertEmailSentByTenant = true | ||
return m.InsertEmailSentByTenantFunc(tenantID) | ||
} | ||
|
||
func (m *MockDatabaseClient) CountEmailSentByTenantSince(tenantID string, from time.Time) (int64, error) { | ||
m.CalledCountEmailSentByTenantFrom = true | ||
return m.CountEmailSentByTenantFromFunc(tenantID, from) | ||
} | ||
|
||
func (m *MockDatabaseClient) CleanupEmailSentByTenant(before time.Time) (int64, error) { | ||
m.CalledCleanupEmailSentByTenant = true | ||
return m.CleanupEmailSentByTenantFunc(before) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package workers | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/golang/glog" | ||
"github.com/stackrox/acs-fleet-manager/emailsender/pkg/db" | ||
) | ||
|
||
// CleanupEmailSent is a worker used to periodically cleanup EmailSentByTenant events | ||
// stored in the database connection that are no longer needed to enforce rate limitting | ||
type CleanupEmailSent struct { | ||
DbConn db.DatabaseClient | ||
Period time.Duration | ||
ExpiredAfter time.Duration | ||
} | ||
|
||
// Run periodically executes a cleanup query against the given DB Connection | ||
func (c *CleanupEmailSent) Run(ctx context.Context) error { | ||
ticker := time.NewTicker(c.Period) | ||
|
||
glog.Info("Starting CleanupEmailSent worker...") | ||
for { | ||
select { | ||
case <-ctx.Done(): | ||
ticker.Stop() | ||
return fmt.Errorf("stopped cleanup worker: %w", context.Canceled) | ||
case <-ticker.C: | ||
numDeleted, err := c.DbConn.CleanupEmailSentByTenant(time.Now().Add(-c.ExpiredAfter)) | ||
if err != nil { | ||
glog.Errorf("failed to cleanup EmailSentByTenant: %v", err) | ||
} | ||
|
||
glog.Infof("deleted %d expired EmailSentByTenant events from DB", numDeleted) | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package workers | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
"github.com/stackrox/acs-fleet-manager/emailsender/pkg/db" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
var testTimeout = time.Second * 10 | ||
|
||
func TestCleanupEmailSent(t *testing.T) { | ||
mockDB := &db.MockDatabaseClient{ | ||
CleanupEmailSentByTenantFunc: func(before time.Time) (int64, error) { return 5, nil }, | ||
} | ||
|
||
cleanup := &CleanupEmailSent{ | ||
Period: time.Second * 1, | ||
ExpiredAfter: time.Hour * 48, | ||
DbConn: mockDB, | ||
} | ||
|
||
ctx, cancel := context.WithTimeout(context.TODO(), time.Second*3) | ||
defer cancel() | ||
|
||
timeoutTimer := time.NewTimer(testTimeout) | ||
defer timeoutTimer.Stop() | ||
|
||
var errChannel = make(chan error) | ||
|
||
go func() { | ||
err := cleanup.Run(ctx) | ||
errChannel <- err | ||
}() | ||
|
||
select { | ||
case err := <-errChannel: | ||
// Expect DB cleanup to be called at least once since this has been running for 3 seconds | ||
// until the context gets canceled | ||
require.True(t, mockDB.CalledCleanupEmailSentByTenant, "expected db cleanup to be called, but was not") | ||
require.ErrorIs(t, err, context.Canceled) | ||
case <-timeoutTimer.C: | ||
t.Fatal("cleanup did not stop on canceled context") | ||
} | ||
|
||
} |