nexusoperation

package
v1.32.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 15, 2026 License: MIT Imports: 52 Imported by: 0

Documentation

Index

Constants

View Source
const TaskGroupName = "nexus"

TaskGroupName groups invocation and cancellation together for the outbound queue

Variables

View Source
var (
	Archetype   = chasm.FullyQualifiedName(libraryName, componentName)
	ArchetypeID = chasm.GenerateTypeID(Archetype)
)
View Source
var (
	EndpointSearchAttribute  = chasm.NewSearchAttributeKeyword("Endpoint", chasm.SearchAttributeFieldKeyword01)
	ServiceSearchAttribute   = chasm.NewSearchAttributeKeyword("Service", chasm.SearchAttributeFieldKeyword02)
	OperationSearchAttribute = chasm.NewSearchAttributeKeyword("Operation", chasm.SearchAttributeFieldKeyword03)
	RequestIDSearchAttribute = chasm.NewSearchAttributeKeyword("RequestId", chasm.SearchAttributeFieldKeyword04)
	StatusSearchAttribute    = chasm.NewSearchAttributeKeyword("ExecutionStatus", chasm.SearchAttributeFieldLowCardinalityKeyword01)
)
View Source
var (
	ErrResponseBodyTooLarge  = errors.New("http: response body too large")
	ErrInvalidOperationToken = errors.New("invalid operation token")
)
View Source
var CallbackURLTemplate = dynamicconfig.NewGlobalTypedSettingWithConverter(
	"nexusoperation.callback.endpoint.template",
	func(in any) (*template.Template, error) {
		s, ok := in.(string)
		if !ok {
			return nil, fmt.Errorf("invalid config type: %T for nexusoperation.callback.endpoint.template, expected string", in)
		}
		if s == "unset" {
			return nil, nil
		}
		return template.New("NexusCallbackURL").Parse(s)
	},
	nil,
	`Controls the template for generating callback URLs included in Nexus operation requests, which are used to deliver
asynchronous completion for external endpoint targets. The template can be used to interpolate the {{.NamepaceName}}
and {{.NamespaceID}} parameters to construct a publicly accessible URL.
Must be set to call external endpoints.`,
)
View Source
var ChasmWorkflowOperationsRolloutPercent = dynamicconfig.NewNamespaceIntSetting(
	"nexusoperation.chasmWorkflowOperationsRolloutPercent",
	0,
	`Per-namespace percentage [0,100] of workflows whose new Nexus Operations are created on the CHASM-based
implementation instead of the legacy HSM-based implementation. This setting is only consulted when
enableChasmWorkflowOperations is true and is re-evaluated on every ScheduleNexusOperation command. Membership is
decided by a stable hash of the namespace and workflow ID, so a given workflow consistently lands on the same
implementation across all of its operations and dialing the percentage up is monotonic. Defaults to 0 (conservative
dial-up model): even when enableChasmWorkflowOperations is on, no operations are routed to CHASM until the percentage
is explicitly dialed up.`,
)
View Source
var DisallowedOperationHeaders = dynamicconfig.NewGlobalTypedSettingWithConverter(
	"nexusoperation.disallowedHeaders",
	func(in any) ([]string, error) {
		keys, err := dynamicconfig.ConvertStructure[[]string](nil)(in)
		if err != nil {
			return nil, err
		}
		for i, k := range keys {
			keys[i] = strings.ToLower(k)
		}
		return keys, nil
	},
	[]string{
		"request-timeout",
		interceptor.DCRedirectionAPIHeaderName,
		interceptor.DCRedirectionSourceCellHeaderName,
		interceptor.DCRedirectionContextHeaderName,
		headers.CallerNameHeaderName,
		headers.CallerTypeHeaderName,
		headers.CallOriginHeaderName,
		headers.PrincipalTypeHeaderName,
		headers.PrincipalNameHeaderName,
	},
	`Case insensitive list of disallowed header keys for Nexus Operations. ScheduleNexusOperation commands with a
"nexus_header" field that contains any of these disallowed keys will be rejected.`,
)
View Source
var EnableChasmWorkflowOperations = dynamicconfig.NewNamespaceBoolSetting(
	"nexusoperation.enableChasmWorkflowOperations",
	false,
	`Feature flag that controls whether the legacy HSM-based implementation (when flag is false; default) or the newer
CHASM-based implementation of Nexus will be used when scheduling new Nexus Operations.`,
)
View Source
var Enabled = dynamicconfig.NewNamespaceBoolSetting(
	"nexusoperation.enableStandalone",
	false,
	`Toggles standalone Nexus operation functionality on the server.`,
)
View Source
var ErrCancellationAlreadyRequested = serviceerror.NewFailedPrecondition("cancellation already requested")

ErrCancellationAlreadyRequested is returned when a cancellation has already been requested for an operation.

View Source
var ErrOperationAlreadyCompleted = serviceerror.NewFailedPrecondition("operation already completed")

