Cadence Go client improvement ideas
mfateev opened this issue · comments
Cadence Go client has been used in production for over two years. While it has been pretty well received there are known issues which we would like to fix in the next major (possibly incompatible release).
The known issues to address:
- Allow registration of activities struct with a worker (#600)
- Get rid of static register calls
- Add a code generator to allow calling activities by the interface they implement as it is done in Java client.
- Add middleware to allow intercepting workflow API calls like (ExecuteActivity)
- Consider not using context for passing ActivityOptions and ChildWorkflowOptions
- Channel.Receive should return error as this calls involves deserialization when channel is a signal one
- Add Channel.ReceiveWithTimeout
- Selector API can be simplified. For example selector.AddTimeout(duration) can be added.
Feel free to add your ideas about possible improvements.
I would consider using OpenCensus or OpenTelemetry instead of Tally. Uber is already a part of the OpenTelemetry effort through Jaeger. (Not sure if this is actually a client issue, but I can see tally in the list of dependencies)
I've got a couple of ideas:
- New error values. I wonder if cadence-client would benefit from the new error values added to the standard library? E.g., would it deprecate functions like
IsGenericError
? Available since Go 1.13 but also in older versions viagolang.org/x/xerrors
. Interesting reads: [1], [2]. - Aliased types. I found hard to get used to aliased types. I'm sure there must be a good reason to export types that way, but it's not very clear for new users how to follow them. E.g. when I land to https://godoc.org/go.uber.org/cadence I see the
RetryPolicy
type with a one-line comment. I need to click oninternal.RetryPolicy
which is clarifying but it also brings the user to a package of unexported types. Perhaps a good start could be to clarify the use of the internal package, perhaps with a mention in cadence.go and/or https://cadenceworkflow.io/docs/07_goclient/.
I would like to see something to better manage waiting for activities that does not return any value. Adding a Future.Wait
method seems like the most straightforward solution to me.
I would like to see something to better manage waiting for activities that does not return any value. Adding a Future.Wait method seems like the most straightforward solution to me.
@furuholm, I've been using Future.Get(ctx, nil)
. Have you tried that? But I think that your method would be nicer.
@sevein I have, and I could have sworn that I got an error when I did that. I will try again. Thanks for the advice!
From a convo in Slack, the user requests to make available general helpers for creating clients and worker services. I understand that most of the complexity origins in creating the workflowserviceclient object because it requires a yarpc dispatcher plus tchannel transport. I guess that it could be similar to the build helper in factory.go that is part of cadence-samples.
@sevein I tried Future.Get(ctx, nil)
and it worked. I must have tried Future.Get(ctx)
when I didn't get it to work.
Consider merging Client.StartWorkflow and ExecuteWorkflow as ExecuteWorkflow returns a future that might be used to get runID and workflowID and waiting for completion through Get is optional.
- Allow registration of activities struct with a worker (#600)
Registering SampleStruct{Dep: dep}.PerformFunc
as a workflow or an activity, and referencing SampleStruct{}.PerformFunc
for execution already works.
It's, apparently, also not necessary to use string names in calls to ExecuteWorkflow/ExecuteActivity. I'll share an example in #600.
That only works if the worker and the publisher share the same codebase.
That only works if the worker and the publisher share the same codebase.
Wouldn't it be the same case for a standalone func as well?
Disparate codebases would necessitate stringly typed workflow/activity names.
Yeah, it would. I kinda mixed up two things together here.
So registering structs is not possible at the moment. Registering a struct would mean that all of it's exported functions are registered as workflows/activities.
What I referred to is indeed a different problem, but AFAIK the new struct registration implementation will also include simpler naming conventions.