v0.5.0 Release
New Features and Improvements:
Breaking changes
Refactored cadence client from a single package to multiple packages. #300 #343
We hear feedback that our godoc was not usable because it mixes internal stuff with public APIs. So we decided to refactor our client library to better organize the code into multiple namespaces and hide internal implementation into its own internal package.
All customers who are using the existing cadence client will have to do manual upgrade to the newest client.
Note: no major behavior change is introduced in this upgrade, only thing customer have to do is string replacement.
Note: minimum required Go version for this release is 1.9.
- Moved cadence package into internal
- Added client, activity, workflow, encoded, worker, testsuite public packages that compose Cadence client public API. It used Type alias Go feature. That bumped minimal required Go version to 1.9.
- Renamed methods to comply with Go style. For example cadence.RegisterWorkflow became workflow.Register.
- Updated README to mention GetVersion
- Changed .travis.yml to use go 1.9
- Updated CONTRIBUTING to indicate minimum required Go version as 1.9
- Fixed Makefile to not run glide install on every invocation.
Please follow the steps below for upgrading.
- Change the glide.yaml to
- package: go.uber.org/cadence
version: ^0.5.0
subpackages:
- .gen/go/cadence
OR
Change glide.lock and change the following (this is an example)
Before:
- name: go.uber.org/cadence
version: 26b7a248b5d668006b959fa32f0d890659611c82
subpackages:
- .gen/go/cadence
- .gen/go/cadence/workflowserviceclient
- .gen/go/cadence/workflowservicetest
- .gen/go/shared
- common
- common/backoff
- common/cache
- common/metrics
- common/util
After:
- name: go.uber.org/cadence
version: e7123e7586e43a82c0a658403523f890d14668a9
subpackages:
- .gen/go/cadence
- .gen/go/cadence/workflowserviceclient
- .gen/go/cadence/workflowservicetest
- .gen/go/shared
- activity
- client
- encoded
- testsuite
- worker
- workflow
- In the terminal, do
glide install
- Change each go source file, with the following change, accordingly
# WORKER #
## import ##
"go.uber.org/cadence" -> "go.uber.org/cadence/worker"
## source ##
cadence.EnableVerboseLogging -> worker.EnableVerboseLogging
cadence.NewWorker -> worker.New
cadence.WorkerOptions -> worker.Options
cadence.Worker -> worker.Worker
# CLIENT #
## import ##
"go.uber.org/cadence" -> "go.uber.org/cadence/workflow"
## source ##
cadence.Client -> client.Client
cadence.ClientOptions -> client.Options
cadence.DomainClient -> client.DomainClient
cadence.StartWorkflowOptions -> client.StartWorkflowOptions
cadence.NewClient -> client.NewClient
cadence.NewDomainClient -> client.NewDomainClient
# WORKFLOW #
## import ##
"go.uber.org/cadence" -> "go.uber.org/cadence/workflow"
## source ##
cadence.ActivityOptions -> workflow.ActivityOptions
cadence.CancelFunc -> workflow.CancelFunc
cadence.Channel -> workflow.Channel
cadence.ChildWorkflowFuture -> workflow.ChildWorkflowFuture
cadence.ChildWorkflowOptions -> workflow.ChildWorkflowOptions
cadence.ChildWorkflowPolicy -> workflow.ChildWorkflowPolicy
cadence.ChildWorkflowPolicyAbandon -> workflow.ChildWorkflowPolicyAbandon
cadence.ChildWorkflowPolicyRequestCancel -> workflow.ChildWorkflowPolicyRequestCancel
cadence.ChildWorkflowPolicyTerminate -> workflow.ChildWorkflowPolicyTerminate
cadence.Context -> workflow.Context
cadence.ContinueAsNewError -> workflow.ContinueAsNewError
cadence.DefaultVersion -> workflow.DefaultVersion
cadence.ErrCanceled -> workflow.ErrCanceled
cadence.ErrDeadlineExceeded -> workflow.ErrDeadlineExceeded
cadence.ExecuteActivity -> workflow.ExecuteActivity
cadence.ExecuteChildWorkflow -> workflow.ExecuteChildWorkflow
cadence.Future -> workflow.Future
cadence.GenericError -> workflow.GenericError
cadence.GetLogger -> workflow.GetLogger
cadence.GetMetricsScope -> workflow.GetMetricsScope
cadence.GetSignalChannel -> workflow.GetSignalChannel
cadence.GetVersion -> workflow.GetVersion
cadence.GetWorkflowInfo -> workflow.GetInfo
cadence.Go -> workflow.Go
cadence.GoNamed -=> workflow.GoNamed
cadence.NewBufferedChannel -> workflow.NewBufferedChannel
cadence.NewChannel -> workflow.NewChannel
cadence.NewContinueAsNewError -> workflow.NewContinueAsNewError
cadence.NewFuture -> workflow.NewFuture
cadence.NewHeartbeatTimeoutError -> workflow.NewHeartbeatTimeoutError
cadence.NewNamedBufferedChannel -> workflow.NewNamedBufferedChannel
cadence.NewNamedChannel -> workflow.NewNamedChannel
cadence.NewNamedSelector -> workflow.NewNamedSelector
cadence.NewSelector -> workflow.NewSelector
cadence.NewTimeoutError -> workflow.NewTimeoutError
cadence.NewTimer -> workflow.NewTimer
cadence.Now -> workflow.Now
cadence.PanicError -> workflow.PanicError
cadence.RegisterWorkflow -> workflow.Register
cadence.RegisterWorkflowOptions -> workflow.RegisterOptions
cadence.RegisterWorkflowWithOptions -> workflow.RegisterWithOptions
cadence.RequestCancelWorkflow -> workflow.RequestCancelWorkflow
cadence.Selector -> workflow.Selector
cadence.SetQueryHandler -> workflow.SetQueryHandler
cadence.Settable -> workflow.Settable
cadence.SideEffect -> workflow.SideEffect
cadence.Sleep -> workflow.Sleep
cadence.TimeoutError -> workflow.TimeoutError
cadence.Version -> workflow.Version
cadence.WithActivityOptions -> workflow.WithActivityOptions
cadence.WithCancel -> workflow.WithCancel
cadence.WithChildPolicy -> workflow.WithChildPolicy
cadence.WithChildWorkflowOptions -> workflow.WithChildOptions
cadence.WithExecutionStartToCloseTimeout -> workflow.WithExecutionStartToCloseTimeout
cadence.WithHeartbeatTimeout -> workflow.WithHeartbeatTimeout
cadence.WithScheduleToCloseTimeout -> workflow.WithScheduleToCloseTimeout
cadence.WithScheduleToStartTimeout -> workflow.WithScheduleToStartTimeout
cadence.WithStartToCloseTimeout ->workflow.WithStartToCloseTimeout
cadence.WithTaskList -> workflow.WithTaskList
cadence.WithValue -> workflow.WithValue
cadence.WithWaitForCancellation -> workflow.WithWaitForCancellation
cadence.WithWorkflowDomain -> workflow.WithWorkflowDomain
cadence.WithWorkflowID -> workflow.WithWorkflowID
cadence.WithWorkflowTaskList -> workflow.WithWorkflowTaskList
cadence.WithWorkflowTaskStartToCloseTimeout -> workflow.WithWorkflowTaskStartToCloseTimeout
cadence.WorkflowExecution -> workflow.Execution
cadence.WorkflowInfo -> workflow.Info
cadence.WorkflowType -> workflow.Type
# ACTIVITY #
## import ##
"go.uber.org/cadence" -> "go.uber.org/cadence/activity"
## source ##
cadence.ActivityInfo -> activity.Info
cadence.ActivityType -> activity.Type
cadence.ErrActivityResultPending -> activity.ErrResultPending
cadence.GetActivityInfo -> activity.GetInfo
cadence.GetActivityLogger -> activity.GetLogger
cadence.GetActivityMetricsScope -> activity.GetMetricsScope
cadence.RecordActivityHeartbeat -> activity.RecordHeartbeat
cadence.RegisterActivity -> activity.Register
cadence.RegisterActivityOptions -> activity.RegisterOptions
cadence.RegisterActivityWithOptions -> activity.RegisterWithOptions
# CODEC #
## import ##
"go.uber.org/cadence" -> "go.uber.org/cadence/encoded"
## source ##
cadence.EncodedValue -> encoded.Value
cadence.EncodedValues -> encoded.Values
# TEST #
## import ##
"go.uber.org/cadence" -> "go.uber.org/cadence/testsuite"
## source ##
cadence.MockCallWrapper -> testsuite.MockCallWrapper
cadence.ServiceInvoker -> testsuite.ServiceInvoker
cadence.TestActivityEnvironment -> testsuite.TestActivityEnvironment
cadence.TestWorkflowEnvironment -> testsuite.TestWorkflowEnvironment
cadence.WithActivityTask -> testsuite.WithActivityTask
cadence.WorkflowTestSuite -> testsuite.WorkflowTestSuite
Change the signature of GetWorkflowHistory from returning whole history to history event iterator #328
workflowID := "workflow-ID"
workflowRunID := // if this is empty string, will use the current run ID of workflow above
// whether use long poll for tracking new events: when the workflow is running, there can be new events generated during iteration
// of HistoryEventIterator, if isLongPoll == true, then iterator will do long poll, tracking new history event, i.e. the iteration
// will not be finished until workflow is finished; if isLongPoll == false, then iterator will only return current history events.
isLongPoll := true
// whether return all history events or just last event
filterType := shared.HistoryEventFilterTypeAllEvent // can also be shared.HistoryEventFilterTypeCloseEvent
iter := client.GetWorkflowHistory(context.Background(), workflowID, workflowRunID, isLongPoll, filterType)
for iter.HasNext() {
event, err := iter.Next()
if err != nil {
return err
}
events = append(events, event)
}
Expose WorkflowIDReusePolicy #328 #338
The new WorkflowIDReusePolicy allow customer to specify the behavior of Cadence service when a workflow is started with the same workflow ID:
-
shared.WorkflowIDReusePolicyAllowDuplicateFailedOnly allow start a workflow execution when workflow not running, and the last execution close state is in [terminated, cancelled, timeout, failed].
-
shared.WorkflowIDReusePolicyAllowDuplicate allow start a workflow execution using the same workflow ID, when workflow not running.
-
shared.WorkflowIDReusePolicyRejectDuplicate do not allow start a workflow execution using the same workflow ID at all.
Note: There is a behavior change in the start workflow / start child workflow workflow ID reuse policy, previously, the default behavior is WorkflowIDReusePolicyAllowDuplicate, while after this change, the default behavior is WorkflowIDReusePolicyAllowDuplicateFailedOnly
Example for starting a workflow:
workflowIDReusePolicy := shared.WorkflowIDReusePolicyAllowDuplicateFailedOnly
startWorkflowOption := shared.StartWorkflowOptions{
...
WorkflowIDReusePolicy: workflowIDReusePolicy,
}
Example for starting a child workflow:
workflowIDReusePolicy := shared.WorkflowIDReusePolicyAllowDuplicateFailedOnly
childWorkflowOption := shared.ChildWorkflowOptions{
...
WorkflowIDReusePolicy: workflowIDReusePolicy,
}
New features
Implement client side sticky query #308
New client helper function ExecuteWorkflow: #328
This API starts a workflow and wait until the workflow finishes, return the result, similar to ExecuteChildWorkflow.
workflowID := "workflow-ID"
tasklist := "tasklist"
timeout := 20 * time.Second
workflowIDReusePolicy := shared.WorkflowIDReusePolicyAllowDuplicateFailedOnly
workflowRun, err := client.ExecuteWorkflow(
context.Background(),
shared.StartWorkflowOptions{
ID: workflowID,
TaskList: tasklist,
ExecutionStartToCloseTimeout: timeout,
DecisionTaskStartToCloseTimeout: timeout,
WorkflowIDReusePolicy: workflowIDReusePolicy,
}, workflowType,
)
var decodedResult ResultType
runID := workflowRun.GetRunID() // this is non blocking
err := workflowRun.Get(context.Background(), &decodedResult) // this is blocking, until workflow is finished
Add client side wrapper API DescribeTaskList #346
DescribeTaskList shows the properties of a given task list, right now this API returns the pollers which poll from this task list in the last few minutes.
resp, err := client.DescribeTaskList(context.Background(), taskListName, shared.TaskListTypeActivity)
if err != nil {
return err
}
for _, poller := range resp.Pollers {
fmt.Println(poller.GetIdentity())
fmt.Println(time.Unix(0, poller.GetLastAccessTime()))
}
Bug fixes
- Fix unit test race condition #306 #307
- Handle ErrActivityResultPending in TestActivityEnvironment #299
- Fix stack overflow #312
- EncodedValue should not be exposed to public #315
- CancellationAlreadyRequestedError should not retry #314
- Yarpc options should not be dropped #313
- Fix timer bug #319
- Should not expose EncodedValue / EncodedValues #324
- Initial retry interval should not be too low #325
- Catch worker panic
- Timer duration change and loose deterministic check #342
- Registered activity with alias in test suite #344
Miscellaneous
- Sync IDL #311 #328 #346
- Converted encoded.Value and encoded.Values to interface #309
- Separate library version from feature version #316
- Fail decision task when decider panic #317
- Update README.md typo #320
- Emit tasklist queue latency #321
- Set up activity throttle limit as input and propagate to server #331
- Make thrift to succeed when vendor dir does not exist #330