Пример #1
0
        /// <summary>
        /// Internal constructor.
        /// </summary>
        /// <param name="parentWorkflow">The parent workflow.</param>
        /// <param name="workflowTypeName">The workflow type name.</param>
        /// <param name="options">Optional child workflow options.</param>
        internal ChildWorkflowFutureStub(Workflow parentWorkflow, string workflowTypeName, ChildWorkflowOptions options = null)
        {
            Covenant.Requires <ArgumentNullException>(parentWorkflow != null, nameof(parentWorkflow));
            Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(workflowTypeName), nameof(workflowTypeName));

            this.parentWorkflow   = parentWorkflow;
            this.client           = parentWorkflow.Client;
            this.WorkflowTypeName = workflowTypeName;
            this.Options          = ChildWorkflowOptions.Normalize(client, options);
        }
Пример #2
0
        /// <summary>
        /// Starts a child workflow.
        /// </summary>
        /// <param name="parentWorkflow">The parent workflow.</param>
        /// <param name="workflowTypeName">
        /// The type name used when registering the workers that will handle this workflow.
        /// This name will often be the fully qualified name of the workflow type but
        /// this may have been customized when the workflow worker was registered.
        /// </param>
        /// <param name="args">Specifies the workflow arguments encoded into a byte array.</param>
        /// <param name="options">Specifies the workflow options.</param>
        /// <returns>A <see cref="ChildExecution"/> identifying the new running workflow instance.</returns>
        /// <exception cref="EntityNotExistsException">Thrown if there is no workflow registered for <paramref name="workflowTypeName"/>.</exception>
        /// <exception cref="BadRequestException">Thrown if the request is not valid.</exception>
        /// <exception cref="WorkflowRunningException">Thrown if a workflow with this ID is already running.</exception>
        /// <remarks>
        /// This method kicks off a new child workflow instance and returns after Cadence has
        /// queued the operation but the method <b>does not</b> wait for the workflow to
        /// complete.
        /// </remarks>
        internal async Task <ChildExecution> StartChildWorkflowAsync(Workflow parentWorkflow, string workflowTypeName, byte[] args, ChildWorkflowOptions options)
        {
            Covenant.Requires <ArgumentNullException>(parentWorkflow != null, nameof(parentWorkflow));
            Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(workflowTypeName), nameof(workflowTypeName));
            EnsureNotDisposed();

            if (options == null)
            {
                options = new ChildWorkflowOptions();
            }
            else
            {
                options = options.Clone();
            }

            if (!options.ScheduleToCloseTimeout.HasValue)
            {
                options.ScheduleToCloseTimeout = Settings.WorkflowScheduleToCloseTimeout;
            }

            if (!options.ScheduleToStartTimeout.HasValue)
            {
                options.ScheduleToStartTimeout = Settings.WorkflowScheduleToStartTimeout;
            }

            if (!options.TaskStartToCloseTimeout.HasValue)
            {
                options.TaskStartToCloseTimeout = Settings.WorkflowTaskStartToCloseTimeout;
            }

            var reply = await parentWorkflow.ExecuteNonParallel(
                async() =>
            {
                return((WorkflowExecuteChildReply)await CallProxyAsync(
                           new WorkflowExecuteChildRequest()
                {
                    ContextId = parentWorkflow.ContextId,
                    Workflow = workflowTypeName,
                    Args = args,
                    Options = options.ToInternal(),
                    ScheduleToStartTimeout = options.ScheduleToStartTimeout ?? Settings.WorkflowScheduleToStartTimeout
                }));
            });

            reply.ThrowOnError();
            parentWorkflow.UpdateReplay(reply);

            return(new ChildExecution(reply.Execution.ToPublic(), reply.ChildId));
        }
