We need to implement a notification scheduler for our app, the idea is that users can set reminders about contract renewals. Users could set reminders for each contract with different settings and frequencies.
Our first approach was to build our own scheduler to send all pending notifications at a given execution time, but we found Temporal Schedule that seems to cover our requirements.
Our approach is to create a Schedule for each reminder created by the user and any other scheduled notifications the system will create based on specific application events, also we would use Schedule Update capability for when a user wants to change the reminder.
For our first PoC, we created a Schedule specifying a StartAt and EndAt with a Cron expression to execute every minute. We expected about 5 executions given we set the start/end for a difference of 5 minutes.
The execution worked as expected, but then we noticed the schedule was still running, it never ended, even though there were no more Upcoming Runs.
The scenario we wanted to mimic is a user setting a reminder for a specific day in the future and then every 2 days until another date or the reminder is canceled.
Not sure if we are missing something or if the way we pretend to use the Schedule is wrong.
I really appreciate any help and guidance you can provide.
In our local test we are using temporal lite.
This is the code we use to test:
package main
import (
"context"
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/worker"
"go.temporal.io/sdk/workflow"
"time"
)
func main() {
c, err := client.Dial(client.Options{})
if err != nil {
panic(err)
}
w := worker.New(c, "notifications", worker.Options{})
w.RegisterWorkflow(Notify)
_, err = c.ScheduleClient().Create(context.TODO(), client.ScheduleOptions{
ID: "notification-schedule-poc-1",
Spec: client.ScheduleSpec{
CronExpressions: []string{"* * * * *"},
StartAt: time.Now().Add(time.Minute),
EndAt: time.Now().Add(time.Minute * 6),
},
Action: &client.ScheduleWorkflowAction{
ID: "notification-workflow",
Workflow: Notify,
Args: []interface{}{"the reminder params"},
TaskQueue: "notifications",
},
})
if err != nil {
panic(err)
}
if err := w.Run(worker.InterruptCh()); err != nil {
panic(err)
}
}
func Notify(ctx workflow.Context, value string) error {
workflow.GetLogger(ctx).Info("Notify", "value", value)
return nil
}