/// <summary> /// Converts the instance into an internal <see cref="InternalStartWorkflowOptions"/>. /// </summary> /// <returns>The corresponding <see cref="InternalStartWorkflowOptions"/>.</returns> internal InternalStartWorkflowOptions ToInternal() { Dictionary <string, byte[]> encodedMemos = null; if (Memo != null && Memo.Count > 0) { encodedMemos = new Dictionary <string, byte[]>(); foreach (var item in Memo) { encodedMemos.Add(item.Key, NeonHelper.JsonSerializeToBytes(item.Value)); } } return(new InternalStartWorkflowOptions() { ID = this.WorkflowId, TaskList = this.TaskList, DecisionTaskStartToCloseTimeout = CadenceHelper.ToCadence(this.TaskStartToCloseTimeout.Value), ExecutionStartToCloseTimeout = CadenceHelper.ToCadence(this.ScheduleToCloseTimeout.Value), RetryPolicy = this.RetryOptions?.ToInternal(), WorkflowIdReusePolicy = (int)(this.WorkflowIdReusePolicy == WorkflowIdReusePolicy.UseDefault ? Cadence.WorkflowIdReusePolicy.AllowDuplicateFailedOnly : this.WorkflowIdReusePolicy), CronSchedule = this.CronSchedule, Memo = encodedMemos }); }
/// <summary> /// Converts this instance into the corresponding internal object. /// </summary> /// <returns>The equivalent <see cref="InternalLocalActivityOptions"/>.</returns> internal InternalLocalActivityOptions ToInternal() { return(new InternalLocalActivityOptions() { ScheduleToCloseTimeout = CadenceHelper.ToCadence(this.ScheduleToCloseTimeout), RetryPolicy = RetryOptions?.ToInternal() }); }
/// <summary> /// Converts the instance into an internal <see cref="InternalStartWorkflowOptions"/>. /// </summary> /// <param name="client">The <see cref="CadenceClient"/>.</param> /// <param name="taskList">Optionally specifies the target task list.</param> /// <param name="methodAttribute">Optionally specifies a <see cref="WorkflowMethodAttribute"/>.</param> /// <returns>The corresponding <see cref="InternalStartWorkflowOptions"/>.</returns> internal InternalStartWorkflowOptions ToInternal(CadenceClient client, string taskList = null, WorkflowMethodAttribute methodAttribute = null) { Covenant.Requires <ArgumentNullException>(client != null); taskList = client.ResolveTaskList(taskList); // Merge optional settings from these options and the method attribute. var decisionTaskStartToCloseTimeout = TimeSpan.FromSeconds(10); var executionStartToCloseTimeout = CadenceClient.DefaultTimeout; var workflowIdReusePolicy = global::Neon.Cadence.WorkflowIdReusePolicy.AllowDuplicateFailedOnly; if (methodAttribute != null) { if (string.IsNullOrEmpty(taskList)) { if (methodAttribute.TaskList != null) { taskList = methodAttribute.TaskList; } else { taskList = client.Settings.DefaultTaskList; } } if (!DecisionTaskStartToCloseTimeout.HasValue && methodAttribute.TaskStartToCloseTimeoutSeconds > 0) { decisionTaskStartToCloseTimeout = TimeSpan.FromSeconds(methodAttribute.TaskStartToCloseTimeoutSeconds); } if (!ExecutionStartToCloseTimeout.HasValue && methodAttribute.ExecutionStartToCloseTimeoutSeconds > 0) { executionStartToCloseTimeout = TimeSpan.FromSeconds(methodAttribute.ExecutionStartToCloseTimeoutSeconds); } if (!WorkflowIdReusePolicy.HasValue && methodAttribute.WorkflowIdReusePolicy.HasValue) { workflowIdReusePolicy = methodAttribute.WorkflowIdReusePolicy.Value; } } return(new InternalStartWorkflowOptions() { ID = this.WorkflowId, TaskList = taskList, DecisionTaskStartToCloseTimeout = CadenceHelper.ToCadence(decisionTaskStartToCloseTimeout), ExecutionStartToCloseTimeout = CadenceHelper.ToCadence(executionStartToCloseTimeout), RetryPolicy = this.RetryOptions?.ToInternal(), WorkflowIdReusePolicy = (int)workflowIdReusePolicy, CronSchedule = this.CronSchedule, Memo = this.Memo }); }
/// <summary> /// Converts the instance into an <see cref="InternalRetryPolicy"/>. /// </summary> /// <returns>The converted instance.</returns> internal InternalRetryPolicy ToInternal() { return(new InternalRetryPolicy() { BackoffCoefficient = this.BackoffCoefficient, ExpirationInterval = CadenceHelper.ToCadence(this.ExpirationInterval), InitialInterval = CadenceHelper.ToCadence(this.InitialInterval), MaximumAttempts = this.MaximumAttempts, MaximumInterval = CadenceHelper.ToCadence(this.MaximumInterval), NonRetriableErrorReasons = NonRetriableErrors.ToList() }); }
/// <summary> /// Converts the instance to its internal representation. /// </summary> internal InternalActivityOptions ToInternal() { return(new InternalActivityOptions() { TaskList = this.TaskList, ScheduleToCloseTimeout = CadenceHelper.ToCadence(this.ScheduleToCloseTimeout), ScheduleToStartTimeout = CadenceHelper.ToCadence(this.ScheduleToStartTimeout), StartToCloseTimeout = CadenceHelper.ToCadence(this.StartToCloseTimeout), HeartbeatTimeout = CadenceHelper.ToCadence(this.HeartbeatTimeout), WaitForCancellation = WaitForCancellation, RetryPolicy = RetryOptions?.ToInternal() }); }
/// <summary> /// Converts this instance into the corresponding internal object. /// </summary> /// <returns>The equivalent <see cref="InternalChildWorkflowOptions"/>.</returns> internal InternalChildWorkflowOptions ToInternal() { return(new InternalChildWorkflowOptions() { Domain = this.Domain, ChildClosePolicy = (int)this.ChildPolicy, CronSchedule = this.CronSchedule, ExecutionStartToCloseTimeout = CadenceHelper.ToCadence(this.ScheduleToCloseTimeout.Value), RetryPolicy = this.RetryOptions?.ToInternal(), TaskList = this.TaskList ?? string.Empty, TaskStartToCloseTimeout = CadenceHelper.ToCadence(this.TaskStartToCloseTimeout.Value), WaitForCancellation = this.WaitUntilFinished, WorkflowID = this.WorkflowId, WorkflowIdReusePolicy = (int)(this.WorkflowIdReusePolicy == WorkflowIdReusePolicy.UseDefault ? Cadence.WorkflowIdReusePolicy.AllowDuplicateFailedOnly : this.WorkflowIdReusePolicy) }); }
/// <summary> /// Converts this instance into the corresponding internal object. /// </summary> /// <returns>The equivalent <see cref="InternalChildWorkflowOptions"/>.</returns> internal InternalChildWorkflowOptions ToInternal() { return new InternalChildWorkflowOptions() { Domain = this.Domain, WorkflowID = this.WorkflowID, TaskList = this.TaskList, ExecutionStartToCloseTimeout = CadenceHelper.ToCadence(this.ExecutionStartToCloseTimeout), TaskStartToCloseTimeout = CadenceHelper.ToCadence(this.TaskStartToCloseTimeout), ChildPolicy = (int)this.ChildPolicy, WaitForCancellation = this.WaitUntilFinished, WorkflowIdReusePolicy = (int)this.WorkflowIdReusePolicy, RetryPolicy = this.RetryPolicy?.ToInternal(), CronSchedule = this.CronSchedule }; }
/// <summary> /// Handles workflow invocation. /// </summary> /// <param name="client">The associated cadence client.</param> /// <param name="request">The request message.</param> /// <returns>The reply message.</returns> internal static async Task <WorkflowInvokeReply> OnInvokeAsync(CadenceClient client, WorkflowInvokeRequest request) { Covenant.Requires <ArgumentNullException>(client != null); Covenant.Requires <ArgumentNullException>(request != null); Covenant.Requires <ArgumentException>(request.ReplayStatus != InternalReplayStatus.Unspecified); IWorkflowBase workflow; WorkflowRegistration registration; var contextId = request.ContextId; var workflowKey = new WorkflowInstanceKey(client, contextId); lock (syncLock) { if (request.ReplayStatus != InternalReplayStatus.Unspecified) { return(new WorkflowInvokeReply() { Error = new CadenceError($"[{nameof(WorkflowInvokeRequest)}] did not specify Workflow type name [Type={request.WorkflowType}] is not registered for this worker.") }); } if (idToWorkflow.TryGetValue(workflowKey, out workflow)) { return(new WorkflowInvokeReply() { Error = new CadenceError($"A workflow with [ID={workflowKey}] is already running on this worker.") }); } registration = GetWorkflowRegistration(client, request.WorkflowType); if (registration == null) { return(new WorkflowInvokeReply() { Error = new CadenceError($"Workflow type name [Type={request.WorkflowType}] is not registered for this worker.") }); } } workflow = (IWorkflowBase)Activator.CreateInstance(registration.WorkflowType); workflow.Workflow = new Workflow( parent: (WorkflowBase)workflow, client: client, contextId: contextId, workflowTypeName: request.WorkflowType, domain: request.Domain, taskList: request.TaskList, workflowId: request.WorkflowId, runId: request.RunId, isReplaying: request.ReplayStatus == InternalReplayStatus.Replaying, methodMap: registration.MethodMap); lock (syncLock) { idToWorkflow.Add(workflowKey, workflow); } // Register any workflow signal and/or query handlers with cadence-proxy foreach (var signalName in registration.MethodMap.GetSignalNames()) { var reply = (WorkflowSignalSubscribeReply)await client.CallProxyAsync( new WorkflowSignalSubscribeRequest() { ContextId = contextId, SignalName = signalName }); reply.ThrowOnError(); } foreach (var queryType in registration.MethodMap.GetQueryTypes()) { var reply = (WorkflowSetQueryHandlerReply)await client.CallProxyAsync( new WorkflowSetQueryHandlerRequest() { ContextId = contextId, QueryName = queryType }); reply.ThrowOnError(); } // Start the workflow by calling its workflow entry point method. // This method will indicate that it has completed via one of these // techniques: // // 1. The method returns normally with the workflow result. // // 2. The method calls [RestartAsync(result, args)] which throws an // [InternalWorkflowRestartException] which will be caught and // handled here. // // 3. The method throws another exception which will be caught // and be used to indicate that the workflow failed. try { var workflowMethod = registration.WorkflowMethod; var resultType = workflowMethod.ReturnType; var args = client.DataConverter.FromDataArray(request.Args, registration.WorkflowMethodParameterTypes); var serializedResult = emptyBytes; if (resultType.IsGenericType) { // Method returns: Task<T> var result = await(Task <object>) workflowMethod.Invoke(workflow, args); serializedResult = client.DataConverter.ToData(result); } else { // Method returns: Task await(Task <object>) workflowMethod.Invoke(workflow, args); serializedResult = emptyBytes; } return(new WorkflowInvokeReply() { Result = serializedResult }); } catch (CadenceWorkflowRestartException e) { return(new WorkflowInvokeReply() { ContinueAsNew = true, ContinueAsNewArgs = e.Args, ContinueAsNewDomain = e.Domain, ContinueAsNewTaskList = e.TaskList, ContinueAsNewExecutionStartToCloseTimeout = CadenceHelper.ToCadence(e.ExecutionStartToCloseTimeout), ContinueAsNewScheduleToCloseTimeout = CadenceHelper.ToCadence(e.ScheduleToCloseTimeout), ContinueAsNewScheduleToStartTimeout = CadenceHelper.ToCadence(e.ScheduleToStartTimeout), ContinueAsNewStartToCloseTimeout = CadenceHelper.ToCadence(e.TaskStartToCloseTimeout), }); } catch (CadenceException e) { return(new WorkflowInvokeReply() { Error = e.ToCadenceError() }); } catch (Exception e) { return(new WorkflowInvokeReply() { Error = new CadenceError(e) }); } }