ErrOperationAlreadyCompleted is returned when trying to cancel an operation that has already completed.

View Source
var ErrStandaloneNexusOperationDisabled = serviceerror.NewUnimplemented("Standalone Nexus operation is disabled")
View Source
var FrontendModule = fx.Module(
	"chasm.lib.nexusoperation.frontend",
	fx.Provide(configProvider),
	fx.Provide(nexusoperationpb.NewNexusOperationServiceLayeredClient),
	fx.Provide(NewFrontendHandler),
	fx.Provide(newComponentOnlyLibrary),
	fx.Invoke(func(l *componentOnlyLibrary, registry *chasm.Registry) error {

		return registry.Register(l)
	}),
)
View Source
var LongPollBuffer = dynamicconfig.NewNamespaceDurationSetting(
	"nexusoperation.longPollBuffer",
	common.DefaultLongPollBuffer,
	`A buffer used to adjust the nexus operation long-poll timeouts.
 Specifically, nexus operation long-poll requests are timed out at a time which leaves at least the buffer's duration
 remaining before the caller's deadline, if permitted by the caller's deadline.`,
)
View Source
var LongPollTimeout = dynamicconfig.NewNamespaceDurationSetting(
	"nexusoperation.longPollTimeout",
	common.DefaultLongPollTimeout,
	`Maximum timeout for nexus operation long-poll requests. Actual wait may be shorter to leave
longPollBuffer before the caller deadline.`,
)
View Source
var MaxConcurrentOperationsPerWorkflow = dynamicconfig.NewNamespaceIntSetting(
	"nexusoperation.limit.operation.concurrencyPerWorkflow.max",
	2000,
	`Limits the maximum allowed concurrent Nexus Operations for a given workflow execution. Once the limit is reached,
ScheduleNexusOperation commands will be rejected.`,
)
View Source
var MaxOperationHeaderSize = dynamicconfig.NewNamespaceIntSetting(
	"nexusoperation.limit.header.size",
	8192,
	`The maximum allowed header size for a Nexus Operation.
ScheduleNexusOperation commands with a "nexus_header" field that exceeds this limit will be rejected.
Uses Go's len() function on header keys and values to determine the total size.`,
)
View Source
var MaxOperationNameLength = dynamicconfig.NewNamespaceIntSetting(
	"nexusoperation.limit.operation.name.length",
	1000,
	`Limits the maximum allowed length for a Nexus Operation name. ScheduleNexusOperation commands with an operation name
that exceeds this limit will be rejected.  Uses Go's len() function to determine the length.`,
)
View Source
var MaxOperationScheduleToCloseTimeout = dynamicconfig.NewNamespaceDurationSetting(
	"nexusoperation.limit.scheduleToCloseTimeout",
	0,
	`Maximum allowed duration of a Nexus Operation. ScheduleOperation commands that specify no schedule-to-close timeout
or a longer timeout than permitted will have their schedule-to-close timeout capped to this value. 0 implies no limit.`,
)
View Source
var MaxOperationTokenLength = dynamicconfig.NewNamespaceIntSetting(
	"nexusoperation.limit.operation.token.length",
	4096,
	`Limits the maximum allowed length for a Nexus Operation token. Tokens returned via start responses or via async
completions that exceed this limit will be rejected. Uses Go's len() function to determine the length.
Leave this limit long enough to fit a workflow ID and namespace name plus padding at minimum since that's what the SDKs
use as the token.`,
)
View Source
var MaxReasonLength = dynamicconfig.NewNamespaceIntSetting(
	"nexusoperation.limit.reasonLength",
	1000,
	`Limits the maximum allowed length for a reason string in Nexus operation requests.
Uses Go's len() function to determine the length.`,
)
View Source
var MaxServiceNameLength = dynamicconfig.NewNamespaceIntSetting(
	"nexusoperation.limit.service.name.length",
	1000,
	`Limits the maximum allowed length for a Nexus Service name. ScheduleNexusOperation commands with a service name that
exceeds this limit will be rejected.  Uses Go's len() function to determine the length.`,
)
View Source
var MetricTagConfiguration = dynamicconfig.NewGlobalTypedSetting(
	"nexusoperation.metrics.tags",
	NexusMetricTagConfig{},
	`Controls which metric tags are included with Nexus operation metrics. This configuration supports:
1. Service name tag - adds the Nexus service name as a metric dimension (IncludeServiceTag)
2. Operation name tag - adds the Nexus operation name as a metric dimension (IncludeOperationTag)
3. Header-based tags - maps values from request headers to metric tags (HeaderTagMappings)

Note: default metric tags (like namespace, endpoint) are always included and not affected by this configuration.
Adding high-cardinality tags (like unique operation names) can significantly increase metric storage requirements and
query complexity. Consider the cardinality impact when enabling these tags.`,
)
View Source
var MinDispatchTaskTimeout = dynamicconfig.NewNamespaceDurationSetting(
	"nexusoperation.limit.dispatch.task.timeout.min",
	time.Second,
	`Minimum time remaining for a request to be dispatched to the handler worker. If the remaining request timeout is less
than this value, a timeout error will be returned. Working in conjunction with MinRequestTimeout, both configs help
ensure that the server has enough time to complete a Nexus request.`,
)
View Source
var MinRequestTimeout = dynamicconfig.NewNamespaceDurationSetting(
	"nexusoperation.limit.request.timeout.min",
	time.Millisecond*1500,
	`Minimum time remaining for a request to complete for the server to make RPCs. If the remaining request timeout is
less than this value, a non-retryable timeout error will be returned.`,
)
View Source
var Module = fx.Module(
	"chasm.lib.nexusoperation",
	fx.Provide(configProvider),
	fx.Provide(commonnexus.NewCallbackTokenGenerator),
	fx.Provide(endpointRegistryProvider),
	fx.Invoke(endpointRegistryLifetimeHooks),
	fx.Provide(defaultNexusTransportProvider),
	fx.Provide(clientProviderFactory),
	fx.Provide(newHandler),
	fx.Provide(newCancellationBackoffTaskHandler),
	fx.Provide(newCancellationInvocationTaskHandler),
	fx.Provide(newOperationBackoffTaskHandler),
	fx.Provide(newOperationInvocationTaskHandler),
	fx.Provide(newOperationScheduleToCloseTimeoutTaskHandler),
	fx.Provide(newOperationScheduleToStartTimeoutTaskHandler),
	fx.Provide(newOperationStartToCloseTimeoutTaskHandler),
	fx.Provide(newLibrary),
	fx.Invoke(register),
)
View Source
var NexusOperationCancelCount = metrics.NewCounterDef(
	"nexus_operation_cancel",
	metrics.WithDescription("Nexus Operations cancellations."),
)
View Source
var NexusOperationFailedCount = metrics.NewCounterDef(
	"nexus_operation_fail",
	metrics.WithDescription("Nexus Operations failures."),
)
View Source
var NexusOperationScheduleToCloseLatency = metrics.NewTimerDef(
	"nexus_operation_schedule_to_close_latency",
	metrics.WithDescription("Duration from Nexus Operation scheduled time to terminal state."),
)
View Source
var NexusOperationScheduleToStartLatency = metrics.NewTimerDef(
	"nexus_operation_schedule_to_start_latency",
	metrics.WithDescription("Duration from Nexus Operation scheduled time to started time."),
)
View Source
var NexusOperationStartToCloseLatency = metrics.NewTimerDef(
	"nexus_operation_start_to_close_latency",
	metrics.WithDescription("Duration from Nexus Operation started time to completed time. Only emitted for async operations."),
)
View Source
var NexusOperationSuccessCount = metrics.NewCounterDef(
	"nexus_operation_success",
	metrics.WithDescription("Nexus Operations successfully completed."),
)
View Source
var NexusOperationTerminateCount = metrics.NewCounterDef(
	"nexus_operation_terminate",
	metrics.WithDescription("Nexus Operations that were terminated before completion."),
)
View Source
var NexusOperationTimeoutCount = metrics.NewCounterDef(
	"nexus_operation_timeout",
	metrics.WithDescription("Nexus Operations that timed out before completion."),
)
View Source
var OperationContextKey = operationContextKeyType{}

