satellite/nodeevents: add method UpdateLastAttempted

Add method to update last_attempted column for a group of rows.

Change-Id: Ib6eadc9efc21368fccb12d1e824c90612c26a8f7
This commit is contained in:
Cameron 2022-11-18 17:18:30 -05:00 committed by Storj Robot
parent b27c6dd032
commit 76c22fa572
3 changed files with 109 additions and 12 deletions

View File

@ -25,14 +25,17 @@ type DB interface {
GetByID(ctx context.Context, id uuid.UUID) (nodeEvent NodeEvent, err error) GetByID(ctx context.Context, id uuid.UUID) (nodeEvent NodeEvent, err error)
// UpdateEmailSent updates email_sent for a group of rows. // UpdateEmailSent updates email_sent for a group of rows.
UpdateEmailSent(ctx context.Context, ids []uuid.UUID, timestamp time.Time) (err error) UpdateEmailSent(ctx context.Context, ids []uuid.UUID, timestamp time.Time) (err error)
// UpdateLastAttempted updates last_attempted for a group of rows.
UpdateLastAttempted(ctx context.Context, ids []uuid.UUID, timestamp time.Time) (err error)
} }
// NodeEvent contains information needed to notify a node operator about something that happened to a node. // NodeEvent contains information needed to notify a node operator about something that happened to a node.
type NodeEvent struct { type NodeEvent struct {
ID uuid.UUID ID uuid.UUID
Email string Email string
NodeID storj.NodeID NodeID storj.NodeID
Event Type Event Type
CreatedAt time.Time CreatedAt time.Time
EmailSent *time.Time LastAttempted *time.Time
EmailSent *time.Time
} }

View File

@ -132,12 +132,13 @@ func fromDBX(dbxNE *dbx.NodeEvent) (event nodeevents.NodeEvent, err error) {
return event, err return event, err
} }
return nodeevents.NodeEvent{ return nodeevents.NodeEvent{
ID: id, ID: id,
Email: dbxNE.Email, Email: dbxNE.Email,
NodeID: nodeID, NodeID: nodeID,
Event: nodeevents.Type(dbxNE.Event), Event: nodeevents.Type(dbxNE.Event),
CreatedAt: dbxNE.CreatedAt, CreatedAt: dbxNE.CreatedAt,
EmailSent: dbxNE.EmailSent, LastAttempted: dbxNE.LastAttempted,
EmailSent: dbxNE.EmailSent,
}, nil }, nil
} }
@ -151,3 +152,14 @@ func (ne *nodeEvents) UpdateEmailSent(ctx context.Context, ids []uuid.UUID, time
`, timestamp, pgutil.UUIDArray(ids)) `, timestamp, pgutil.UUIDArray(ids))
return err return err
} }
// UpdateLastAttempted updates last_attempted for a group of rows.
func (ne *nodeEvents) UpdateLastAttempted(ctx context.Context, ids []uuid.UUID, timestamp time.Time) (err error) {
defer mon.Task()(&ctx)(&err)
_, err = ne.db.ExecContext(ctx, `
UPDATE node_events SET last_attempted = $1
WHERE id = ANY($2::bytea[])
`, timestamp, pgutil.UUIDArray(ids))
return err
}

View File

@ -81,6 +81,39 @@ func TestNodeEventsUpdateEmailSent(t *testing.T) {
}) })
} }
func TestNodeEventsUpdateLastAttempted(t *testing.T) {
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
testID1 := teststorj.NodeIDFromString("test1")
testID2 := teststorj.NodeIDFromString("test2")
testEmail1 := "test1@storj.test"
eventType := nodeevents.Disqualified
event1, err := db.NodeEvents().Insert(ctx, testEmail1, testID1, eventType)
require.NoError(t, err)
event1, err = db.NodeEvents().GetByID(ctx, event1.ID)
require.NoError(t, err)
require.Nil(t, event1.LastAttempted)
event2, err := db.NodeEvents().Insert(ctx, testEmail1, testID2, eventType)
require.NoError(t, err)
event2, err = db.NodeEvents().GetByID(ctx, event2.ID)
require.NoError(t, err)
require.Nil(t, event2.LastAttempted)
require.NoError(t, db.NodeEvents().UpdateLastAttempted(ctx, []uuid.UUID{event1.ID, event2.ID}, time.Now()))
event1, err = db.NodeEvents().GetByID(ctx, event1.ID)
require.NoError(t, err)
require.NotNil(t, event1.LastAttempted)
event2, err = db.NodeEvents().GetByID(ctx, event2.ID)
require.NoError(t, err)
require.NotNil(t, event2.LastAttempted)
})
}
func TestNodeEventsGetByID(t *testing.T) { func TestNodeEventsGetByID(t *testing.T) {
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) { satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
testID1 := teststorj.NodeIDFromString("test1") testID1 := teststorj.NodeIDFromString("test1")
@ -158,3 +191,52 @@ func TestNodeEventsGetNextBatch(t *testing.T) {
require.True(t, foundEvent2) require.True(t, foundEvent2)
}) })
} }
func TestNodeEventsGetNextBatchSelectionOrder(t *testing.T) {
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
testID1 := teststorj.NodeIDFromString("test1")
testID2 := teststorj.NodeIDFromString("test2")
testEmail1 := "test1@storj.test"
testEmail2 := "test2@storj.test"
eventType := nodeevents.Disqualified
event1, err := db.NodeEvents().Insert(ctx, testEmail1, testID1, eventType)
require.NoError(t, err)
// insert one event with same email and event type, but with different node ID. It should be selected.
event2, err := db.NodeEvents().Insert(ctx, testEmail1, testID2, eventType)
require.NoError(t, err)
// insert one event with same email and event type, but email_sent is not null. Should not be selected.
event3, err := db.NodeEvents().Insert(ctx, testEmail1, testID1, eventType)
require.NoError(t, err)
require.NoError(t, db.NodeEvents().UpdateEmailSent(ctx, []uuid.UUID{event3.ID}, time.Now()))
// insert one event with same email, but different type. Should not be selected.
_, err = db.NodeEvents().Insert(ctx, testEmail1, testID1, nodeevents.BelowMinVersion)
require.NoError(t, err)
// insert one event with same event type, but different email. Should not be selected.
_, err = db.NodeEvents().Insert(ctx, testEmail2, testID1, eventType)
require.NoError(t, err)
batch, err := db.NodeEvents().GetNextBatch(ctx, time.Now())
require.NoError(t, err)
require.Len(t, batch, 2)
var foundEvent1, foundEvent2 bool
for _, ne := range batch {
switch ne.NodeID {
case event1.NodeID:
foundEvent1 = true
case event2.NodeID:
foundEvent2 = true
default:
}
}
require.True(t, foundEvent1)
require.True(t, foundEvent2)
})
}