Пример #3
0
        //---------------------------------------------------------------------
        // Static members

        /// <summary>
        /// <b>INTERNAL USE ONLY:</b> Normalizes the options passed by creating or cloning a new
        /// instance as required and filling unset properties using default client settings.
        /// </summary>
        /// <param name="client">The associated Cadence client.</param>
        /// <param name="options">The input options or <c>null</c>.</param>
        /// <param name="workflowInterface">Optionally specifies the workflow interface definition.</param>
        /// <returns>The normalized options.</returns>
        /// <exception cref="ArgumentNullException">Thrown if a valid task list is not specified.</exception>
        public static ChildWorkflowOptions Normalize(CadenceClient client, ChildWorkflowOptions options, Type workflowInterface = null)
        {
            Covenant.Requires <ArgumentNullException>(client != null, nameof(client));

            WorkflowInterfaceAttribute interfaceAttribute = null;

            if (workflowInterface != null)
            {
                CadenceHelper.ValidateWorkflowInterface(workflowInterface);

                interfaceAttribute = workflowInterface.GetCustomAttribute <WorkflowInterfaceAttribute>();
            }

            if (options == null)
            {
                options = new ChildWorkflowOptions();
            }
            else
            {
                options = options.Clone();
            }

            if (!options.ScheduleToCloseTimeout.HasValue || options.ScheduleToCloseTimeout.Value <= TimeSpan.Zero)
            {
                options.ScheduleToCloseTimeout = client.Settings.WorkflowScheduleToCloseTimeout;
            }

            if (!options.ScheduleToStartTimeout.HasValue || options.ScheduleToStartTimeout.Value <= TimeSpan.Zero)
            {
                options.ScheduleToStartTimeout = client.Settings.WorkflowScheduleToStartTimeout;
            }

            if (!options.TaskStartToCloseTimeout.HasValue || options.TaskStartToCloseTimeout.Value <= TimeSpan.Zero)
            {
                options.TaskStartToCloseTimeout = client.Settings.WorkflowTaskStartToCloseTimeout;
            }

            if (string.IsNullOrEmpty(options.TaskList))
            {
                if (interfaceAttribute != null && !string.IsNullOrEmpty(interfaceAttribute.TaskList))
                {
                    options.TaskList = interfaceAttribute.TaskList;
                }
            }

            return(options);
        }
Пример #4
0
        /// <summary>
        /// Internal constructor.
        /// </summary>
        /// <param name="parentWorkflow">The associated parent workflow.</param>
        /// <param name="methodName">Identifies the target workflow method or <c>null</c> or empty.</param>
        /// <param name="options">The child workflow options or <c>null</c>.</param>
        internal ChildWorkflowStub(Workflow parentWorkflow, string methodName, ChildWorkflowOptions options)
        {
            Covenant.Requires <ArgumentNullException>(parentWorkflow != null, nameof(parentWorkflow));

            var workflowInterface = typeof(TWorkflowInterface);

            CadenceHelper.ValidateWorkflowInterface(workflowInterface);

            this.parentWorkflow = parentWorkflow;
            this.options        = ChildWorkflowOptions.Normalize(parentWorkflow.Client, options);
            this.hasStarted     = false;

            var workflowTarget = CadenceHelper.GetWorkflowTarget(workflowInterface, methodName);

            this.workflowTypeName = workflowTarget.WorkflowTypeName;
            this.targetMethod     = workflowTarget.TargetMethod;
        }
