Apologies in advance for a very n00b-ish question. I have a use case where I want to create a workflow that only responds to signals and never actually completes. Essentially a “state machine” kind of thing where the workflow begins waiting for signals as soon it’s started and only ever waits for new signals and reacts to them. Here’s a kind of silly example that should illustrate the barrier I’m running into:
type Person struct {
Name string
}
func PersonNameWorkflow(ctx workflow.Context, person Person) error {
log := workflow.GetLogger(ctx)
var name string
nameChan := workflow.GetSignalChannel(ctx, "name-channel")
s := workflow.NewSelector(ctx)
s.AddReceive(nameChan, func(c workflow.ReceiveChannel, more bool) {
c.Receive(ctx, &name)
person.Name = name
log.Info("received signal")
})
s.Select(ctx)
return nil
}
In this case, if a signal is received the workflow proceeds and completes. What I’d like it to do, though, is to simply continue waiting until it’s canceled by a client and make the current state queryable.
If you are waiting for a single signal type you don’t need the selector. Just call nameChan.Receive in a loop. As @mleow pointed out if you need to process a very large number of signals then it is recommended to call ContinueAsNew periodically (let’s say every 1k signals received) to keep the workflow event history size bounded.
@mleow In this particular case I was kind of hoping to retain the same run ID across signals, so unfortunately this approach doesn’t quite work for me, but I appreciate the help! The NewContinueAsNewError trick is something I always forget but it’s super handy.
@maxim In this case I actually do need to handle multiple signal types (which wasn’t reflected in my trivial example). Is there a convenient way to do that?