OperationContextKey is the context key for OperationContext, registered as a CHASM component context value. Exported for use in tests that need to set up MockContext.

View Source
var OutboundRequestCounter = metrics.NewCounterDef(
	"nexus_outbound_requests",
	metrics.WithDescription("The number of Nexus outbound requests made by the history service."),
)
View Source
var OutboundRequestLatency = metrics.NewTimerDef(
	"nexus_outbound_latency",
	metrics.WithDescription("Latency of outbound Nexus requests made by the history service."),
)
View Source
var RequestTimeout = dynamicconfig.NewDestinationDurationSetting(
	"nexusoperation.request.timeout",
	time.Second*10,
	`Timeout for making a single nexus start or cancel request.`,
)
View Source
var RetryPolicy = dynamicconfig.NewGlobalTypedSettingWithConverter(
	"nexusoperation.retryPolicy",
	func(in any) (backoff.RetryPolicy, error) {
		cfg, err := dynamicconfig.ConvertStructure(defaultRetryPolicyConfig)(in)
		if err != nil {
			return nil, err
		}
		return cfg.build(), nil
	},
	defaultRetryPolicyConfig.build(),
	`The retry policy for nexus StartOperation or CancelOperation requests for a given operation.`,
)
View Source
var TransitionCanceled = chasm.NewTransition(
	[]nexusoperationpb.OperationStatus{
		nexusoperationpb.OPERATION_STATUS_SCHEDULED,
		nexusoperationpb.OPERATION_STATUS_STARTED,
		nexusoperationpb.OPERATION_STATUS_BACKING_OFF,
	},
	nexusoperationpb.OPERATION_STATUS_CANCELED,
	func(o *Operation, ctx chasm.MutableContext, event EventCanceled) error {
		closeTime := ctx.Now(o)
		if event.CompleteTime != nil {
			closeTime = *event.CompleteTime
		}
		o.emitOnCanceledMetrics(ctx, closeTime)

		fromAttempt := o.GetStatus() == nexusoperationpb.OPERATION_STATUS_SCHEDULED
		return o.resolveUnsuccessfully(ctx, event.Failure, closeTime, fromAttempt)
	},
)
View Source
var TransitionCancellationFailed = chasm.NewTransition(
	[]nexusoperationpb.CancellationStatus{

		nexusoperationpb.CANCELLATION_STATUS_UNSPECIFIED,
		nexusoperationpb.CANCELLATION_STATUS_SCHEDULED,
	},
	nexusoperationpb.CANCELLATION_STATUS_FAILED,
	func(c *Cancellation, ctx chasm.MutableContext, event EventCancellationFailed) error {
		currentTime := ctx.Now(c)
		c.LastAttemptCompleteTime = timestamppb.New(currentTime)
		c.LastAttemptFailure = event.Failure

		return nil
	},
)
View Source
var TransitionCancellationScheduled = chasm.NewTransition(
	[]nexusoperationpb.CancellationStatus{nexusoperationpb.CANCELLATION_STATUS_UNSPECIFIED},
	nexusoperationpb.CANCELLATION_STATUS_SCHEDULED,
	func(c *Cancellation, ctx chasm.MutableContext, event EventCancellationScheduled) error {
		c.Attempt++

		ctx.AddTask(c, chasm.TaskAttributes{
			Destination: event.Destination,
		}, &nexusoperationpb.CancellationTask{
			Attempt: c.Attempt,
		})

		return nil
	},
)
View Source
var TransitionCancellationSucceeded = chasm.NewTransition(
	[]nexusoperationpb.CancellationStatus{nexusoperationpb.CANCELLATION_STATUS_SCHEDULED},
	nexusoperationpb.CANCELLATION_STATUS_SUCCEEDED,
	func(c *Cancellation, ctx chasm.MutableContext, event EventCancellationSucceeded) error {
		currentTime := ctx.Now(c)
		c.LastAttemptCompleteTime = timestamppb.New(currentTime)
		c.LastAttemptFailure = nil

		return nil
	},
)
View Source
var TransitionFailed = chasm.NewTransition(
	[]nexusoperationpb.OperationStatus{
		nexusoperationpb.OPERATION_STATUS_SCHEDULED,
		nexusoperationpb.OPERATION_STATUS_STARTED,
		nexusoperationpb.OPERATION_STATUS_BACKING_OFF,
	},
	nexusoperationpb.OPERATION_STATUS_FAILED,
	func(o *Operation, ctx chasm.MutableContext, event EventFailed) error {
		closeTime := ctx.Now(o)
		if event.CompleteTime != nil {
			closeTime = *event.CompleteTime
		}

		fromAttempt := o.GetStatus() == nexusoperationpb.OPERATION_STATUS_SCHEDULED
		o.emitOnFailedMetrics(ctx, closeTime)
		return o.resolveUnsuccessfully(ctx, event.Failure, closeTime, fromAttempt)
	},
)
View Source
var TransitionScheduled = chasm.NewTransition(
	[]nexusoperationpb.OperationStatus{nexusoperationpb.OPERATION_STATUS_UNSPECIFIED},
	nexusoperationpb.OPERATION_STATUS_SCHEDULED,
	func(o *Operation, ctx chasm.MutableContext, event EventScheduled) error {
		o.Attempt++

		ctx.AddTask(o, chasm.TaskAttributes{Destination: o.GetEndpoint()}, &nexusoperationpb.InvocationTask{
			Attempt: o.Attempt,
		})

		if o.ScheduleToStartTimeout != nil && o.ScheduleToStartTimeout.AsDuration() != 0 {
			deadline := o.ScheduledTime.AsTime().Add(o.ScheduleToStartTimeout.AsDuration())
			ctx.AddTask(o, chasm.TaskAttributes{
				ScheduledTime: deadline,
			}, &nexusoperationpb.ScheduleToStartTimeoutTask{})
		}

		if o.ScheduleToCloseTimeout != nil && o.ScheduleToCloseTimeout.AsDuration() != 0 {
			deadline := o.ScheduledTime.AsTime().Add(o.ScheduleToCloseTimeout.AsDuration())
			ctx.AddTask(o, chasm.TaskAttributes{
				ScheduledTime: deadline,
			}, &nexusoperationpb.ScheduleToCloseTimeoutTask{})
		}

		return nil
	},
)
View Source
var TransitionStarted = chasm.NewTransition(
	[]nexusoperationpb.OperationStatus{
		nexusoperationpb.OPERATION_STATUS_SCHEDULED,
		nexusoperationpb.OPERATION_STATUS_BACKING_OFF,
	},
	nexusoperationpb.OPERATION_STATUS_STARTED,
	func(o *Operation, ctx chasm.MutableContext, event EventStarted) error {
		startTime := ctx.Now(o)
		if event.StartTime != nil {
			startTime = *event.StartTime
		}

		o.StartedTime = timestamppb.New(startTime)

		o.LastAttemptCompleteTime = o.StartedTime
		o.LastAttemptFailure = nil

		o.NextAttemptScheduleTime = nil

		o.OperationToken = event.OperationToken

		metricsHandler := o.metricsHandler(ctx)
		NexusOperationScheduleToStartLatency.With(metricsHandler).Record(startTime.Sub(o.GetScheduledTime().AsTime()))

		if o.StartToCloseTimeout != nil && o.StartToCloseTimeout.AsDuration() != 0 {
			deadline := startTime.Add(o.StartToCloseTimeout.AsDuration())
			ctx.AddTask(o, chasm.TaskAttributes{
				ScheduledTime: deadline,
			}, &nexusoperationpb.StartToCloseTimeoutTask{})
		}

		cancellation, ok := o.Cancellation.TryGet(ctx)
		if ok && cancellation.StateMachineState() == nexusoperationpb.CANCELLATION_STATUS_UNSPECIFIED {
			return TransitionCancellationScheduled.Apply(cancellation, ctx, EventCancellationScheduled{
				Destination: o.GetEndpoint(),
			})
		}

		return nil
	},
)
View Source
var TransitionSucceeded = chasm.NewTransition(
	[]nexusoperationpb.OperationStatus{
		nexusoperationpb.OPERATION_STATUS_SCHEDULED,
		nexusoperationpb.OPERATION_STATUS_STARTED,
		nexusoperationpb.OPERATION_STATUS_BACKING_OFF,
	},
	nexusoperationpb.OPERATION_STATUS_SUCCEEDED,
	func(o *Operation, ctx chasm.MutableContext, event EventSucceeded) error {

		closeTime := ctx.Now(o)
		if event.CompleteTime != nil {
			closeTime = *event.CompleteTime
		}
		o.NextAttemptScheduleTime = nil
		o.ClosedTime = timestamppb.New(closeTime)

		o.getOrCreateOutcome(ctx).Variant = &nexusoperationpb.OperationOutcome_Successful_{
			Successful: &nexusoperationpb.OperationOutcome_Successful{Result: event.Result},
		}

		o.emitOnSucceededMetrics(ctx, closeTime)

		return nil
	},
)
View Source
var TransitionTerminated = chasm.NewTransition(
	[]nexusoperationpb.OperationStatus{
		nexusoperationpb.OPERATION_STATUS_SCHEDULED,
		nexusoperationpb.OPERATION_STATUS_STARTED,
		nexusoperationpb.OPERATION_STATUS_BACKING_OFF,
		nexusoperationpb.OPERATION_STATUS_CANCELED,
	},
	nexusoperationpb.OPERATION_STATUS_TERMINATED,
	func(o *Operation, ctx chasm.MutableContext, event EventTerminated) error {
		closeTime := ctx.Now(o)
		o.TerminateState = &nexusoperationpb.NexusOperationTerminateState{
			RequestId: event.RequestID,
		}
		failure := &failurepb.Failure{
			Message: event.Reason,
			FailureInfo: &failurepb.Failure_TerminatedFailureInfo{
				TerminatedFailureInfo: &failurepb.TerminatedFailureInfo{
					Identity: event.Identity,
				},
			},
		}
		o.emitOnTerminatedMetrics(ctx, closeTime)
		return o.resolveUnsuccessfully(ctx, failure, closeTime, false)
	},
)
View Source
var TransitionTimedOut = chasm.NewTransition(
	[]nexusoperationpb.OperationStatus{
		nexusoperationpb.OPERATION_STATUS_SCHEDULED,
		nexusoperationpb.OPERATION_STATUS_STARTED,
		nexusoperationpb.OPERATION_STATUS_BACKING_OFF,
	},
	nexusoperationpb.OPERATION_STATUS_TIMED_OUT,
	func(o *Operation, ctx chasm.MutableContext, event EventTimedOut) error {
		closeTime := ctx.Now(o)
		timeoutType := event.Failure.GetTimeoutFailureInfo().GetTimeoutType().String()
		o.emitOnTimedOutMetrics(ctx, closeTime, timeoutType)
		return o.resolveUnsuccessfully(ctx, event.Failure, closeTime, event.FromAttempt)
	},
)
View Source
var UseNewFailureWireFormat = dynamicconfig.NewNamespaceBoolSetting(
	"nexusoperation.useNewFailureWireFormat",
	true,
	`Controls whether to use the new failure wire format via an HTTP header that is attached to StartOperation requests.
Added for safety. Defaults to true. Likely to be removed in future server versions.`,
)

