go.uber.org/cadence@v1.2.9/worker/worker.go (about)

     1  // Copyright (c) 2017-2020 Uber Technologies Inc.
     2  // Portions of the Software are attributed to Copyright (c) 2020 Temporal Technologies Inc.
     3  //
     4  // Permission is hereby granted, free of charge, to any person obtaining a copy
     5  // of this software and associated documentation files (the "Software"), to deal
     6  // in the Software without restriction, including without limitation the rights
     7  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     8  // copies of the Software, and to permit persons to whom the Software is
     9  // furnished to do so, subject to the following conditions:
    10  //
    11  // The above copyright notice and this permission notice shall be included in
    12  // all copies or substantial portions of the Software.
    13  //
    14  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    15  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    16  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    17  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    18  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    19  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    20  // THE SOFTWARE.
    21  
    22  // Package worker contains functions to manage lifecycle of a Cadence client side worker.
    23  package worker
    24  
    25  import (
    26  	"context"
    27  	"io"
    28  
    29  	"go.uber.org/zap"
    30  
    31  	"go.uber.org/cadence/.gen/go/cadence/workflowserviceclient"
    32  	"go.uber.org/cadence/.gen/go/shared"
    33  	"go.uber.org/cadence/activity"
    34  	"go.uber.org/cadence/internal"
    35  	"go.uber.org/cadence/internal/common/auth"
    36  	"go.uber.org/cadence/workflow"
    37  )
    38  
    39  type (
    40  	// Worker hosts workflow and activity implementations.
    41  	// Use worker.New(...) to create an instance.
    42  	Worker interface {
    43  		Registry
    44  
    45  		// Start starts the worker in a non-blocking fashion
    46  		Start() error
    47  		// Run is a blocking start and cleans up resources when killed
    48  		// returns error only if it fails to start the worker
    49  		Run() error
    50  		// Stop cleans up any resources opened by worker
    51  		Stop()
    52  	}
    53  
    54  	// Registry exposes registration functions to consumers.
    55  	Registry interface {
    56  		WorkflowRegistry
    57  		ActivityRegistry
    58  	}
    59  
    60  	// WorkflowRegistry exposes workflow registration functions to consumers.
    61  	WorkflowRegistry interface {
    62  		// RegisterWorkflow - registers a workflow function with the worker.
    63  		// A workflow takes a workflow.Context and input and returns a (result, error) or just error.
    64  		// Examples:
    65  		//	func sampleWorkflow(ctx workflow.Context, input []byte) (result []byte, err error)
    66  		//	func sampleWorkflow(ctx workflow.Context, arg1 int, arg2 string) (result []byte, err error)
    67  		//	func sampleWorkflow(ctx workflow.Context) (result []byte, err error)
    68  		//	func sampleWorkflow(ctx workflow.Context, arg1 int) (result string, err error)
    69  		// Serialization of all primitive types, structures is supported ... except channels, functions, variadic, unsafe pointer.
    70  		// For global registration consider workflow.Register
    71  		// This method panics if workflowFunc doesn't comply with the expected format or tries to register the same workflow
    72  		RegisterWorkflow(w interface{})
    73  
    74  		// RegisterWorkflowWithOptions registers the workflow function with options.
    75  		// The user can use options to provide an external name for the workflow or leave it empty if no
    76  		// external name is required. This can be used as
    77  		//  worker.RegisterWorkflowWithOptions(sampleWorkflow, RegisterWorkflowOptions{})
    78  		//  worker.RegisterWorkflowWithOptions(sampleWorkflow, RegisterWorkflowOptions{Name: "foo"})
    79  		// This method panics if workflowFunc doesn't comply with the expected format or tries to register the same workflow
    80  		// type name twice. Use workflow.RegisterOptions.DisableAlreadyRegisteredCheck to allow multiple registrations.
    81  		RegisterWorkflowWithOptions(w interface{}, options workflow.RegisterOptions)
    82  	}
    83  
    84  	// ActivityRegistry exposes activity registration functions to consumers.
    85  	ActivityRegistry interface {
    86  		// RegisterActivity - register an activity function or a pointer to a structure with the worker.
    87  		// An activity function takes a context and input and returns a (result, error) or just error.
    88  		//
    89  		// And activity struct is a structure with all its exported methods treated as activities. The default
    90  		// name of each activity is the method name.
    91  		//
    92  		// Examples:
    93  		//	func sampleActivity(ctx context.Context, input []byte) (result []byte, err error)
    94  		//	func sampleActivity(ctx context.Context, arg1 int, arg2 string) (result *customerStruct, err error)
    95  		//	func sampleActivity(ctx context.Context) (err error)
    96  		//	func sampleActivity() (result string, err error)
    97  		//	func sampleActivity(arg1 bool) (result int, err error)
    98  		//	func sampleActivity(arg1 bool) (err error)
    99  		//
   100  		//  type Activities struct {
   101  		//     // fields
   102  		//  }
   103  		//  func (a *Activities) SampleActivity1(ctx context.Context, arg1 int, arg2 string) (result *customerStruct, err error) {
   104  		//    ...
   105  		//  }
   106  		//
   107  		//  func (a *Activities) SampleActivity2(ctx context.Context, arg1 int, arg2 *customerStruct) (result string, err error) {
   108  		//    ...
   109  		//  }
   110  		//
   111  		// Serialization of all primitive types, structures is supported ... except channels, functions, variadic, unsafe pointer.
   112  		// This method panics if activityFunc doesn't comply with the expected format or an activity with the same
   113  		// type name is registered more than once.
   114  		// For global registration consider activity.Register
   115  		RegisterActivity(a interface{})
   116  
   117  		// RegisterActivityWithOptions registers the activity function or struct pointer with options.
   118  		// The user can use options to provide an external name for the activity or leave it empty if no
   119  		// external name is required. This can be used as
   120  		//  worker.RegisterActivityWithOptions(barActivity, RegisterActivityOptions{})
   121  		//  worker.RegisterActivityWithOptions(barActivity, RegisterActivityOptions{Name: "barExternal"})
   122  		// When registering the structure that implements activities the name is used as a prefix that is
   123  		// prepended to the activity method name.
   124  		//  worker.RegisterActivityWithOptions(&Activities{ ... }, RegisterActivityOptions{Name: "MyActivities_"})
   125  		// To override each name of activities defined through a structure register the methods one by one:
   126  		// activities := &Activities{ ... }
   127  		// worker.RegisterActivityWithOptions(activities.SampleActivity1, RegisterActivityOptions{Name: "Sample1"})
   128  		// worker.RegisterActivityWithOptions(activities.SampleActivity2, RegisterActivityOptions{Name: "Sample2"})
   129  		// See RegisterActivity function for more info.
   130  		// The other use of options is to disable duplicated activity registration check
   131  		// which might be useful for integration tests.
   132  		// worker.RegisterActivityWithOptions(barActivity, RegisterActivityOptions{DisableAlreadyRegisteredCheck: true})
   133  		RegisterActivityWithOptions(a interface{}, options activity.RegisterOptions)
   134  	}
   135  
   136  	// WorkflowReplayer supports replaying a workflow from its event history.
   137  	// Use for troubleshooting and backwards compatibility unit tests.
   138  	// For example if a workflow failed in production then its history can be downloaded through UI or CLI
   139  	// and replayed in a debugger as many times as necessary.
   140  	// Use this class to create unit tests that check if workflow changes are backwards compatible.
   141  	// It is important to maintain backwards compatibility through use of workflow.GetVersion
   142  	// to ensure that new deployments are not going to break open workflows.
   143  	WorkflowReplayer interface {
   144  		WorkflowRegistry
   145  		ActivityRegistry
   146  
   147  		// ReplayWorkflowHistory executes a single decision task for the given json history file.
   148  		// Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
   149  		// The logger is an optional parameter. Defaults to the noop logger.
   150  		ReplayWorkflowHistory(logger *zap.Logger, history *shared.History) error
   151  
   152  		// ReplayWorkflowHistoryFromJSONFile executes a single decision task for the json history file downloaded from the cli.
   153  		// To download the history file: cadence workflow showid <workflow_id> -of <output_filename>
   154  		// See https://github.com/uber/cadence/blob/master/tools/cli/README.md for full documentation
   155  		// Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
   156  		// The logger is an optional parameter. Defaults to the noop logger.
   157  		//
   158  		// Deprecated: prefer ReplayWorkflowHistoryFromJSON
   159  		ReplayWorkflowHistoryFromJSONFile(logger *zap.Logger, jsonfileName string) error
   160  
   161  		// ReplayPartialWorkflowHistoryFromJSONFile executes a single decision task for the json history file upto provided
   162  		// lastEventID(inclusive), downloaded from the cli.
   163  		// To download the history file: cadence workflow showid <workflow_id> -of <output_filename>
   164  		// See https://github.com/uber/cadence/blob/master/tools/cli/README.md for full documentation
   165  		// Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
   166  		// The logger is an optional parameter. Defaults to the noop logger.
   167  		//
   168  		// Deprecated: prefer ReplayPartialWorkflowHistoryFromJSON
   169  		ReplayPartialWorkflowHistoryFromJSONFile(logger *zap.Logger, jsonfileName string, lastEventID int64) error
   170  
   171  		// ReplayWorkflowExecution loads a workflow execution history from the Cadence service and executes a single decision task for it.
   172  		// Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
   173  		// The logger is the only optional parameter. Defaults to the noop logger.
   174  		ReplayWorkflowExecution(ctx context.Context, service workflowserviceclient.Interface, logger *zap.Logger, domain string, execution workflow.Execution) error
   175  
   176  		// ReplayWorkflowHistoryFromJSON executes a single decision task for the json history file downloaded from the cli.
   177  		// To download the history file:
   178  		//  cadence workflow showid <workflow_id> -of <output_filename>
   179  		// See https://github.com/uber/cadence/blob/master/tools/cli/README.md for full documentation
   180  		// Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
   181  		// The logger is an optional parameter. Defaults to the noop logger.
   182  		ReplayWorkflowHistoryFromJSON(logger *zap.Logger, reader io.Reader) error
   183  
   184  		// ReplayPartialWorkflowHistoryFromJSON executes a single decision task for the json history file upto provided
   185  		// lastEventID(inclusive), downloaded from the cli.
   186  		// To download the history file:
   187  		//   cadence workflow showid <workflow_id> -of <output_filename>
   188  		// See https://github.com/uber/cadence/blob/master/tools/cli/README.md for full documentation
   189  		// Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
   190  		// The logger is an optional parameter. Defaults to the noop logger.
   191  		ReplayPartialWorkflowHistoryFromJSON(logger *zap.Logger, reader io.Reader, lastEventID int64) error
   192  	}
   193  
   194  	// WorkflowShadower retrieves and replays workflow history from Cadence service to determine if there's any nondeterministic changes in the workflow definition
   195  	WorkflowShadower interface {
   196  		WorkflowRegistry
   197  
   198  		Run() error
   199  	}
   200  
   201  	// Options is used to configure a worker instance.
   202  	Options = internal.WorkerOptions
   203  
   204  	// ShadowOptions is used to configure a WorkflowShadower.
   205  	ShadowOptions = internal.ShadowOptions
   206  	// ShadowMode is an enum for configuring if shadowing should continue after all workflows matches the WorkflowQuery have been replayed.
   207  	ShadowMode = internal.ShadowMode
   208  	// TimeFilter represents a time range through the min and max timestamp
   209  	TimeFilter = internal.TimeFilter
   210  	// ShadowExitCondition configures when the workflow shadower should exit.
   211  	// If not specified shadower will exit after replaying all workflows satisfying the visibility query.
   212  	ShadowExitCondition = internal.ShadowExitCondition
   213  
   214  	// ReplayOptions is used to configure the replay decision task worker.
   215  	ReplayOptions = internal.ReplayOptions
   216  
   217  	// NonDeterministicWorkflowPolicy is an enum for configuring how client's decision task handler deals with
   218  	// mismatched history events (presumably arising from non-deterministic workflow definitions).
   219  	NonDeterministicWorkflowPolicy = internal.NonDeterministicWorkflowPolicy
   220  
   221  	// AuthorizationProvider is the interface that contains the method to get the auth token
   222  	AuthorizationProvider = auth.AuthorizationProvider
   223  
   224  	// OAuthConfig allows to configure external OAuth token provider.
   225  	OAuthConfig = internal.OAuthAuthorizerConfig
   226  )
   227  
   228  const (
   229  	// NonDeterministicWorkflowPolicyBlockWorkflow is the default policy for handling detected non-determinism.
   230  	// This option simply logs to console with an error message that non-determinism is detected, but
   231  	// does *NOT* reply anything back to the server.
   232  	// It is chosen as default for backward compatibility reasons because it preserves the old behavior
   233  	// for handling non-determinism that we had before NonDeterministicWorkflowPolicy type was added to
   234  	// allow more configurability.
   235  	NonDeterministicWorkflowPolicyBlockWorkflow = internal.NonDeterministicWorkflowPolicyBlockWorkflow
   236  	// NonDeterministicWorkflowPolicyFailWorkflow behaves exactly the same as Ignore, up until the very
   237  	// end of processing a decision task.
   238  	// Whereas default does *NOT* reply anything back to the server, fail workflow replies back with a request
   239  	// to fail the workflow execution.
   240  	NonDeterministicWorkflowPolicyFailWorkflow = internal.NonDeterministicWorkflowPolicyFailWorkflow
   241  )
   242  
   243  const (
   244  	// ShadowModeNormal is the default mode for workflow shadowing.
   245  	// Shadowing will complete after all workflows matches WorkflowQuery have been replayed.
   246  	ShadowModeNormal = internal.ShadowModeNormal
   247  	// ShadowModeContinuous mode will start a new round of shadowing
   248  	// after all workflows matches WorkflowQuery have been replayed.
   249  	// There will be a 5 min wait period between each round,
   250  	// currently this wait period is not configurable.
   251  	// Shadowing will complete only when ExitCondition is met.
   252  	// ExitCondition must be specified when using this mode
   253  	ShadowModeContinuous = internal.ShadowModeContinuous
   254  )
   255  
   256  // New creates an instance of worker for managing workflow and activity executions.
   257  //
   258  //	service  - thrift connection to the cadence server
   259  //	domain   - the name of the cadence domain
   260  //	taskList - is the task list name you use to identify your client worker, also
   261  //	           identifies group of workflow and activity implementations that are
   262  //	           hosted by a single worker process
   263  //	options  - configure any worker specific options like logger, metrics, identity
   264  func New(
   265  	service workflowserviceclient.Interface,
   266  	domain string,
   267  	taskList string,
   268  	options Options,
   269  ) Worker {
   270  	return internal.NewWorker(service, domain, taskList, options)
   271  }
   272  
   273  // NewWorkflowReplayer creates a WorkflowReplayer instance.
   274  func NewWorkflowReplayer() WorkflowReplayer {
   275  	return internal.NewWorkflowReplayer()
   276  }
   277  
   278  // NewWorkflowReplayerWithOptions creates an instance of the WorkflowReplayer
   279  // with provided replay worker options
   280  func NewWorkflowReplayerWithOptions(
   281  	options ReplayOptions,
   282  ) WorkflowReplayer {
   283  	return internal.NewWorkflowReplayerWithOptions(options)
   284  }
   285  
   286  // NewWorkflowShadower creates a WorkflowShadower instance.
   287  func NewWorkflowShadower(
   288  	service workflowserviceclient.Interface,
   289  	domain string,
   290  	shadowOptions ShadowOptions,
   291  	replayOptions ReplayOptions,
   292  	logger *zap.Logger,
   293  ) (WorkflowShadower, error) {
   294  	return internal.NewWorkflowShadower(service, domain, shadowOptions, replayOptions, logger)
   295  }
   296  
   297  // EnableVerboseLogging enable or disable verbose logging of internal Cadence library components.
   298  // Most customers don't need this feature, unless advised by the Cadence team member.
   299  // Also there is no guarantee that this API is not going to change.
   300  func EnableVerboseLogging(enable bool) {
   301  	internal.EnableVerboseLogging(enable)
   302  }
   303  
   304  // ReplayWorkflowHistory executes a single decision task for the given json history file.
   305  // Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
   306  // The logger is an optional parameter. Defaults to the noop logger.
   307  func ReplayWorkflowHistory(logger *zap.Logger, history *shared.History) error {
   308  	return internal.ReplayWorkflowHistory(logger, history)
   309  }
   310  
   311  // ReplayWorkflowHistoryFromJSONFile executes a single decision task for the json history file downloaded from the cli.
   312  // To download the history file: cadence workflow showid <workflow_id> -of <output_filename>
   313  // See https://github.com/uber/cadence/blob/master/tools/cli/README.md for full documentation
   314  // Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
   315  // The logger is an optional parameter. Defaults to the noop logger.
   316  func ReplayWorkflowHistoryFromJSONFile(logger *zap.Logger, jsonfileName string) error {
   317  	return internal.ReplayWorkflowHistoryFromJSONFile(logger, jsonfileName)
   318  }
   319  
   320  // ReplayPartialWorkflowHistoryFromJSONFile executes a single decision task for the json history file upto provided
   321  // // lastEventID(inclusive), downloaded from the cli.
   322  // To download the history file: cadence workflow showid <workflow_id> -of <output_filename>
   323  // See https://github.com/uber/cadence/blob/master/tools/cli/README.md for full documentation
   324  // Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
   325  // The logger is an optional parameter. Defaults to the noop logger.
   326  func ReplayPartialWorkflowHistoryFromJSONFile(logger *zap.Logger, jsonfileName string, lastEventID int64) error {
   327  	return internal.ReplayPartialWorkflowHistoryFromJSONFile(logger, jsonfileName, lastEventID)
   328  }
   329  
   330  // ReplayWorkflowExecution loads a workflow execution history from the Cadence service and executes a single decision task for it.
   331  // Use for testing the backwards compatibility of code changes and troubleshooting workflows in a debugger.
   332  // The logger is the only optional parameter. Defaults to the noop logger.
   333  func ReplayWorkflowExecution(ctx context.Context, service workflowserviceclient.Interface, logger *zap.Logger, domain string, execution workflow.Execution) error {
   334  	return internal.ReplayWorkflowExecution(ctx, service, logger, domain, execution)
   335  }
   336  
   337  // SetStickyWorkflowCacheSize sets the cache size for sticky workflow cache. Sticky workflow execution is the affinity
   338  // between decision tasks of a specific workflow execution to a specific worker. The affinity is set if sticky execution
   339  // is enabled via Worker.Options (It is enabled by default unless disabled explicitly). The benefit of sticky execution
   340  // is that workflow does not have to reconstruct the state by replaying from beginning of history events. But the cost
   341  // is it consumes more memory as it rely on caching workflow execution's running state on the worker. The cache is shared
   342  // between workers running within same process. This must be called before any worker is started. If not called, the
   343  // default size of 10K (might change in future) will be used.
   344  func SetStickyWorkflowCacheSize(cacheSize int) {
   345  	internal.SetStickyWorkflowCacheSize(cacheSize)
   346  }
   347  
   348  // SetBinaryChecksum sets the identifier of the binary(aka BinaryChecksum).
   349  // The identifier is mainly used in recording reset points when respondDecisionTaskCompleted. For each workflow, the very first
   350  // decision completed by a binary will be associated as a auto-reset point for the binary. So that when a customer wants to
   351  // mark the binary as bad, the workflow will be reset to that point -- which means workflow will forget all progress generated
   352  // by the binary.
   353  // On another hand, once the binary is marked as bad, the bad binary cannot poll decision and make any progress any more.
   354  func SetBinaryChecksum(checksum string) {
   355  	internal.SetBinaryChecksum(checksum)
   356  }
   357  
   358  // NewAdminJwtAuthorizationProvider creates a JwtAuthorizationProvider instance.
   359  func NewAdminJwtAuthorizationProvider(privateKey []byte) AuthorizationProvider {
   360  	return internal.NewAdminJwtAuthorizationProvider(privateKey)
   361  }
   362  
   363  // NewOAuthAuthorizationProvider asks for a token from external OAuth provider
   364  func NewOAuthAuthorizationProvider(config OAuthConfig) AuthorizationProvider {
   365  	return internal.NewOAuthAuthorizationProvider(config)
   366  }
   367  
   368  // AugmentWorkerOptions fill all unset worker Options fields with their default values
   369  // Use as getter for default worker options
   370  func AugmentWorkerOptions(options Options) Options {
   371  	return internal.AugmentWorkerOptions(options)
   372  }