From 7bb1c41cff469f5abb773f7eb6de2010f07d6855 Mon Sep 17 00:00:00 2001 From: Brandur Leach Date: Thu, 4 Jul 2024 07:37:05 -0700 Subject: [PATCH] Prepare release 0.9.0 + add test for periodic job bundle (#421) We haven't cut a new release in a while, and the bug in #420 is kind of bad, so now that there's a fix it's not a bad time to cut a new release. I'm also including a test case that catches the bug from #420. Apparently none of our other test cases can catch the problem, so it's good to have a regression guard. --- CHANGELOG.md | 3 ++ go.mod | 8 ++-- periodic_job_test.go | 71 +++++++++++++++++++++++++++++ riverdriver/go.mod | 2 +- riverdriver/riverdatabasesql/go.mod | 4 +- riverdriver/riverpgxv5/go.mod | 4 +- 6 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 periodic_job_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index e9224429..33c89841 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.9.0] - 2024-07-04 + ### Added - `Config.TestOnly` has been added. It disables various features in the River client like staggered maintenance service start that are useful in production, but may be somewhat harmful in tests because they make start/stop slower. [PR #414](https://github.com/riverqueue/river/pull/414). @@ -28,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Pausing or resuming a queue that was already paused or not paused respectively no longer returns `rivertype.ErrNotFound`. The same goes for pausing or resuming using the all queues string (`*`) when no queues are in the database (previously that also returned `rivertype.ErrNotFound`). [PR #408](https://github.com/riverqueue/river/pull/408). +- Fix a bug where periodic job constructors were only called once when adding the periodic job rather than being invoked every time the periodic job is scheduled. [PR #420](https://github.com/riverqueue/river/pull/420). ## [0.8.0] - 2024-06-25 diff --git a/go.mod b/go.mod index fadfcc33..edb07775 100644 --- a/go.mod +++ b/go.mod @@ -14,10 +14,10 @@ require ( github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa github.com/jackc/pgx/v5 v5.6.0 github.com/jackc/puddle/v2 v2.2.1 - github.com/riverqueue/river/riverdriver v0.8.0 - github.com/riverqueue/river/riverdriver/riverdatabasesql v0.8.0 - github.com/riverqueue/river/riverdriver/riverpgxv5 v0.8.0 - github.com/riverqueue/river/rivertype v0.8.0 + github.com/riverqueue/river/riverdriver v0.9.0 + github.com/riverqueue/river/riverdriver/riverdatabasesql v0.9.0 + github.com/riverqueue/river/riverdriver/riverpgxv5 v0.9.0 + github.com/riverqueue/river/rivertype v0.9.0 github.com/robfig/cron/v3 v3.0.1 github.com/stretchr/testify v1.9.0 go.uber.org/goleak v1.3.0 diff --git a/periodic_job_test.go b/periodic_job_test.go new file mode 100644 index 00000000..1bb3cf84 --- /dev/null +++ b/periodic_job_test.go @@ -0,0 +1,71 @@ +package river + +import ( + "encoding/json" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/riverqueue/river/internal/maintenance" + "github.com/riverqueue/river/internal/riverinternaltest" +) + +func TestPeriodicJobBundle(t *testing.T) { + t.Parallel() + + type testBundle struct{} + + setup := func(t *testing.T) (*PeriodicJobBundle, *testBundle) { + t.Helper() + + periodicJobEnqueuer := maintenance.NewPeriodicJobEnqueuer( + riverinternaltest.BaseServiceArchetype(t), + &maintenance.PeriodicJobEnqueuerConfig{}, + nil, + ) + + return newPeriodicJobBundle(newTestConfig(t, nil), periodicJobEnqueuer), &testBundle{} + } + + t.Run("ConstructorFuncGeneratesNewArgsOnEachCall", func(t *testing.T) { + t.Parallel() + + periodicJobBundle, _ := setup(t) + + type TestJobArgs struct { + JobArgsReflectKind[TestJobArgs] + JobNum int `json:"job_num"` + } + + var jobNum int + + periodicJob := NewPeriodicJob( + PeriodicInterval(15*time.Minute), + func() (JobArgs, *InsertOpts) { + jobNum++ + return TestJobArgs{JobNum: jobNum}, nil + }, + nil, + ) + + internalPeriodicJob := periodicJobBundle.toInternal(periodicJob) + + insertParams1, _, err := internalPeriodicJob.ConstructorFunc() + require.NoError(t, err) + require.Equal(t, 1, mustUnmarshalJSON[TestJobArgs](t, insertParams1.EncodedArgs).JobNum) + + insertParams2, _, err := internalPeriodicJob.ConstructorFunc() + require.NoError(t, err) + require.Equal(t, 2, mustUnmarshalJSON[TestJobArgs](t, insertParams2.EncodedArgs).JobNum) + }) +} + +func mustUnmarshalJSON[T any](t *testing.T, data []byte) *T { + t.Helper() + + var val T + err := json.Unmarshal(data, &val) + require.NoError(t, err) + return &val +} diff --git a/riverdriver/go.mod b/riverdriver/go.mod index 2586824c..b2777b82 100644 --- a/riverdriver/go.mod +++ b/riverdriver/go.mod @@ -4,4 +4,4 @@ go 1.21.4 replace github.com/riverqueue/river/rivertype => ../rivertype -require github.com/riverqueue/river/rivertype v0.8.0 +require github.com/riverqueue/river/rivertype v0.9.0 diff --git a/riverdriver/riverdatabasesql/go.mod b/riverdriver/riverdatabasesql/go.mod index 5238c1c5..bf3be64e 100644 --- a/riverdriver/riverdatabasesql/go.mod +++ b/riverdriver/riverdatabasesql/go.mod @@ -8,8 +8,8 @@ replace github.com/riverqueue/river/rivertype => ../../rivertype require ( github.com/lib/pq v1.10.9 - github.com/riverqueue/river/riverdriver v0.8.0 - github.com/riverqueue/river/rivertype v0.8.0 + github.com/riverqueue/river/riverdriver v0.9.0 + github.com/riverqueue/river/rivertype v0.9.0 github.com/stretchr/testify v1.9.0 ) diff --git a/riverdriver/riverpgxv5/go.mod b/riverdriver/riverpgxv5/go.mod index a3aa0a1b..460c825d 100644 --- a/riverdriver/riverpgxv5/go.mod +++ b/riverdriver/riverpgxv5/go.mod @@ -9,8 +9,8 @@ replace github.com/riverqueue/river/rivertype => ../../rivertype require ( github.com/jackc/pgx/v5 v5.5.0 github.com/jackc/puddle/v2 v2.2.1 - github.com/riverqueue/river/riverdriver v0.8.0 - github.com/riverqueue/river/rivertype v0.8.0 + github.com/riverqueue/river/riverdriver v0.9.0 + github.com/riverqueue/river/rivertype v0.9.0 github.com/stretchr/testify v1.9.0 )