mirror of
https://github.com/hanzoai/tasks.git
synced 2026-10-04 02:04:03 +00:00
## What changed? Add StateSizeBytes to NexusOperationInfo set to ApproximateStateSize ## Why? Enables storage estimations ## How did you test it? - [ ] built - [ ] run locally and tested manually - [x] covered by existing tests - [x] added new unit test(s) - [ ] added new functional test(s)
141 lines
5.1 KiB
Go
141 lines
5.1 KiB
Go
package workflow
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/nexus-rpc/sdk-go/nexus"
|
|
commonpb "go.temporal.io/api/common/v1"
|
|
"go.temporal.io/api/serviceerror"
|
|
"go.temporal.io/api/workflowservice/v1"
|
|
"go.temporal.io/api/workflowservice/v1/workflowservicenexus"
|
|
"go.temporal.io/server/api/historyservice/v1"
|
|
"go.temporal.io/server/chasm"
|
|
"go.temporal.io/server/common/namespace"
|
|
commonnexus "go.temporal.io/server/common/nexus"
|
|
"go.temporal.io/server/common/searchattribute"
|
|
)
|
|
|
|
var ErrSignalWithStartOperationDisabled = serviceerror.NewUnimplemented("SignalWithStart operation is disabled")
|
|
|
|
type workflowServiceNexusHandler struct {
|
|
config Config
|
|
namespaceRegistry namespace.Registry
|
|
historyHandler historyservice.HistoryServiceServer
|
|
}
|
|
|
|
// signalWithStartWorkflowExecution implements the SignalWithStartWorkflowExecution Nexus operation.
|
|
func (h *workflowServiceNexusHandler) signalWithStartWorkflowExecution(
|
|
ctx context.Context,
|
|
req *workflowservice.SignalWithStartWorkflowExecutionRequest,
|
|
options nexus.StartOperationOptions,
|
|
) (*workflowservice.SignalWithStartWorkflowExecutionResponse, error) {
|
|
if !h.config.enableSignalWithStartFromWorkflow(req.GetNamespace()) {
|
|
return nil, ErrSignalWithStartOperationDisabled
|
|
}
|
|
nsID, err := h.namespaceRegistry.GetNamespaceID(namespace.Name(req.GetNamespace()))
|
|
if err != nil {
|
|
return nil, serviceerror.NewInvalidArgumentf("Invalid namespace %q: %v", req.GetNamespace(), err)
|
|
}
|
|
res, err := h.historyHandler.SignalWithStartWorkflowExecution(ctx, &historyservice.SignalWithStartWorkflowExecutionRequest{
|
|
NamespaceId: nsID.String(),
|
|
SignalWithStartRequest: req,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
link := commonnexus.ConvertLinkWorkflowEventToNexusLink(&commonpb.Link_WorkflowEvent{
|
|
Namespace: req.GetNamespace(),
|
|
WorkflowId: req.GetWorkflowId(),
|
|
RunId: res.GetRunId(),
|
|
Reference: &commonpb.Link_WorkflowEvent_RequestIdRef{
|
|
RequestIdRef: &commonpb.Link_WorkflowEvent_RequestIdReference{
|
|
RequestId: req.GetRequestId(),
|
|
},
|
|
},
|
|
})
|
|
nexus.AddHandlerLinks(ctx, link)
|
|
return &workflowservice.SignalWithStartWorkflowExecutionResponse{
|
|
RunId: res.GetRunId(),
|
|
Started: res.GetStarted(),
|
|
}, nil
|
|
}
|
|
|
|
func mustNewWorkflowServiceNexusHandler(
|
|
handler *workflowServiceNexusHandler,
|
|
) *nexus.Service {
|
|
svc := nexus.NewService(workflowservicenexus.TemporalAPIWorkflowserviceV1WorkflowService.ServiceName)
|
|
svc.MustRegister(nexus.NewSyncOperation(
|
|
workflowservicenexus.TemporalAPIWorkflowserviceV1WorkflowService.SignalWithStartWorkflowExecution.Name(),
|
|
handler.signalWithStartWorkflowExecution,
|
|
))
|
|
return svc
|
|
}
|
|
|
|
func (h *workflowServiceNexusHandler) setHistoryHandler(handler historyservice.HistoryServiceServer) {
|
|
h.historyHandler = handler
|
|
}
|
|
|
|
type SignalWithStartOperationProcessor struct {
|
|
validator *RequestValidator
|
|
}
|
|
|
|
func (o SignalWithStartOperationProcessor) ProcessInput(ctx chasm.NexusOperationProcessorContext, request *workflowservice.SignalWithStartWorkflowExecutionRequest) (*chasm.NexusOperationProcessorResult, error) {
|
|
if !o.validator.config.enableSignalWithStartFromWorkflow(ctx.Namespace.Name().String()) {
|
|
return nil, ErrSignalWithStartOperationDisabled
|
|
}
|
|
if request == nil {
|
|
return nil, serviceerror.NewInvalidArgument("Request is empty")
|
|
}
|
|
if request.GetNamespace() == "" {
|
|
request.Namespace = ctx.Namespace.Name().String()
|
|
} else if request.GetNamespace() != ctx.Namespace.Name().String() {
|
|
return nil, serviceerror.NewInvalidArgumentf("Namespace in request %q does not match namespace in context %q", request.GetNamespace(), ctx.Namespace.Name().String())
|
|
}
|
|
|
|
if request.GetRequestId() != "" {
|
|
return nil, serviceerror.NewInvalidArgument("RequestID should not be set on the request")
|
|
}
|
|
request.RequestId = ctx.RequestID
|
|
|
|
if len(request.GetLinks()) > 0 {
|
|
return nil, serviceerror.NewInvalidArgument("Links should not be set on the request")
|
|
}
|
|
request.Links = make([]*commonpb.Link, len(ctx.Links))
|
|
for i, link := range ctx.Links {
|
|
wLink, err := commonnexus.ConvertNexusLinkToLinkWorkflowEvent(link)
|
|
if err != nil {
|
|
return nil, serviceerror.NewInvalidArgumentf("Cannot convert %v link %v: %v", link.Type, link.URL, err)
|
|
}
|
|
request.Links[i] = &commonpb.Link{
|
|
Variant: &commonpb.Link_WorkflowEvent_{
|
|
WorkflowEvent: wLink,
|
|
},
|
|
}
|
|
}
|
|
|
|
if err := o.validator.ValidateSignalWithStartRequest(request); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &chasm.NexusOperationProcessorResult{
|
|
RoutingKey: chasm.NexusOperationRoutingKeyExecution{
|
|
NamespaceID: ctx.Namespace.ID().String(),
|
|
BusinessID: request.WorkflowId,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func NewWorkflowServiceNexusServiceProcessor(
|
|
config Config,
|
|
saMapperProvider searchattribute.MapperProvider,
|
|
saValidator *searchattribute.Validator,
|
|
) *chasm.NexusServiceProcessor {
|
|
sp := chasm.NewNexusServiceProcessor(workflowservicenexus.TemporalAPIWorkflowserviceV1WorkflowService.ServiceName)
|
|
op := SignalWithStartOperationProcessor{validator: NewValidator(config, saMapperProvider, saValidator)}
|
|
sp.MustRegisterOperation(
|
|
workflowservicenexus.TemporalAPIWorkflowserviceV1WorkflowService.SignalWithStartWorkflowExecution.Name(),
|
|
chasm.NewRegisterableNexusOperationProcessor(op),
|
|
)
|
|
return sp
|
|
}
|