Making grpc calls from an activity


We have several micro-services, accessed using grpc. Want to orchestrate these. Typical workflow has just a few activities. Trying the following, but looks like the grpc client object is not serializable?


conn, err := grpc.Dial(address, grpc.WithInsecure())

c := svc1proto.NewSvc1Client(conn)

ao := workflow.ActivityOptions{
	StartToCloseTimeout:    50 * time.Second,
	ScheduleToCloseTimeout: 100 * time.Second,
ctx = workflow.WithActivityOptions(ctx, ao)

workflow.ExecuteActivity(ctx, activities.Activity1, nil, c).Get(ctx, nil)


func Activity1(ctx context.Context, c svc1proto.Svc1Client) error {
r, err := c.SvcMethod1()

return nil

In general, are there some best practices of how to structure the workflow/workers/activity code in go. Say we have 50+ services, accessed using grpc, each workflow typically calls 5 or so activities, and each activity makes the grpc service call. Searched here, but did not come up with much. Any pointers much appreciated. Thanks.

You should not use a gRPC client, or really any network or external system (disk, etc) from inside a workflow. If you want a client shared amongst your activities, you can instantiate a struct with the client as a member, then either individually register methods on the struct as activities or register the struct itself as activities with the worker (which causes all exported methods to be registered). The receiver of the activity method can then access its client.

Remember, when Temporal executes an activity, it goes to the server and can happen on a different server. You can’t send something like a client as a serializable parameter across a server. Also remember that Temporal workflows must be deterministic and free from side effects, so you should not do anything external from inside workflow code.

Thank you for the detailed explanation. Will try.