Пример #5
0
        //---------------------------------------------------------------------
        // Static members

        /// <summary>
        /// <b>INTERNAL USE ONLY:</b> Normalizes the options passed by creating or cloning a new
        /// instance as required and filling unset properties using default client settings.
        /// </summary>
        /// <param name="client">The associated Cadence client.</param>
        /// <param name="options">The input options or <c>null</c>.</param>
        /// <param name="workflowInterface">Optionally specifies the workflow interface definition.</param>
        /// <param name="method">Optionally specifies the target workflow method.</param>
        /// <returns>The normalized options.</returns>
        /// <exception cref="ArgumentNullException">Thrown if a valid task list is not specified.</exception>
        public static ChildWorkflowOptions Normalize(CadenceClient client, ChildWorkflowOptions options, Type workflowInterface = null, MethodInfo method = null)
        {
            Covenant.Requires <ArgumentNullException>(client != null, nameof(client));

            WorkflowInterfaceAttribute interfaceAttribute = null;
            WorkflowMethodAttribute    methodAttribute    = null;

            if (options == null)
            {
                options = new ChildWorkflowOptions();
            }
            else
            {
                options = options.Clone();
            }

            if (workflowInterface != null)
            {
                CadenceHelper.ValidateWorkflowInterface(workflowInterface);

                interfaceAttribute = workflowInterface.GetCustomAttribute <WorkflowInterfaceAttribute>();
            }

            if (method != null)
            {
                methodAttribute = method.GetCustomAttribute <WorkflowMethodAttribute>();
            }

            if (string.IsNullOrEmpty(options.Domain))
            {
                if (!string.IsNullOrEmpty(methodAttribute?.Domain))
                {
                    options.Domain = methodAttribute.Domain;
                }

                if (string.IsNullOrEmpty(options.Domain) && !string.IsNullOrEmpty(interfaceAttribute?.Domain))
                {
                    options.Domain = interfaceAttribute.Domain;
                }
            }

            if (string.IsNullOrEmpty(options.TaskList))
            {
                if (!string.IsNullOrEmpty(methodAttribute?.TaskList))
                {
                    options.TaskList = methodAttribute.TaskList;
                }

                if (string.IsNullOrEmpty(options.TaskList) && !string.IsNullOrEmpty(interfaceAttribute?.TaskList))
                {
                    options.TaskList = interfaceAttribute.TaskList;
                }
            }

            if (options.StartToCloseTimeout <= TimeSpan.Zero)
            {
                if (methodAttribute != null && methodAttribute.StartToCloseTimeoutSeconds > 0)
                {
                    options.StartToCloseTimeout = TimeSpan.FromSeconds(methodAttribute.StartToCloseTimeoutSeconds);
                }

                if (options.StartToCloseTimeout <= TimeSpan.Zero)
                {
                    options.StartToCloseTimeout = client.Settings.WorkflowStartToCloseTimeout;
                }
            }

            if (options.ScheduleToStartTimeout <= TimeSpan.Zero)
            {
                if (methodAttribute != null && methodAttribute.ScheduleToStartTimeoutSeconds > 0)
                {
                    options.ScheduleToStartTimeout = TimeSpan.FromSeconds(methodAttribute.ScheduleToStartTimeoutSeconds);
                }

                if (options.ScheduleToStartTimeout <= TimeSpan.Zero)
                {
                    options.ScheduleToStartTimeout = client.Settings.WorkflowScheduleToStartTimeout;
                }
            }

            if (options.DecisionTaskTimeout <= TimeSpan.Zero)
            {
                if (methodAttribute != null && methodAttribute.DecisionTaskTimeoutSeconds > 0)
                {
                    options.DecisionTaskTimeout = TimeSpan.FromSeconds(methodAttribute.DecisionTaskTimeoutSeconds);
                }

                if (options.DecisionTaskTimeout <= TimeSpan.Zero)
                {
                    options.DecisionTaskTimeout = client.Settings.WorkflowDecisionTaskTimeout;
                }
            }

            if (options.WorkflowIdReusePolicy == Cadence.WorkflowIdReusePolicy.UseDefault)
            {
                if (methodAttribute != null && methodAttribute.WorkflowIdReusePolicy != WorkflowIdReusePolicy.UseDefault)
                {
                    options.WorkflowIdReusePolicy = methodAttribute.WorkflowIdReusePolicy;
                }

                if (options.WorkflowIdReusePolicy == Cadence.WorkflowIdReusePolicy.UseDefault)
                {
                    options.WorkflowIdReusePolicy = client.Settings.WorkflowIdReusePolicy;
                }
            }

            return(options);
        }