/// <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)); }
/// <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); }
/// <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; }
/// <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); }