Skip to content

Commit 5759b31

Browse files
committed
Deleting the deprecated proto codepaths
1 parent dd77619 commit 5759b31

8 files changed

Lines changed: 294 additions & 180 deletions

common/nexus/dispatch_outcome.go

Lines changed: 112 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import (
1111

1212
// DispatchOutcome names the arm of matching's DispatchNexusTaskResponse that came back from a
1313
// DispatchNexusTask call. The nested oneofs and the deprecated variants collapse into one flat set of
14-
// cases.
14+
// cases. (Including those from a worker sending the deprecated failure responses, those will get
15+
// silently converted into the newer forms.)
1516
//
1617
// The zero value is the empty string and is not a valid outcome, so a switch over a DispatchOutcome
1718
// needs a default clause. For metric tags use DispatchResult.OutcomeTag, not the string value.
@@ -32,26 +33,30 @@ const (
3233
// DispatchOutcomeCancelAccepted means the worker accepted the cancellation request.
3334
DispatchOutcomeCancelAccepted DispatchOutcome = "cancel-accepted"
3435

35-
// DispatchOutcomeOperationFailure means the worker ran the operation and it failed or was
36-
// canceled. The task was handled; this is the handler's answer, not a delivery problem.
36+
// DispatchOutcomeOperationFailure means the worker successfully ran the operation to completion. But
37+
// operation resulted in a failure or was canceled. This is not a delivery problem.
38+
//
39+
// e.g. the Nexus handler fails with:
40+
// nexus.NewOperationFailedError("insufficient funds")
41+
// nexus.NewOperationCanceledError("already canceled upstream")
3742
DispatchOutcomeOperationFailure DispatchOutcome = "operation-failure"
3843

39-
// DispatchOutcomeOperationFailureDeprecated is DispatchOutcomeOperationFailure as reported by a
40-
// worker predating Temporal failure responses.
41-
DispatchOutcomeOperationFailureDeprecated DispatchOutcome = "operation-failure-deprecated"
42-
4344
// DispatchOutcomeHandlerFailure means the worker refused the task with a Nexus handler error,
4445
// whose retry behavior says whether another attempt is worthwhile.
46+
//
47+
// e.g. the Temporal worker fails before the handler executes, with:
48+
// nexus.NewHandlerErrorf(nexus.HandlerErrorTypeBadRequest, "cannot deserialize input")
49+
// nexus.NewHandlerErrorf(nexus.HandlerErrorTypeBadRequest, "callback URL required for async UpdateWorkflow operation invocations")
4550
DispatchOutcomeHandlerFailure DispatchOutcome = "nexus-handler-failure"
4651

4752
// DispatchOutcomeWorkerFailure means the worker failed the task with a failure that is not a
4853
// Nexus handler error, e.g. an application error sent via RespondNexusTaskFailed.
54+
//
55+
// e.g. the Temporal worker fails before the handler executes, but with a non-HandlerError like:
56+
// TimeoutFailureInfo
57+
// CanceledFailureInfo
4958
DispatchOutcomeWorkerFailure DispatchOutcome = "worker-failure"
5059

51-
// DispatchOutcomeHandlerFailureDeprecated is DispatchOutcomeHandlerFailure as reported by a worker
52-
// predating Temporal failure responses.
53-
DispatchOutcomeHandlerFailureDeprecated DispatchOutcome = "nexus-handler-failure-deprecated"
54-
5560
// DispatchOutcomeRequestTimeout means matching gave up before the task was answered: no worker
5661
// was polling the task queue, or a worker took the task and never responded.
5762
DispatchOutcomeRequestTimeout DispatchOutcome = "request-timeout"
@@ -94,44 +99,17 @@ type DispatchResult struct {
9499
// in place mutate the response too.
95100
Failure *failurepb.Failure
96101

97-
// HandlerError is set only for DispatchOutcomeHandlerFailureDeprecated.
98-
HandlerError *nexuspb.HandlerError
99-
100-
// OperationError is set only for DispatchOutcomeOperationFailureDeprecated.
101-
OperationError *nexuspb.UnsuccessfulOperationError
102-
}
103-
104-
// handlerErrorType returns the Nexus handler error type the worker reported, or "" when the outcome is
105-
// not a handler error.
106-
func (r DispatchResult) handlerErrorType() string {
107-
switch r.Outcome {
108-
case DispatchOutcomeHandlerFailure:
109-
return r.Failure.GetNexusHandlerFailureInfo().GetType()
110-
case DispatchOutcomeHandlerFailureDeprecated:
111-
//nolint:staticcheck // Deprecated field on a deprecated variant.
112-
return r.HandlerError.GetErrorType()
113-
default:
114-
return ""
115-
}
102+
// usedDeprecatedFormat records that the worker answered in a format predating Temporal failure
103+
// responses. Outcome and Failure are normalized to failurepb.Failure. This is only needed
104+
// for reporting metrics. (Which are different based on the kind of error format received.)
105+
usedDeprecatedFormat bool
116106
}
117107

118-
// ClassifyStartOperationDispatch classifies matching's response to a dispatched StartOperation task.
119-
func ClassifyStartOperationDispatch(resp *matchingservice.DispatchNexusTaskResponse) DispatchResult {
120-
return classifyDispatchNexusTaskResponse(resp, classifyStartOperationResponse)
121-
}
122-
123-
// ClassifyCancelOperationDispatch classifies matching's response to a dispatched CancelOperation task.
124-
func ClassifyCancelOperationDispatch(resp *matchingservice.DispatchNexusTaskResponse) DispatchResult {
125-
return classifyDispatchNexusTaskResponse(
126-
resp,
127-
func(*nexuspb.StartOperationResponse) DispatchResult {
128-
// A cancel response carries no fields, so any response means the worker accepted.
129-
return DispatchResult{Outcome: DispatchOutcomeCancelAccepted}
130-
})
131-
}
132-
133-
// classifyDispatchNexusTaskResponse converts a DispatchNexusTaskResponse into a DispatchResult object.
134-
func classifyDispatchNexusTaskResponse(
108+
// baseClassifyDispatchNexusTaskResponse converts a DispatchNexusTaskResponse into a DispatchResult object.
109+
//
110+
// The supplied lambda is invoked to classify a successful Response outcome. (Since the DispatchNexusTaskResponse
111+
// proto is used for different kinds of request types, only the caller will know what success means.)
112+
func baseClassifyDispatchNexusTaskResponse(
135113
resp *matchingservice.DispatchNexusTaskResponse,
136114
onResponseFn func(*nexuspb.StartOperationResponse) DispatchResult,
137115
) DispatchResult {
@@ -147,9 +125,10 @@ func classifyDispatchNexusTaskResponse(
147125

148126
case *matchingservice.DispatchNexusTaskResponse_HandlerError: //nolint:staticcheck // Deprecated, still sent by older workers.
149127
return DispatchResult{
150-
Outcome: DispatchOutcomeHandlerFailureDeprecated,
128+
Outcome: DispatchOutcomeHandlerFailure,
151129
//nolint:staticcheck // Deprecated field on a deprecated variant.
152-
HandlerError: t.HandlerError,
130+
Failure: deprecatedHandlerErrorToFailure(t.HandlerError),
131+
usedDeprecatedFormat: true,
153132
}
154133

155134
case *matchingservice.DispatchNexusTaskResponse_RequestTimeout:
@@ -165,7 +144,7 @@ func classifyDispatchNexusTaskResponse(
165144
}
166145
}
167146

168-
// classifyStartOperationResponse classifies the answer a worker gave to a StartOperation request.
147+
// classifyStartOperationResponse classifies the response a worker gave to a StartOperation request.
169148
func classifyStartOperationResponse(resp *nexuspb.StartOperationResponse) DispatchResult {
170149
switch t := resp.GetVariant().(type) {
171150
case *nexuspb.StartOperationResponse_SyncSuccess:
@@ -196,16 +175,91 @@ func classifyStartOperationResponse(resp *nexuspb.StartOperationResponse) Dispat
196175

197176
case *nexuspb.StartOperationResponse_OperationError: //nolint:staticcheck // Deprecated, still sent by older workers.
198177
return DispatchResult{
199-
Outcome: DispatchOutcomeOperationFailureDeprecated,
178+
Outcome: DispatchOutcomeOperationFailure,
200179
//nolint:staticcheck // Deprecated field on a deprecated variant.
201-
OperationError: t.OperationError,
180+
Failure: deprecatedOperationErrorToFailure(t.OperationError),
181+
usedDeprecatedFormat: true,
202182
}
203183

204184
default:
205185
return DispatchResult{Outcome: DispatchOutcomeUnrecognized}
206186
}
207187
}
208188

189+
// ClassifyStartOperationDispatch classifies matching's response to a dispatched StartOperation task.
190+
func ClassifyStartOperationDispatch(resp *matchingservice.DispatchNexusTaskResponse) DispatchResult {
191+
return baseClassifyDispatchNexusTaskResponse(resp, classifyStartOperationResponse)
192+
}
193+
194+
// ClassifyCancelOperationDispatch classifies matching's response to a dispatched CancelOperation task.
195+
func ClassifyCancelOperationDispatch(resp *matchingservice.DispatchNexusTaskResponse) DispatchResult {
196+
return baseClassifyDispatchNexusTaskResponse(
197+
resp,
198+
func(*nexuspb.StartOperationResponse) DispatchResult {
199+
// A cancel response carries no fields, so any response means the worker accepted.
200+
return DispatchResult{Outcome: DispatchOutcomeCancelAccepted}
201+
})
202+
}
203+
204+
// deprecatedHandlerErrorToFailure converts the deprecated nexuspb.HandlerError into the new format,
205+
// a Temporal failurepb.Failure.
206+
func deprecatedHandlerErrorToFailure(handlerErr *nexuspb.HandlerError) *failurepb.Failure {
207+
failure := &failurepb.Failure{
208+
FailureInfo: &failurepb.Failure_NexusHandlerFailureInfo{
209+
NexusHandlerFailureInfo: &failurepb.NexusHandlerFailureInfo{
210+
Type: handlerErr.GetErrorType(),
211+
RetryBehavior: handlerErr.GetRetryBehavior(),
212+
},
213+
},
214+
}
215+
if handlerErr.GetFailure() != nil {
216+
failure.Cause = convertNexusFailureToTemporalFailure(handlerErr.GetFailure())
217+
}
218+
return failure
219+
}
220+
221+
// deprecatedOperationErrorToFailure converts the deprecated nexuspb.UnsccessfulOperationError into the
222+
// new format, a Temporal failurepb.Failure proto.
223+
func deprecatedOperationErrorToFailure(opErr *nexuspb.UnsuccessfulOperationError) *failurepb.Failure {
224+
failure := convertNexusFailureToTemporalFailure(opErr.GetFailure())
225+
226+
// If the OperationError was because it was cancelled, encode that into the Failure proto.
227+
opState := nexus.OperationState(opErr.GetOperationState())
228+
isCanceledErr := opState == nexus.OperationStateCanceled
229+
if !isCanceledErr && failure.GetCanceledFailureInfo() == nil {
230+
return failure
231+
}
232+
233+
return &failurepb.Failure{
234+
Message: failure.GetMessage(),
235+
Cause: failure,
236+
FailureInfo: &failurepb.Failure_CanceledFailureInfo{
237+
CanceledFailureInfo: &failurepb.CanceledFailureInfo{},
238+
},
239+
}
240+
}
241+
242+
// convertNexusFailureToTemporalFailure converts the deprecated nexuspb.Failure into the new format,
243+
// a Temporal failurepb.Failure.
244+
func convertNexusFailureToTemporalFailure(nexusFailure *nexuspb.Failure) *failurepb.Failure {
245+
//nolint:staticcheck // Deprecated function still in use for backward compatibility.
246+
converted, err := NexusFailureToTemporalFailure(ProtoFailureToNexusFailure(nexusFailure))
247+
// A failure that cannot be re-encoded falls back to its message. We know the operation failed,
248+
// we just don't recognize the format of the data in its cause/details.
249+
if err != nil {
250+
return &failurepb.Failure{
251+
Message: nexusFailure.GetMessage(),
252+
FailureInfo: &failurepb.Failure_ApplicationFailureInfo{
253+
ApplicationFailureInfo: &failurepb.ApplicationFailureInfo{
254+
Type: "NexusFailure",
255+
NonRetryable: false,
256+
},
257+
},
258+
}
259+
}
260+
return converted
261+
}
262+
209263
// OutcomeTag returns the metrics outcome tag for a dispatch.
210264
//
211265
// The handler-error suffix is bounded by boundHandlerErrorType(). A worker failure that is not a handler
@@ -225,14 +279,15 @@ func (r DispatchResult) metricOutcome() string {
225279
case DispatchOutcomeCancelAccepted:
226280
return "success"
227281
case DispatchOutcomeOperationFailure:
282+
if r.usedDeprecatedFormat {
283+
return "operation_error"
284+
}
228285
return "failure"
229-
case DispatchOutcomeOperationFailureDeprecated:
230-
return "operation_error"
231286
case DispatchOutcomeHandlerFailure,
232-
DispatchOutcomeWorkerFailure,
233-
DispatchOutcomeHandlerFailureDeprecated:
287+
DispatchOutcomeWorkerFailure:
234288
// A worker failure has no handler error type to report and will map to UNKNOWN.
235-
return "handler_error:" + boundHandlerErrorType(r.handlerErrorType())
289+
hErrType := r.Failure.GetNexusHandlerFailureInfo().GetType()
290+
return "handler_error:" + boundHandlerErrorType(hErrType)
236291
case DispatchOutcomeRequestTimeout:
237292
return "handler_timeout"
238293
default:

0 commit comments

Comments
 (0)