Functions

func PendingOperationState

PendingOperationState maps a nexus operation status to the corresponding pending API state. Returns PENDING_NEXUS_OPERATION_STATE_UNSPECIFIED for non-pending or unspecified statuses.

func UseChasmForWorkflow

func UseChasmForWorkflow(enabled bool, rolloutPercent int, namespaceName, workflowID string) bool

UseChasmForWorkflow reports whether new Nexus operations for a workflow should be created on CHASM. Live creation and rebuild must share this predicate so reset keeps workflows in the same rollout bucket.

Types

type Cancellation

type Cancellation struct {
	chasm.UnimplementedComponent

	// Persisted internal state
	*nexusoperationpb.CancellationState

	// Operation is a pointer to the parent Operation component.
	Operation chasm.ParentPtr[*Operation]
}

Cancellation is a CHASM component that represents a pending cancellation of a Nexus operation.

func (*Cancellation) LifecycleState

func (c *Cancellation) LifecycleState(_ chasm.Context) chasm.LifecycleState

LifecycleState maps the cancellation's status to a CHASM lifecycle state.

func (*Cancellation) SetStateMachineState

func (c *Cancellation) SetStateMachineState(status nexusoperationpb.CancellationStatus)

SetStateMachineState sets the cancellation status.

func (*Cancellation) StateMachineState

