go.uber.org/cadence@v1.2.9/internal/interceptors.go (about) 1 // Modifications Copyright (c) 2020 Uber Technologies Inc. 2 // 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 internal 23 24 import ( 25 "time" 26 27 "github.com/uber-go/tally" 28 "go.uber.org/zap" 29 ) 30 31 // WorkflowInterceptorFactory is used to create a single link in the interceptor chain 32 type WorkflowInterceptorFactory interface { 33 // NewInterceptor creates an interceptor instance. The created instance must delegate every call to 34 // the next parameter for workflow code function correctly. 35 NewInterceptor(info *WorkflowInfo, next WorkflowInterceptor) WorkflowInterceptor 36 } 37 38 // WorkflowInterceptor is an interface that can be implemented to intercept calls to the workflow function 39 // as well calls done by the workflow code. 40 // Use worker.WorkflowInterceptorBase as a base struct for implementations that do not want to implement every method. 41 // Interceptor implementation must forward calls to the next in the interceptor chain. 42 // All code in the interceptor is executed in the context of a workflow. So all the rules and restrictions 43 // that apply to the workflow code should be obeyed by the interceptor implementation. 44 // Use workflow.IsReplaying(ctx) to filter out duplicated calls. 45 type WorkflowInterceptor interface { 46 // Intercepts workflow function invocation. As calls to other intercepted functions are done from a workflow 47 // function this function is the first to be called and completes workflow as soon as it returns. 48 // workflowType argument is for information purposes only and should not be mutated. 49 ExecuteWorkflow(ctx Context, workflowType string, args ...interface{}) []interface{} 50 51 ExecuteActivity(ctx Context, activityType string, args ...interface{}) Future 52 ExecuteLocalActivity(ctx Context, activityType string, args ...interface{}) Future 53 ExecuteChildWorkflow(ctx Context, childWorkflowType string, args ...interface{}) ChildWorkflowFuture 54 GetWorkflowInfo(ctx Context) *WorkflowInfo 55 GetLogger(ctx Context) *zap.Logger 56 GetMetricsScope(ctx Context) tally.Scope 57 Now(ctx Context) time.Time 58 NewTimer(ctx Context, d time.Duration) Future 59 Sleep(ctx Context, d time.Duration) (err error) 60 RequestCancelExternalWorkflow(ctx Context, workflowID, runID string) Future 61 SignalExternalWorkflow(ctx Context, workflowID, runID, signalName string, arg interface{}) Future 62 UpsertSearchAttributes(ctx Context, attributes map[string]interface{}) error 63 GetSignalChannel(ctx Context, signalName string) Channel 64 SideEffect(ctx Context, f func(ctx Context) interface{}) Value 65 MutableSideEffect(ctx Context, id string, f func(ctx Context) interface{}, equals func(a, b interface{}) bool) Value 66 GetVersion(ctx Context, changeID string, minSupported, maxSupported Version) Version 67 SetQueryHandler(ctx Context, queryType string, handler interface{}) error 68 IsReplaying(ctx Context) bool 69 HasLastCompletionResult(ctx Context) bool 70 GetLastCompletionResult(ctx Context, d ...interface{}) error 71 } 72 73 var _ WorkflowInterceptor = (*WorkflowInterceptorBase)(nil) 74 75 // WorkflowInterceptorBase is a helper type that can simplify creation of WorkflowInterceptorChainFactories 76 type WorkflowInterceptorBase struct { 77 Next WorkflowInterceptor 78 } 79 80 // ExecuteWorkflow forwards to t.Next 81 func (t *WorkflowInterceptorBase) ExecuteWorkflow(ctx Context, workflowType string, args ...interface{}) []interface{} { 82 return t.Next.ExecuteWorkflow(ctx, workflowType, args...) 83 } 84 85 // ExecuteActivity forwards to t.Next 86 func (t *WorkflowInterceptorBase) ExecuteActivity(ctx Context, activityType string, args ...interface{}) Future { 87 return t.Next.ExecuteActivity(ctx, activityType, args...) 88 } 89 90 // ExecuteLocalActivity forwards to t.Next 91 func (t *WorkflowInterceptorBase) ExecuteLocalActivity(ctx Context, activityType string, args ...interface{}) Future { 92 return t.Next.ExecuteLocalActivity(ctx, activityType, args...) 93 } 94 95 // ExecuteChildWorkflow forwards to t.Next 96 func (t *WorkflowInterceptorBase) ExecuteChildWorkflow(ctx Context, childWorkflowType string, args ...interface{}) ChildWorkflowFuture { 97 return t.Next.ExecuteChildWorkflow(ctx, childWorkflowType, args...) 98 } 99 100 // GetWorkflowInfo forwards to t.Next 101 func (t *WorkflowInterceptorBase) GetWorkflowInfo(ctx Context) *WorkflowInfo { 102 return t.Next.GetWorkflowInfo(ctx) 103 } 104 105 // GetLogger forwards to t.Next 106 func (t *WorkflowInterceptorBase) GetLogger(ctx Context) *zap.Logger { 107 return t.Next.GetLogger(ctx) 108 } 109 110 // GetMetricsScope forwards to t.Next 111 func (t *WorkflowInterceptorBase) GetMetricsScope(ctx Context) tally.Scope { 112 return t.Next.GetMetricsScope(ctx) 113 } 114 115 // Now forwards to t.Next 116 func (t *WorkflowInterceptorBase) Now(ctx Context) time.Time { 117 return t.Next.Now(ctx) 118 } 119 120 // NewTimer forwards to t.Next 121 func (t *WorkflowInterceptorBase) NewTimer(ctx Context, d time.Duration) Future { 122 return t.Next.NewTimer(ctx, d) 123 } 124 125 // Sleep forwards to t.Next 126 func (t *WorkflowInterceptorBase) Sleep(ctx Context, d time.Duration) (err error) { 127 return t.Next.Sleep(ctx, d) 128 } 129 130 // RequestCancelExternalWorkflow forwards to t.Next 131 func (t *WorkflowInterceptorBase) RequestCancelExternalWorkflow(ctx Context, workflowID, runID string) Future { 132 return t.Next.RequestCancelExternalWorkflow(ctx, workflowID, runID) 133 } 134 135 // SignalExternalWorkflow forwards to t.Next 136 func (t *WorkflowInterceptorBase) SignalExternalWorkflow(ctx Context, workflowID, runID, signalName string, arg interface{}) Future { 137 return t.Next.SignalExternalWorkflow(ctx, workflowID, runID, signalName, arg) 138 } 139 140 // UpsertSearchAttributes forwards to t.Next 141 func (t *WorkflowInterceptorBase) UpsertSearchAttributes(ctx Context, attributes map[string]interface{}) error { 142 return t.Next.UpsertSearchAttributes(ctx, attributes) 143 } 144 145 // GetSignalChannel forwards to t.Next 146 func (t *WorkflowInterceptorBase) GetSignalChannel(ctx Context, signalName string) Channel { 147 return t.Next.GetSignalChannel(ctx, signalName) 148 } 149 150 // SideEffect forwards to t.Next 151 func (t *WorkflowInterceptorBase) SideEffect(ctx Context, f func(ctx Context) interface{}) Value { 152 return t.Next.SideEffect(ctx, f) 153 } 154 155 // MutableSideEffect forwards to t.Next 156 func (t *WorkflowInterceptorBase) MutableSideEffect(ctx Context, id string, f func(ctx Context) interface{}, equals func(a, b interface{}) bool) Value { 157 return t.Next.MutableSideEffect(ctx, id, f, equals) 158 } 159 160 // GetVersion forwards to t.Next 161 func (t *WorkflowInterceptorBase) GetVersion(ctx Context, changeID string, minSupported, maxSupported Version) Version { 162 return t.Next.GetVersion(ctx, changeID, minSupported, maxSupported) 163 } 164 165 // SetQueryHandler forwards to t.Next 166 func (t *WorkflowInterceptorBase) SetQueryHandler(ctx Context, queryType string, handler interface{}) error { 167 return t.Next.SetQueryHandler(ctx, queryType, handler) 168 } 169 170 // IsReplaying forwards to t.Next 171 func (t *WorkflowInterceptorBase) IsReplaying(ctx Context) bool { 172 return t.Next.IsReplaying(ctx) 173 } 174 175 // HasLastCompletionResult forwards to t.Next 176 func (t *WorkflowInterceptorBase) HasLastCompletionResult(ctx Context) bool { 177 return t.Next.HasLastCompletionResult(ctx) 178 } 179 180 // GetLastCompletionResult forwards to t.Next 181 func (t *WorkflowInterceptorBase) GetLastCompletionResult(ctx Context, d ...interface{}) error { 182 return t.Next.GetLastCompletionResult(ctx, d...) 183 }