Run workflow once in future time

Hello guys, I hope everyone is fine and safe.

I have been studying temporal, and I am thinking to use in my current company.

I have a question which I couldn’t find an “easy” solution, reading the docs and examples.

I need to schedule a job to run once, in a future time (like after 2 weeks, 1 month… etc).
It must run only once. I know I can start a workflow and keep it running (blocked using sleep and so on) until the future time I need.
I can also use cron job, and after the first time it runs, in some way kill the cron, avoiding to run another time.

I am wondering if there is a “simpler” way to do that.

Thanks in advance.

The simplest supported way is to start the workflow which sleeps for the desired time before executing the job through an activity.

1 Like

Also be careful when using a timer/sleep if you want to schedule a workflow to be executed at a specific date.
If your workers are not running, your timers will not be started

I don’t know if it’s intended to have to do this, but this is what I do

I have a starting_date, let’s say it’s 10 days from now (“now” being the date when my workflow gets scheduled)
Instead of making it sleep for 10 days, I will substract my starting_date from workflow.Now (workflow.Now being the time when the workflow is picked up by a worker)
So now my workflow will correctly sleep until the starting_date

func MyScheduledWorkflow(ctx workflow.Context, starting_date int64) error {
	sleepDuration := starting_date - workflow.Now(ctx).Unix()
	workflow.Sleep(ctx, time.Second*time.Duration(sleepDuration))
}

I would have thought temporal takes the difference between WorkflowTaskScheduled's and WorkflowTaskStarted's creation dates
then deducts from the time used in timers and sleeps.

Or maybe it’s already doing it and I am doing things wrong?

@evlad you have a good point. You can use workflow.Info.WorkflowStartTime to retrieve the time when workflow was started:

func MyScheduledWorkflow(ctx workflow.Context, delay int64) error {
	timeSinceStarted :=workflow.Now(ctx).Sub(workflow.GetInfo(ctx).WorkflowStartTime)
	sleepDuration := time.Second * time.Duration(delay) - timeSinceStarted
	workflow.Sleep(ctx, sleepDuration)
}
1 Like