func (c *Cancellation) StateMachineState() nexusoperationpb.CancellationStatus

StateMachineState returns the current cancellation status.

type ClientProvider

type ClientProvider func(ctx context.Context, namespaceID string, entry *persistencespb.NexusEndpointEntry, service string) (*nexusrpc.HTTPClient, error)

ClientProvider provides a nexus client for a given endpoint.

type Config

type Config struct {
	Enabled                                    dynamicconfig.BoolPropertyFnWithNamespaceFilter
	EnableChasm                                dynamicconfig.BoolPropertyFnWithNamespaceFilter
	EnableChasmNexusWorkflowOperations         dynamicconfig.BoolPropertyFnWithNamespaceFilter
	ChasmNexusWorkflowOperationsRolloutPercent dynamicconfig.IntPropertyFnWithNamespaceFilter
	NumHistoryShards                           int32
	LongPollBuffer                             dynamicconfig.DurationPropertyFnWithNamespaceFilter
	LongPollTimeout                            dynamicconfig.DurationPropertyFnWithNamespaceFilter
	RequestTimeout                             dynamicconfig.DurationPropertyFnWithDestinationFilter
	MinRequestTimeout                          dynamicconfig.DurationPropertyFnWithNamespaceFilter
	MaxConcurrentOperationsPerWorkflow         dynamicconfig.IntPropertyFnWithNamespaceFilter
	MaxServiceNameLength                       dynamicconfig.IntPropertyFnWithNamespaceFilter
	MaxOperationNameLength                     dynamicconfig.IntPropertyFnWithNamespaceFilter
	MaxOperationTokenLength                    dynamicconfig.IntPropertyFnWithNamespaceFilter
	MaxOperationHeaderSize                     dynamicconfig.IntPropertyFnWithNamespaceFilter
	DisallowedOperationHeaders                 dynamicconfig.TypedPropertyFn[[]string]
	MaxOperationScheduleToCloseTimeout         dynamicconfig.DurationPropertyFnWithNamespaceFilter
	PayloadSizeLimit                           dynamicconfig.IntPropertyFnWithNamespaceFilter
	CallbackURLTemplate                        dynamicconfig.TypedPropertyFn[*template.Template]
	PayloadSizeLimitWarn                       dynamicconfig.IntPropertyFnWithNamespaceFilter
	MaxUserMetadataSummarySize                 dynamicconfig.IntPropertyFnWithNamespaceFilter
	MaxUserMetadataDetailsSize                 dynamicconfig.IntPropertyFnWithNamespaceFilter
	UseNewFailureWireFormat                    dynamicconfig.BoolPropertyFnWithNamespaceFilter
	RecordCancelRequestCompletionEvents        dynamicconfig.BoolPropertyFn
	VisibilityMaxPageSize                      dynamicconfig.IntPropertyFnWithNamespaceFilter
	MaxIDLengthLimit                           dynamicconfig.IntPropertyFn
	MaxReasonLength                            dynamicconfig.IntPropertyFnWithNamespaceFilter
	RetryPolicy                                func() backoff.RetryPolicy
}

