Throw-away activities in Workflow

Sometimes in my workflows I want to do a “throw-away” activity, meaning I want it to happen eventually if possible but I don’t care about the result and I don’t want to wait for it. An example could be firing off an email notification of something else the workflow has done. If the email takes a week to get sent, or never gets sent, I don’t want it to have any impact on the rest of the workflow because it is just a notification.

My pattern so far has been to start a new coroutine with workflow.Go and using a context separate from the rest of the activities (e.g. it is not cancellable):

workflow.Go(ctx, func(ctx workflow.Context) {
	emailContext := workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
		StartToCloseTimeout: time.Minute,
		RetryPolicy: &temporal.RetryPolicy{
			MaximumInterval: time.Minute,
		},
	})
	err := workflow.ExecuteActivity(emailContext, activities.SendEmail /* , params... */).Get(ctx, nil)
	// Log error if any
}

Is there any downside to this approach? Is there another method that is better?

One issue I can think of is, what happens if the workflow finishes while the coroutine is still active?

Replying to myself, I guess I could just start the activity and never call Get? Is that better? What happens to that activity if the workflow ends?

Replying to myself, I guess I could just start the activity and never call Get ? Is that better?

For a single activity not calling Get on its Future is simpler than the workflow.Go code route. Otherwise, it is practically the same. The workflow.Go route consumes a little bit more resources on the worker due to additional goroutine used.

One issue I can think of is, what happens if the workflow finishes while the coroutine is still active?

Activity will be automatically canceled. So to ensure that an activity completes the workflow must wait for its completion before completing itself.

1 Like