Beispiel #1
0
        /// <summary>
        /// Starts the child workflow, returning an <see cref="ChildWorkflowFuture{T}"/> that can be used
        /// to retrieve the workflow result.
        /// </summary>
        /// <param name="args">The workflow arguments.</param>
        /// <returns>An <see cref="ChildWorkflowFuture{T}"/> that can be used to retrieve the workflow result.</returns>
        /// <exception cref="InvalidOperationException">Thrown if the child workflow has already been started.</exception>
        /// <remarks>
        /// <note>
        /// <b>IMPORTANT:</b> You need to take care to ensure that the parameters and
        /// result type passed are compatible with the target workflow arguments.
        /// </note>
        /// </remarks>
        public async Task <ChildWorkflowFuture <TResult> > StartAsync(params object[] args)
        {
            await SyncContext.Clear;

            Covenant.Requires <ArgumentNullException>(args != null, nameof(args));

            if (childExecution != null)
            {
                throw new InvalidOperationException("Cannot start a future stub more than once.");
            }

            childExecution = await client.StartChildWorkflowAsync(parentWorkflow, WorkflowTypeName, CadenceHelper.ArgsToBytes(client.DataConverter, args), Options);

            // Create and return the future.

            return(new ChildWorkflowFuture <TResult>(parentWorkflow, childExecution));
        }
Beispiel #2
0
        /// <summary>
        /// <para>
        /// Signals a child workflow.  This low-level method accepts a byte array
        /// with the already encoded parameters.
        /// </para>
        /// <note>
        /// This method blocks until the child workflow is scheduled and
        /// actually started on a worker.
        /// </note>
        /// </summary>
        /// <param name="parentWorkflow">The parent workflow.</param>
        /// <param name="execution">The child workflow execution.</param>
        /// <param name="signalName">Specifies the signal name.</param>
        /// <param name="signalArgs">Specifies the signal arguments as an encoded byte array.</param>
        /// <returns>The tracking <see cref="Task"/>.</returns>
        /// <exception cref="EntityNotExistsException">Thrown if the named domain does not exist.</exception>
        /// <exception cref="BadRequestException">Thrown when the request is invalid.</exception>
        /// <exception cref="InternalServiceException">Thrown for internal Cadence cluster problems.</exception>
        /// <exception cref="ServiceBusyException">Thrown when Cadence is too busy.</exception>
        internal async Task SignalChildWorkflowAsync(Workflow parentWorkflow, ChildExecution execution, string signalName, byte[] signalArgs)
        {
            Covenant.Requires <ArgumentNullException>(parentWorkflow != null, nameof(parentWorkflow));
            Covenant.Requires <ArgumentNullException>(execution != null, nameof(execution));
            Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(signalName), nameof(signalName));

            var reply = await parentWorkflow.ExecuteNonParallel(
                async() =>
            {
                return((WorkflowSignalChildReply)await CallProxyAsync(
                           new WorkflowSignalChildRequest()
                {
                    ContextId = parentWorkflow.ContextId,
                    ChildId = execution.ChildId,
                    SignalName = signalName,
                    SignalArgs = signalArgs
                }));
            });

            reply.ThrowOnError();
            parentWorkflow.UpdateReplay(reply);
        }
Beispiel #3
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="parentWorkflow">Identifies the parent workflow context.</param>
 /// <param name="childExecution">The child workflow execution.</param>
 internal ChildWorkflowFuture(Workflow parentWorkflow, ChildExecution childExecution)
 {
     this.parentWorkflow = parentWorkflow;
     this.childExecution = childExecution;
 }
Beispiel #4
0
        /// <summary>
        /// Returns the result from a child workflow execution, blocking until the workflow
        /// completes if it is still running.
        /// </summary>
        /// <param name="parentWorkflow">The parent workflow.</param>
        /// <param name="execution">Identifies the child workflow execution.</param>
        /// <returns>The workflow result encoded as bytes or <c>null</c>.</returns>
        /// <exception cref="EntityNotExistsException">Thrown if the workflow no longer exists.</exception>
        /// <exception cref="BadRequestException">Thrown if the request is invalid.</exception>
        /// <exception cref="InternalServiceException">Thrown for internal Cadence problems.</exception>
        internal async Task <byte[]> GetChildWorkflowResultAsync(Workflow parentWorkflow, ChildExecution execution)
        {
            Covenant.Requires <ArgumentNullException>(parentWorkflow != null, nameof(parentWorkflow));
            Covenant.Requires <ArgumentNullException>(execution != null, nameof(execution));
            EnsureNotDisposed();

            var reply = await parentWorkflow.ExecuteNonParallel(
                async() =>
            {
                return((WorkflowWaitForChildReply)await CallProxyAsync(
                           new WorkflowWaitForChildRequest()
                {
                    ContextId = parentWorkflow.ContextId,
                    ChildId = execution.ChildId
                }));
            });

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

            return(reply.Result);
        }