type EventAttemptFailed

type EventAttemptFailed struct {
	Failure     *failurepb.Failure
	RetryPolicy backoff.RetryPolicy
}

EventAttemptFailed is triggered when an invocation attempt is failed with a retryable error.

type EventCanceled

type EventCanceled struct {
	// If not nil, uses the provided time instead of the current component time.
	// Used when a completion comes in before start is recorded (rare race).
	CompleteTime *time.Time
	Failure      *failurepb.Failure
}

EventCanceled is triggered when an operation is completed as canceled.

type EventCancellationAttemptFailed

type EventCancellationAttemptFailed struct {
	Failure     *failurepb.Failure
	RetryPolicy backoff.RetryPolicy
}

EventCancellationAttemptFailed is triggered when a cancellation attempt is failed with a retryable error.

type EventCancellationFailed

type EventCancellationFailed struct {
	Failure *failurepb.Failure
}

EventCancellationFailed is triggered when a cancellation attempt is failed with a non retryable error.

type EventCancellationRescheduled

type EventCancellationRescheduled struct {
}

EventCancellationRescheduled is triggered when cancellation is meant to be rescheduled after backing off from a previous attempt.

type EventCancellationScheduled

type EventCancellationScheduled struct {
	// Destination is the endpoint name for the cancellation task.
	// Must be provided by the caller because ParentPtr is not available during inline creation.
	Destination string
}

