ContinueAsNew + signals

@maxim and to be clear, would it be accurate to say that it is not possible to “drain” using a Selector? i.e. even if you are not blocking while processing signals you still need to drain every channel with ReceiveAsync before returning after Select. So if you are using a selector like @yugandhar, then you need to something like this:

type channelConfig struct {
  channel workflow.ReceiveChannel
  val interface{}
  handler func()  // do something with val
}

channels := []*channelConfig{
  {
    channel: workflow.GetSignalChannel(...)
    val: "",
    handler func() {
      // do something with val
    },
  },
  // etc
}

s := workflow.NewSelector(ctx)
for _, cc := range channels {
  s.AddReceive(cc.channel, func (c workflow.ReceiveChannel, _ bool) {
    c.Receive(ctx, &cc.val)
    cc.handler()
  })
}

for keepGoing {
  s.Select(ctx)
  // not safe to return here
}

// Now I want to return but first I need to make sure that no signals are pending
canReturn := false
for !canReturn {
  canReturn = true
  for _, cc := range channels {
    if ok := c.ReceiveAsync(&cc.val); ok {
      canReturn = false
      cc.handler()
    }
  }
}

This should work both with and without blocking calls in the handlers.

Is that right? It feels kind of awkward but I can’t think of a simpler way to express it.