Deserialization error for signal struct

Folks,

Need some guidance; have not been able to figure out how to pass a struct in a signal. It works when passing string or when struct marshalled into string.

However when try to pass in signal OffBoardingReq struct; it fails to decode after receiving.

Error Details

NEW Lifecycle started .. for  mleow
Blocking ...
SIG2: More? true
2021/02/28 20:34:05 ERROR Deserialization error. Corrupted signal received on channel CLF-OFF-BOARD. Namespace INFRAML TaskQueue credential-lifecycle WorkerID 36229@Mojaves-iMac.local@ WorkflowType CredentialsLifecycleWorkflow WorkflowID BOOMER3-mleow RunID b523df20-5b0d-4fb5-a7ab-c25263010895 Attempt 1 Error payload item 0: unable to decode: json: Unmarshal(nil *rds_password_lifecycle.OffBoardingReq)

Workflow Code snippet

type OffBoardingReq struct {
	Username    string
	Immediately bool
}

func CredentialsLifecycleWorkflow(ctx workflow.Context, lifecycle CredentialsLifecycle) error {
	fmt.Println("NEW Lifecycle started .. for ", lifecycle.Username)
...
	sig1Ch := workflow.GetSignalChannel(ctx, "CLF-ON-BOARD")
	sig2Ch := workflow.GetSignalChannel(ctx, "CLF-OFF-BOARD")

	s := workflow.NewSelector(ctx)

	var signal1 *OnBoardingReq
	var signal2 *OffBoardingReq
...
	s.AddReceive(sig2Ch, func(c workflow.ReceiveChannel, more bool) {
		fmt.Println("SIG2: More?", more)
		c.Receive(ctx, signal2)
	})
	// Block until receive
	fmt.Println("Blocking ...")
	s.Select(ctx)
..

Signal Triggering

...
			wf, wferr := c.SignalWithStartWorkflow(context.Background(),
                                "CLF-mleow",
				"CLF-OFF-BOARD", rds_password_lifecycle.OffBoardingReq{
				    Username:    "mleow",
				    Immediately: true,
			        },
				client.StartWorkflowOptions{
			            TaskQueue: "credential-lifecycle",
				},
				rds_password_lifecycle.CredentialsLifecycleWorkflow, rds_password_lifecycle.CredentialsLifecycle{"mleow"})

...

What am I doing wrong?

Try changing your code to:

	var signal1 OnBoardingReq
	var signal2 OffBoardingReq
...
	s.AddReceive(sig2Ch, func(c workflow.ReceiveChannel, more bool) {
		fmt.Println("SIG2: More?", more)
		c.Receive(ctx, &signal2)
	})
	// Block until receive
	fmt.Println("Blocking ...")
	s.Select(ctx)

I works! Thanks @maxim So if I understand it correctly, it failed due to the receiver ptr being nil rather than being a pointer to the zero value of the struct instead.

It would have helped if the docs / examples have this slightly more complicated example; and also maybe better directed error message for beginner users.

Will be happy to submit a PR as example; where do you suggest to put it? In docs, examples?

1 Like

So if I understand it correctly, it failed due to the receiver ptr being nil rather than being a pointer to the zero value of the struct instead.

It is not a zero value of the struct. It is a struct instance with default field values.

Documentation would be a good place to mention this.