EventCancellationScheduled is triggered when cancellation is meant to be scheduled for the first time - immediately after it has been requested.

type EventCancellationSucceeded

type EventCancellationSucceeded struct {
}

EventCancellationSucceeded is triggered when a cancellation attempt succeeds.

type EventFailed

type EventFailed struct {
	// If not nil, uses the provided time instead of the current component time.
	// Used when a completion comes in before start is recorded (rare race).
	CompleteTime *time.Time
	Failure      *failurepb.Failure
}

EventFailed is triggered when an invocation attempt is failed with a non retryable error.

type EventRescheduled

type EventRescheduled struct {
}

EventRescheduled is triggered when the operation is meant to be rescheduled after backing off from a previous attempt.

type EventScheduled

type EventScheduled struct {
}

EventScheduled is triggered when the operation is meant to be scheduled - immediately after initialization.

type EventStarted

type EventStarted struct {
	OperationToken string
	// If not nil, uses the provided time instead of the current component time.
	// Used when a completion comes in before start is recorded (rare race).
	StartTime *time.Time
}

EventStarted is triggered when an invocation attempt succeeds and the handler indicates that it started an asynchronous operation.

type EventSucceeded

type EventSucceeded struct {
	// If not nil, uses the provided time instead of the current component time.
	// Used when a completion comes in before start is recorded (rare race).
	CompleteTime *time.Time
	Result       *commonpb.Payload
}

EventSucceeded is triggered when an invocation attempt succeeds.

type EventTerminated

type EventTerminated struct {
	chasm.TerminateComponentRequest
}

EventTerminated is triggered when the operation is terminated by user request.

type EventTimedOut

type EventTimedOut struct {
	Failure *failurepb.Failure
	// FromAttempt is true when the failure came from an invocation attempt.
	FromAttempt bool
}

EventTimedOut is triggered when a timeout is triggered for an operation.

type FrontendHandler

FrontendHandler provides the frontend-facing API for standalone Nexus operations.

func NewFrontendHandler

func NewFrontendHandler(
	client nexusoperationpb.NexusOperationServiceClient,
	config *Config,
	logger log.Logger,
	namespaceRegistry namespace.Registry,
	endpointRegistry commonnexus.EndpointRegistry,
	saMapperProvider searchattribute.MapperProvider,
	saValidator *searchattribute.Validator,
) FrontendHandler

type InvocationData

type InvocationData struct {
	// Input is the operation input payload.
	Input *commonpb.Payload
	// Header contains the Nexus headers for the operation.
	Header map[string]string
	// NexusLinks are the links to the caller(s) that scheduled this operation.
	NexusLinks []nexus.Link
}

InvocationData contains data needed to invoke a Nexus operation.

type InvocationTaskHandlerOptions

type InvocationTaskHandlerOptions struct {
	fx.In

	Config            *Config
	NamespaceRegistry namespace.Registry
	MetricsHandler    metrics.Handler
	Logger            log.Logger
	ClientProvider    ClientProvider
	EndpointRegistry  commonnexus.EndpointRegistry
	HTTPTraceProvider commonnexus.HTTPClientTraceProvider
	HistoryClient     resource.HistoryClient
	ChasmRegistry     *chasm.Registry
}

InvocationTaskHandlerOptions groups the common dependencies shared by the invocation and cancellation task handlers. It embeds fx.In so that dig can flatten its fields when embedded in other dig.In structs.

type Library

type Library struct {
	// contains filtered or unexported fields
}

func (*Library) Components

func (l *Library) Components() []*chasm.RegistrableComponent

func (*Library) Name

func (l *Library) Name() string

func (*Library) RegisterServices

func (l *Library) RegisterServices(server *grpc.Server)

func (*Library) Tasks

func (l *Library) Tasks() []*chasm.RegistrableTask

type NexusHeaderTagMapping

type NexusHeaderTagMapping struct {
	// Name of the request header to extract value from
	SourceHeader string
	// Name of the metric tag to set with the header value
	TargetTag string
}

