Temporal Cron Questions

Hi,

I’m planning to use a cron workflow to schedule tasks periodically. The task runs every 15 minutes and would fan out more workflows consumed by another service.

I have the following questions regarding how to set up the cron:

  1. If I want this cron triggered by only 1 instance at a time and running in a dedicated service. Should I just trigger the cron workflow during service start up time?
  2. If yes to Q1, when I redeploy the service each time, this would mean a new cron workflow will be triggered, if it is using the same workflow id, will this cause failures?
  3. If during the redeployment, I change some config of the workflow, like the cron schedule from 15 min to 5 min, How will Temporal pick up the change and make sure all subsequent runs will execute with the latest version? (I dont care existing scheduled run)?
  4. Is there a good way to stop or pause the cron workflow?

Thanks!
Bill

2 Likes
  1. There is no problem triggering workflow by more than one instance. Temporal ensures the uniqueness of workflow executions by their WorkflowId. So if your triggering code is using the same ID then there will be only one workflow execution running. The trigger code should ignore the WorkflowExecutionAlreadyStarted exception which is thrown in the case of duplicated starts.
  2. No problem here.
  3. Currently, there is no way to update a cron workflow schedule directly without stopping the cron workflow. The workarounds are:
    3.1. Triggering code can query already running the workflow for its cron schedule and then terminate and start it again if it changed.
    3.2. Do not use “cron” workflow feature and implement your own periodic workflow that can check if cron schedule has changed using activity and sleep accordingly. Here is a periodic workflow example. And here is an example of updating timer on the signal which is also relevant.
1 Like

Thanks a lot for the reply! @maxim

Would calling continueAsNew on the workflow also pick up the new cron schedule?

I believe it does pick it up. But please test.

1 Like

@maxim Is there an example for how to do this (with the Java SDK)? I can’t seem to find the API for querying an existing cron schedule.

Workflow.getInfo().getCronSchedule() exposes this, but how can I query it from outside of the workflow?

Would calling continueAsNew on the workflow also pick up the new cron schedule?

No, currently if a cron workflow calls continueAsNew the created new run loses cronSchedule prop.

You would need to get the workflow history, and and get the cronSchedule from the first event.
Example:

public static String getCronSchedule(WorkflowExecution wfExec) {
     GetWorkflowExecutionHistoryRequest req = GetWorkflowExecutionHistoryRequest.newBuilder()
                .setNamespace(client.getOptions().getNamespace())
                .setExecution(wfExec)
                .build();
     GetWorkflowExecutionHistoryResponse res =
                service.blockingStub().getWorkflowExecutionHistory(req);
     HistoryEvent firstEvent = res.getHistory().getEvents(0);
     return firstEvent.getWorkflowExecutionStartedEventAttributes().getCronSchedule();
}

You can invoke it with:

getCronSchedule(WorkflowExecution.newBuilder()
                .setWorkflowId("<wokflow_id>")
                .setRunId("<workflow_run_id>")
                .build())

Thank you @tihomir. After writing my question, I also found that we can use an untyped workflow stub: WorkflowStub#getOptions()#getCronSchedule(). This should work as well?

Yes, if you have a running execution you could do something like:

// create new wf stub for existing exec
MyWorkflow workflow = client.newWorkflowStub(MyWorkflow.class, "<workflow_id>");
// convert to untyped
WorkflowStub untyped = WorkflowStub.fromTyped(workflow);
String cron = untyped.getOptions().get().getCronSchedule();

or use untyped stub directly

WorkflowStub stub = client.newUntypedWorkflowStub("<workflow_id>", Optional.empty(), Optional.empty());
stub.getOptions().get().getCronSchedule();
1 Like