How to keep workflow paused and open indefinitely

In the case of a non-retryable error or an error caused by the exhaustion of the retry policy of an activity, i want to pause the workflow and keep it open there instead of failing it by returning an error. Then i can review the cause of error, fix and reset the workflow if needed or even continue the workflow. Just wondering through what mechanism can i achieve this pause behaviour. Thanks!

Edit: Not thinking properly. Await solves this

Here is a Java sample that implements your idea as an interceptor:

1 Like

Hi @maxim, so instead of using interceptors im trying to use workflow.Await.

In the test below i get a deadline exceeded (type: ScheduleToClose) error before a minute. Just wondering how can i write a test to indicate that the workflow was waiting for signal and timed out. Thanks!

// Awaits for a signal from given workflow channel
func AwaitWorkflowSignal(ctx workflow.Context, channelName string) error {
	err := workflow.Await(ctx, func() bool {
		channel := workflow.GetSignalChannel(ctx, channelName)
		channel.Receive(ctx, nil)
		return true
	})
	if err != nil {
		return err
	}

	return nil
}

// A test workflow to test AwaitWorkflowSignal
func AwaitWorkflowSignalTestWorkflow(ctx workflow.Context) error {
	err := AwaitWorkflowSignal(ctx, "channel-name")
	if err != nil {
		return err
	}

	return nil
}
type WorkflowsTestSuite struct {
	suite.Suite
	testsuite.WorkflowTestSuite
}

// How to write this test properly
func (s *WorkflowsTestSuite) TestAwaitWorkflowSignal_Timeout() {
	env := s.NewTestWorkflowEnvironment()
	env.SetTestTimeout(time.Minute)

	env.ExecuteWorkflow(AwaitWorkflowSignalTestWorkflow)

        // Assert timeout error?
}

This code doesn’t make sense to me:

err := workflow.Await(ctx, func() bool {
		channel := workflow.GetSignalChannel(ctx, channelName)
		channel.Receive(ctx, nil)
		return true
	})

[/quote]
How is it different from:

channel := workflow.GetSignalChannel(ctx, channelName)
channel.Receive(ctx, nil)

Ah yeah my bad, no need for the await. Still same question applies on how to test that workflow is waiting for a signal

Use env.RegisterDelayedCallback.

Hey thanks for your help so far. Just want to confirm that this effectively tests that the workflow waits for a signal and times out because of the SetWorkflowRunTimeout i’ve set.

// Test workflow waits for a signal
func TestAwaitWorkflowSignal() {
	env := s.NewTestWorkflowEnvironment()
	env.SetWorkflowRunTimeout(time.Minute)

	env.RegisterDelayedCallback(func() {
		env.SignalWorkflow(testChannelName, nil)
	}, time.Hour)

	env.ExecuteWorkflow(AwaitWorkflowSignalTestWorkflow)
}

I"'m not sure if this test makes sense as it tests the Temporal framework itself, not your business logic.

Sorry mate, in that case how would someone test that a workflow is awaiting a signal until configured workflow end?

You mentioned to use env.RegisterDelayedCallback earlier. I can use it to send a signal and check that workflow is complete. But what about the case to test that the workflow will wait indefinitely until a signal is recieved. It would be nice to test this, as it’s a part of the business flow that would be nice to confirm with a test.

Maybe the test i have above (removing the delayed callback stuff, since that doesnt test anything) where the workflow waits for a signal and times out kind of achieves this.

I don’t think this is possible to test in principle. You can delay the callback to a second before the workflow timeout, but it is still not 100% guarantee that the signal waits till the timeout.