-
Notifications
You must be signed in to change notification settings - Fork 90
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
Add capability to schedule periodic jobs dynamically #288
Conversation
4fd4c50
to
85ceb9c
Compare
@@ -0,0 +1,189 @@ | |||
package river |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed this from periodic.go
to periodic_job.go
to be a bit more descriptive.
// leader because only the leader enqueues periodic jobs. To make sure that a | ||
// new periodic job is fully enabled or disabled, it should be added or removed | ||
// from _every_ active River client across all processes. | ||
func (b *PeriodicJobBundle) Remove(periodicJobHandle rivertype.PeriodicJobHandle) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Debated on whether this should return (1) nothing, (2) an error, (3) an OK boolean, or even (4) panic when a job handle isn't found.
Decided to go with no return value because I figure an unknown job will be an edge most people don't have to handle, and it mirrors the Go API of delete(map, key)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Only minor comments ✨
periodic_job.go
Outdated
// leader because only the leader enqueues periodic jobs. To make sure that a | ||
// new periodic job is fully enabled or disabled, it should be added or removed | ||
// from _every_ active River client across all processes. | ||
func (b *PeriodicJobBundle) RemoveManyAll(periodicJobHandles []rivertype.PeriodicJobHandle) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any particular reason for the All
suffix? I feel like RemoveMany
would suffice here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Damn, good catch. Totally a refactor problem where I renamed something, but apparently left an outdated artifact in there. That was close ...
t.Run("NoJobsConfigured", func(t *testing.T) { | ||
t.Parallel() | ||
|
||
svc, _ := setup(t) | ||
|
||
svc.periodicJobs = []*PeriodicJob{} | ||
// TODO: How about just don't configure the jobs in the first place. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missed TODO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, oops. I ended up changing the setup function to not add default jobs, but forgot to fix this.
Here, attempt to resolve #242 by providing a way for new periodic jobs to be added dynamically after a client's already started (i.e. not only by passing them to the client's initial constructor). The new API puts all functions on a separate `PeriodicJobs` bundle to avoid further polluting `Client`'s namespace, and to make all related functions easy to find. riverClient.PeriodicJobs().Add( river.NewPeriodicJob( river.PeriodicInterval(15*time.Minute), func() (river.JobArgs, *river.InsertOpts) { return PeriodicJobArgs{}, nil }, nil, ), ) Additions return a periodic job "handle" which can be used to remove an added job: periodicJobHandle := riverClient.PeriodicJobs().Add(...) riverClient.PeriodicJobs().Remove(periodicJobHandle) I used a handle because the `river.PeriodicJob` construct isn't particularly pretty to keep around, and contains a number of fields that are aren't comparable so its unsuitable for use in equality checks or as a map key. Adding a new periodic job bumps the enqueuer's run loop so that it enqueues the job immediately if it's configured with `RunOnStart`, and schedules its initial target run time. In other words, adding or removing periodic jobs should take effect ~instantly. Fixes #242.
85ceb9c
to
785c353
Compare
Thanks! |
Tees up the project for version `v0.2.0`. Contains a few small changes and bug fixes, and with a new periodic job feature from #288.
Here, attempt to resolve #242 by providing a way for new periodic jobs
to be added dynamically after a client's already started (i.e. not only
by passing them to the client's initial constructor).
The new API puts all functions on a separate
PeriodicJobs
bundle toavoid further polluting
Client
's namespace, and to make all relatedfunctions easy to find.
Additions return a periodic job "handle" which can be used to remove an
added job:
I used a handle because the
river.PeriodicJob
construct isn'tparticularly pretty to keep around, and contains a number of fields that
are aren't comparable so its unsuitable for use in equality checks or as
a map key.
Adding a new periodic job bumps the enqueuer's run loop so that it
enqueues the job immediately if it's configured with
RunOnStart
, andschedules its initial target run time. In other words, adding or
removing periodic jobs should take effect ~instantly.
Fixes #242.