mirror of
https://github.com/hanzoai/tasks.git
synced 2026-10-04 02:04:03 +00:00
Goes from 135 MB binary with 1153 files importing go.temporal.io and 224
importing google.golang.org/grpc to a 10 MB native binary with ZERO of
either.
Deleted:
- tasks/, tasktests/, service/, chasm/, client/, api/, proto/, tools/
- cmd/tools/, components/, docker/
- schema/{cassandra,elasticsearch,mysql,postgresql,sqlite}/
- 40 tainted common/ subdirs + 7 top-level common files
- tests/testutils (no longer referenced after surviving deps drop common)
New cmd/tasksd (~100 lines) boots tasks.Embed (zap.Node) + http.Server.
New pkg/tasks/embed.go registers ZAP handlers for the SDK opcode surface
(0x0060-0x00A5). Workflow handlers return a 501 "not yet implemented"
envelope; native engine lands behind this contract.
Build: go build ./cmd/tasksd → 10 MB
Vet: go vet ./... → clean
Boot: tasksd --zap-port 9999 --http :7243
Probes: /healthz, /v1/tasks/health → 200
UI: /_/tasks/, / → 200 (embedded Vite bundle)
ZAP: _tasks._tcp on :9999 (mDNS disabled; direct connect)
go.mod: tidy. No go.temporal.io. No google.golang.org/grpc.
326 lines
9.5 KiB
Go
326 lines
9.5 KiB
Go
package nexus
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/nexus-rpc/sdk-go/nexus"
|
|
"github.com/stretchr/testify/require"
|
|
commonpb "go.temporal.io/api/common/v1"
|
|
enumspb "go.temporal.io/api/enums/v1"
|
|
failurepb "go.temporal.io/api/failure/v1"
|
|
"go.temporal.io/sdk/temporal"
|
|
"go.temporal.io/server/common/nexus/nexusrpc"
|
|
"go.temporal.io/server/common/testing/protorequire"
|
|
)
|
|
|
|
func TestRoundTrip_ApplicationFailure(t *testing.T) {
|
|
original := &failurepb.Failure{
|
|
Message: "application error",
|
|
StackTrace: "stack trace here",
|
|
EncodedAttributes: mustToPayload(t, "encoded"),
|
|
FailureInfo: &failurepb.Failure_ApplicationFailureInfo{
|
|
ApplicationFailureInfo: &failurepb.ApplicationFailureInfo{
|
|
Type: "CustomError",
|
|
NonRetryable: false,
|
|
Details: &commonpb.Payloads{
|
|
Payloads: []*commonpb.Payload{mustToPayload(t, "encoded")},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
nexusFailure, err := TemporalFailureToNexusFailure(original)
|
|
require.NoError(t, err)
|
|
|
|
converted, err := NexusFailureToTemporalFailure(nexusFailure)
|
|
require.NoError(t, err)
|
|
|
|
protorequire.ProtoEqual(t, original, converted)
|
|
}
|
|
|
|
func TestRoundTrip_NexusHandlerFailure_Retryable(t *testing.T) {
|
|
original := &failurepb.Failure{
|
|
Message: "handler error - retryable",
|
|
StackTrace: "handler stack trace",
|
|
FailureInfo: &failurepb.Failure_NexusHandlerFailureInfo{
|
|
NexusHandlerFailureInfo: &failurepb.NexusHandlerFailureInfo{
|
|
Type: "CustomHandlerError",
|
|
RetryBehavior: enumspb.NEXUS_HANDLER_ERROR_RETRY_BEHAVIOR_RETRYABLE,
|
|
},
|
|
},
|
|
}
|
|
|
|
nexusFailure, err := TemporalFailureToNexusFailure(original)
|
|
require.NoError(t, err)
|
|
|
|
converted, err := NexusFailureToTemporalFailure(nexusFailure)
|
|
require.NoError(t, err)
|
|
|
|
protorequire.ProtoEqual(t, original, converted)
|
|
}
|
|
|
|
func TestRoundTrip_NexusHandlerFailure_NonRetryable(t *testing.T) {
|
|
original := &failurepb.Failure{
|
|
Message: "handler error - non-retryable",
|
|
StackTrace: "handler stack trace",
|
|
FailureInfo: &failurepb.Failure_NexusHandlerFailureInfo{
|
|
NexusHandlerFailureInfo: &failurepb.NexusHandlerFailureInfo{
|
|
Type: "FatalHandlerError",
|
|
RetryBehavior: enumspb.NEXUS_HANDLER_ERROR_RETRY_BEHAVIOR_NON_RETRYABLE,
|
|
},
|
|
},
|
|
}
|
|
|
|
nexusFailure, err := TemporalFailureToNexusFailure(original)
|
|
require.NoError(t, err)
|
|
|
|
converted, err := NexusFailureToTemporalFailure(nexusFailure)
|
|
require.NoError(t, err)
|
|
|
|
protorequire.ProtoEqual(t, original, converted)
|
|
}
|
|
|
|
func TestRoundTrip_NexusHandlerFailure_Unspecified(t *testing.T) {
|
|
original := &failurepb.Failure{
|
|
Message: "handler error - unspecified retry",
|
|
StackTrace: "handler stack trace",
|
|
FailureInfo: &failurepb.Failure_NexusHandlerFailureInfo{
|
|
NexusHandlerFailureInfo: &failurepb.NexusHandlerFailureInfo{
|
|
Type: "UnspecifiedHandlerError",
|
|
RetryBehavior: enumspb.NEXUS_HANDLER_ERROR_RETRY_BEHAVIOR_UNSPECIFIED,
|
|
},
|
|
},
|
|
}
|
|
|
|
nexusFailure, err := TemporalFailureToNexusFailure(original)
|
|
require.NoError(t, err)
|
|
|
|
converted, err := NexusFailureToTemporalFailure(nexusFailure)
|
|
require.NoError(t, err)
|
|
|
|
protorequire.ProtoEqual(t, original, converted)
|
|
}
|
|
|
|
func TestRoundTrip_NexusHandlerFailure_WithAttributes(t *testing.T) {
|
|
original := &failurepb.Failure{
|
|
Message: "handler error with attributes",
|
|
StackTrace: "handler stack trace",
|
|
FailureInfo: &failurepb.Failure_NexusHandlerFailureInfo{
|
|
NexusHandlerFailureInfo: &failurepb.NexusHandlerFailureInfo{
|
|
Type: "ComplexHandlerError",
|
|
RetryBehavior: enumspb.NEXUS_HANDLER_ERROR_RETRY_BEHAVIOR_RETRYABLE,
|
|
},
|
|
},
|
|
EncodedAttributes: mustToPayload(t, "encoded attributes"),
|
|
}
|
|
|
|
nexusFailure, err := TemporalFailureToNexusFailure(original)
|
|
require.NoError(t, err)
|
|
|
|
converted, err := NexusFailureToTemporalFailure(nexusFailure)
|
|
require.NoError(t, err)
|
|
|
|
protorequire.ProtoEqual(t, original, converted)
|
|
}
|
|
|
|
func TestRoundTrip_WithNestedCauses(t *testing.T) {
|
|
original := &failurepb.Failure{
|
|
Message: "top level failure",
|
|
StackTrace: "top stack trace",
|
|
FailureInfo: &failurepb.Failure_ApplicationFailureInfo{
|
|
ApplicationFailureInfo: &failurepb.ApplicationFailureInfo{
|
|
Type: "TopLevelError",
|
|
},
|
|
},
|
|
Cause: &failurepb.Failure{
|
|
Message: "middle failure",
|
|
StackTrace: "middle stack trace",
|
|
FailureInfo: &failurepb.Failure_TimeoutFailureInfo{
|
|
TimeoutFailureInfo: &failurepb.TimeoutFailureInfo{
|
|
TimeoutType: enumspb.TIMEOUT_TYPE_START_TO_CLOSE,
|
|
},
|
|
},
|
|
Cause: &failurepb.Failure{
|
|
Message: "root cause",
|
|
StackTrace: "root stack trace",
|
|
FailureInfo: &failurepb.Failure_ServerFailureInfo{
|
|
ServerFailureInfo: &failurepb.ServerFailureInfo{
|
|
NonRetryable: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
nexusFailure, err := TemporalFailureToNexusFailure(original)
|
|
require.NoError(t, err)
|
|
|
|
converted, err := NexusFailureToTemporalFailure(nexusFailure)
|
|
require.NoError(t, err)
|
|
|
|
protorequire.ProtoEqual(t, original, converted)
|
|
}
|
|
|
|
func TestRoundTrip_EmptyFailure(t *testing.T) {
|
|
original := &failurepb.Failure{
|
|
Message: "simple message",
|
|
}
|
|
|
|
nexusFailure, err := TemporalFailureToNexusFailure(original)
|
|
require.NoError(t, err)
|
|
|
|
converted, err := NexusFailureToTemporalFailure(nexusFailure)
|
|
require.NoError(t, err)
|
|
|
|
protorequire.ProtoEqual(t, original, converted)
|
|
}
|
|
|
|
func TestRoundTrip_OnlyStackTrace(t *testing.T) {
|
|
original := &failurepb.Failure{
|
|
StackTrace: "just a stack trace",
|
|
}
|
|
|
|
nexusFailure, err := TemporalFailureToNexusFailure(original)
|
|
require.NoError(t, err)
|
|
|
|
converted, err := NexusFailureToTemporalFailure(nexusFailure)
|
|
require.NoError(t, err)
|
|
protorequire.ProtoEqual(t, original, converted)
|
|
}
|
|
|
|
func TestFromOperationFailedError(t *testing.T) {
|
|
nexusFailure, err := nexusrpc.DefaultFailureConverter().ErrorToFailure(&nexus.OperationError{
|
|
State: nexus.OperationStateFailed,
|
|
Message: "operation failed",
|
|
StackTrace: "stack trace",
|
|
})
|
|
require.NoError(t, err)
|
|
cause, err := TemporalFailureToNexusFailure(
|
|
temporal.GetDefaultFailureConverter().ErrorToFailure(
|
|
temporal.NewApplicationError("app err", "CustomError", "details"),
|
|
),
|
|
)
|
|
require.NoError(t, err)
|
|
nexusFailure.Cause = &cause
|
|
|
|
converted, err := NexusFailureToTemporalFailure(nexusFailure)
|
|
require.NoError(t, err)
|
|
|
|
expected := &failurepb.Failure{
|
|
Message: "operation failed",
|
|
StackTrace: "stack trace",
|
|
FailureInfo: &failurepb.Failure_ApplicationFailureInfo{
|
|
ApplicationFailureInfo: &failurepb.ApplicationFailureInfo{
|
|
NonRetryable: true,
|
|
Type: "OperationError",
|
|
},
|
|
},
|
|
Cause: &failurepb.Failure{
|
|
Message: "app err",
|
|
Source: "GoSDK",
|
|
FailureInfo: &failurepb.Failure_ApplicationFailureInfo{
|
|
ApplicationFailureInfo: &failurepb.ApplicationFailureInfo{
|
|
Type: "CustomError",
|
|
Details: &commonpb.Payloads{
|
|
Payloads: []*commonpb.Payload{mustToPayload(t, "details")},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
protorequire.ProtoEqual(t, expected, converted)
|
|
}
|
|
|
|
func TestNexusFailureToTemporalFailure_UnknownMetadataType(t *testing.T) {
|
|
nf := nexus.Failure{
|
|
Message: "unknown failure",
|
|
StackTrace: "unknown stack trace",
|
|
Metadata: map[string]string{
|
|
"type": "some.custom.Type",
|
|
},
|
|
Details: []byte(`{"key":"value"}`),
|
|
}
|
|
|
|
converted, err := NexusFailureToTemporalFailure(nf)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, "unknown failure", converted.GetMessage())
|
|
require.Equal(t, "unknown stack trace", converted.GetStackTrace())
|
|
|
|
appInfo := converted.GetApplicationFailureInfo()
|
|
require.NotNil(t, appInfo)
|
|
require.Equal(t, "NexusFailure", appInfo.GetType())
|
|
require.NotNil(t, appInfo.GetDetails())
|
|
require.Len(t, appInfo.GetDetails().GetPayloads(), 1)
|
|
}
|
|
|
|
func TestNexusFailureToTemporalFailure_NoMetadataWithDetails(t *testing.T) {
|
|
nf := nexus.Failure{
|
|
Message: "bare failure",
|
|
Details: []byte(`{"info":"data"}`),
|
|
}
|
|
|
|
converted, err := NexusFailureToTemporalFailure(nf)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, "bare failure", converted.GetMessage())
|
|
|
|
appInfo := converted.GetApplicationFailureInfo()
|
|
require.NotNil(t, appInfo)
|
|
require.Equal(t, "NexusFailure", appInfo.GetType())
|
|
require.NotNil(t, appInfo.GetDetails())
|
|
require.Len(t, appInfo.GetDetails().GetPayloads(), 1)
|
|
}
|
|
|
|
func TestNexusFailureToTemporalFailure_NoMetadataNoDetails(t *testing.T) {
|
|
nf := nexus.Failure{
|
|
Message: "plain failure",
|
|
}
|
|
|
|
converted, err := NexusFailureToTemporalFailure(nf)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, "plain failure", converted.GetMessage())
|
|
require.Nil(t, converted.GetFailureInfo())
|
|
}
|
|
|
|
func TestFromOperationCanceledError(t *testing.T) {
|
|
nexusFailure, err := nexusrpc.DefaultFailureConverter().ErrorToFailure(&nexus.OperationError{
|
|
State: nexus.OperationStateCanceled,
|
|
Message: "operation canceled",
|
|
StackTrace: "stack trace",
|
|
})
|
|
require.NoError(t, err)
|
|
cause, err := TemporalFailureToNexusFailure(
|
|
temporal.GetDefaultFailureConverter().ErrorToFailure(
|
|
temporal.NewApplicationError("app err", "CustomError", "details"),
|
|
),
|
|
)
|
|
require.NoError(t, err)
|
|
nexusFailure.Cause = &cause
|
|
|
|
converted, err := NexusFailureToTemporalFailure(nexusFailure)
|
|
require.NoError(t, err)
|
|
|
|
expected := &failurepb.Failure{
|
|
Message: "operation canceled",
|
|
StackTrace: "stack trace",
|
|
FailureInfo: &failurepb.Failure_CanceledFailureInfo{
|
|
CanceledFailureInfo: &failurepb.CanceledFailureInfo{},
|
|
},
|
|
Cause: &failurepb.Failure{
|
|
Message: "app err",
|
|
Source: "GoSDK",
|
|
FailureInfo: &failurepb.Failure_ApplicationFailureInfo{
|
|
ApplicationFailureInfo: &failurepb.ApplicationFailureInfo{
|
|
Type: "CustomError",
|
|
Details: &commonpb.Payloads{
|
|
Payloads: []*commonpb.Payload{mustToPayload(t, "details")},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
protorequire.ProtoEqual(t, expected, converted)
|
|
}
|