@@ -2,6 +2,7 @@ package riverdrivertest
22
33import (
44 "context"
5+ "fmt"
56 "sort"
67 "strconv"
78 "testing"
@@ -12,6 +13,7 @@ import (
1213
1314 "github.com/riverqueue/river/internal/rivercommon"
1415 "github.com/riverqueue/river/riverdriver"
16+ riversharedmaintenance "github.com/riverqueue/river/rivershared/riversharedmaintenance"
1517 "github.com/riverqueue/river/rivershared/testfactory"
1618 "github.com/riverqueue/river/rivershared/util/ptrutil"
1719 "github.com/riverqueue/river/rivershared/util/sliceutil"
@@ -519,16 +521,22 @@ func exerciseJobRead[TTx any](ctx context.Context, t *testing.T, executorWithTx
519521 afterHorizon = horizon .Add (1 * time .Minute )
520522 )
521523
522- stuckJob1 := testfactory .Job (ctx , t , exec , & testfactory.JobOpts {AttemptedAt : & beforeHorizon , State : ptrutil .Ptr (rivertype .JobStateRunning )})
524+ metadataWithLastSeen := func (t time.Time ) []byte {
525+ return fmt .Appendf (nil , `{"%s": %q}` , riversharedmaintenance .MetadataKeyLastSeenAt ,
526+ t .UTC ().Round (time .Millisecond ).Format ("2006-01-02 15:04:05.999-07:00" ))
527+ }
528+
529+ stuckJob1 := testfactory .Job (ctx , t , exec , & testfactory.JobOpts {AttemptedAt : & beforeHorizon , Metadata : []byte (`{"other":"value"}` ), State : ptrutil .Ptr (rivertype .JobStateRunning )})
523530 stuckJob2 := testfactory .Job (ctx , t , exec , & testfactory.JobOpts {AttemptedAt : & beforeHorizon , State : ptrutil .Ptr (rivertype .JobStateRunning )})
531+ stuckJob3 := testfactory .Job (ctx , t , exec , & testfactory.JobOpts {AttemptedAt : & beforeHorizon , State : ptrutil .Ptr (rivertype .JobStateRunning )})
524532
525533 t .Logf ("horizon = %s" , horizon )
526534 t .Logf ("stuckJob1 = %s" , stuckJob1 .AttemptedAt )
527535 t .Logf ("stuckJob2 = %s" , stuckJob2 .AttemptedAt )
528536
529537 t .Logf ("stuckJob1 full = %s" , spew .Sdump (stuckJob1 ))
530538
531- // Not returned because we put a maximum of two .
539+ // Not returned because we put a maximum of three .
532540 _ = testfactory .Job (ctx , t , exec , & testfactory.JobOpts {AttemptedAt : & beforeHorizon , State : ptrutil .Ptr (rivertype .JobStateRunning )})
533541
534542 // Not stuck because not in running state.
@@ -537,13 +545,19 @@ func exerciseJobRead[TTx any](ctx context.Context, t *testing.T, executorWithTx
537545 // Not stuck because after queried horizon.
538546 _ = testfactory .Job (ctx , t , exec , & testfactory.JobOpts {AttemptedAt : & afterHorizon , State : ptrutil .Ptr (rivertype .JobStateRunning )})
539547
540- // Max two stuck
548+ // Not stuck because last seen is after queried horizon.
549+ _ = testfactory .Job (ctx , t , exec , & testfactory.JobOpts {AttemptedAt : & beforeHorizon , Metadata : metadataWithLastSeen (afterHorizon ), State : ptrutil .Ptr (rivertype .JobStateRunning )})
550+
551+ // Not stuck because attempted at is after queried horizon.
552+ _ = testfactory .Job (ctx , t , exec , & testfactory.JobOpts {AttemptedAt : & afterHorizon , Metadata : metadataWithLastSeen (beforeHorizon ), State : ptrutil .Ptr (rivertype .JobStateRunning )})
553+
554+ // Max three stuck.
541555 stuckJobs , err := exec .JobGetStuck (ctx , & riverdriver.JobGetStuckParams {
542- Max : 2 ,
556+ Max : 3 ,
543557 StuckHorizon : horizon ,
544558 })
545559 require .NoError (t , err )
546- require .Equal (t , []int64 {stuckJob1 .ID , stuckJob2 .ID },
560+ require .Equal (t , []int64 {stuckJob1 .ID , stuckJob2 .ID , stuckJob3 . ID },
547561 sliceutil .Map (stuckJobs , func (j * rivertype.JobRow ) int64 { return j .ID }))
548562 })
549563
0 commit comments