type NexusMetricTagConfig

type NexusMetricTagConfig struct {
	// Include service name as a metric tag. Used for caller and handler metrics.
	IncludeServiceTag bool
	// Include operation name as a metric tag. Used for caller and handler metrics.
	IncludeOperationTag bool
	// Configuration for mapping request headers to metric tags. Only used for handler metrics.
	HeaderTagMappings []NexusHeaderTagMapping
}

type NexusTransportProvider

type NexusTransportProvider func(namespaceID, serviceName string) http.RoundTripper

NexusTransportProvider allows customization of the HTTP transport used for Nexus requests.

type Operation

type Operation struct {
	chasm.UnimplementedComponent

	// Persisted internal state
	*nexusoperationpb.OperationState

	// Pointer to an implementation of the "store". For a workflow-based Nexus operation
	// this is a parent pointer back to the workflow. For a standalone Nexus operation this is nil.
	Store chasm.ParentPtr[OperationStore]

	RequestData chasm.Field[*nexusoperationpb.OperationRequestData]
	// Cancellation is a child component that manages sending the cancel request to the Nexus endpoint.
	// Created when cancellation is requested, nil otherwise.
	Cancellation chasm.Field[*Cancellation]
	Outcome      chasm.Field[*nexusoperationpb.OperationOutcome]
	Visibility   chasm.Field[*chasm.Visibility]
}

Operation is a CHASM component that represents a Nexus operation.

func NewOperation

func NewOperation(state *nexusoperationpb.OperationState) *Operation

NewOperation creates a new Operation component with the given persisted state.

func (*Operation) ContextMetadata

func (o *Operation) ContextMetadata(_ chasm.Context) map[string]string

func (*Operation) HandleNexusCompletion

func (o *Operation) HandleNexusCompletion(
	ctx chasm.MutableContext,
	completion *persistencespb.ChasmNexusCompletion,
) error

HandleNexusCompletion handles the outcome of an asynchronous completion callback.

func (*Operation) LifecycleState

func (o *Operation) LifecycleState(_ chasm.Context) chasm.LifecycleState

LifecycleState maps the operation's status to a CHASM lifecycle state.

func (*Operation) RequestCancel

func (o *Operation) RequestCancel(
	ctx chasm.MutableContext,
	req *nexusoperationpb.CancellationState,
) error

RequestCancel requests cancellation of the operation. It creates a Cancellation child component and, if the operation has already started, schedules the cancellation request to be sent to the Nexus endpoint.

func (*Operation) SearchAttributes

func (o *Operation) SearchAttributes(_ chasm.Context) []chasm.SearchAttributeKeyValue

func (*Operation) SetStateMachineState

func (o *Operation) SetStateMachineState(status nexusoperationpb.OperationStatus)

SetStateMachineState sets the operation status.

func (*Operation) StateMachineState

func (o *Operation) StateMachineState() nexusoperationpb.OperationStatus

StateMachineState returns the current operation status.

type OperationContext

type OperationContext struct {
	MetricTagConfig dynamicconfig.TypedPropertyFn[NexusMetricTagConfig]
}

OperationContext holds dependencies injected into the chasm.Context for use by Operation methods.

type OperationStore

type OperationStore interface {
	OnNexusOperationStarted(ctx chasm.MutableContext, operation *Operation, operationToken string, startTime *time.Time, links []*commonpb.Link) error
	OnNexusOperationCanceled(ctx chasm.MutableContext, operation *Operation, cause *failurepb.Failure) error
	OnNexusOperationFailed(ctx chasm.MutableContext, operation *Operation, cause *failurepb.Failure) error
	OnNexusOperationTimedOut(ctx chasm.MutableContext, operation *Operation, cause *failurepb.Failure, fromAttempt bool) error
	OnNexusOperationCompleted(ctx chasm.MutableContext, operation *Operation, result *commonpb.Payload, links []*commonpb.Link) error
	OnNexusOperationCancellationCompleted(ctx chasm.MutableContext, operation *Operation) error
	OnNexusOperationCancellationFailed(ctx chasm.MutableContext, operation *Operation, cause *failurepb.Failure) error
	// NexusOperationInvocationData loads invocation data (Input, Header, NexusLinks) from the scheduled history event.
	NexusOperationInvocationData(ctx chasm.Context, operation *Operation) (InvocationData, error)
	WorkflowTypeName() string
}

OperationStore defines the interface that must be implemented by any parent component that wants to manage Nexus operations. It's the responsibility of the parent component to apply the appropriate state transitions to the operation.

type RetryPolicyConfig

type RetryPolicyConfig struct {
	InitialInterval time.Duration
	MaxInterval     time.Duration
}

Directories

Path Synopsis
gen
nexusoperationpb/v1
Code generated by protoc-gen-go-helpers.
Code generated by protoc-gen-go-helpers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL