Пример #1
0
        public void OnNotifyIdle()
        {
            bool isTrySetCompleted = activeTaskCompletionSources.TrySetCompleted();

            if (completionState != null)
            {
                if (instance.WorkflowInstanceState == WorkflowInstanceState.Complete)
                {
                    // Completed as expected.
                    instance = null;
                }
                else
                {
                    // Typically aborted after completion due to a persistence failure.
                    completionState = null;
                }
            }
            if (!isTrySetCompleted)
            {
                idle.Set();
            }
        }
Пример #2
0
 public Task OnCompletedAsync(ActivityInstanceState completionState, IDictionary <string, object> outputArguments, Exception terminationException)
 {
     this.completionState = new WorkflowCompletionState(completionState, outputArguments, terminationException);
     return(RaiseCompletedAsync(completionState, outputArguments, terminationException));
 }
Пример #3
0
        // TODO handle timeout? TimeoutException on this task, and finish preparation in the background and set idle at the end, problem: it shouldn't know about idle!
        // Can be called only after a successful WaitIdleAsync()!
        private async Task PrepareAsync()
        {
            if (completionState == null)
            {
                if (instance != null && instance.WorkflowInstanceState == WorkflowInstanceState.Aborted)
                {
                    // We try to restart or reload it from the previous persisted state.
                    await grain.LoadWorkflowStateAsync();

                    instance = null;
                }
                if (instance == null)
                {
                    IWorkflowState          workflowState = grain.WorkflowState;
                    WorkflowIdentity        workflowDefinitionIdentity = null;
                    IWorkflowInstance       instance        = null;
                    WorkflowCompletionState completionState = null;
                    if (workflowState.InstanceValues == null)
                    {
                        // Start, there is no previous persisted state.
                        workflowDefinitionIdentity = workflowDefinitionIdentityFactory();
                        instance = new WorkflowInstance(this, workflowDefinitionFactory(workflowDefinitionIdentity), workflowDefinitionIdentity);
                        instance.Start(await RaiseStartingAsync(), Extensions);
                    }
                    else if (!WorkflowInstance.IsCompleted(workflowState.InstanceValues))
                    {
                        // Load previous persisted state.
                        instance = new WorkflowInstance(this, workflowDefinitionFactory(workflowState.WorkflowDefinitionIdentity), workflowState.WorkflowDefinitionIdentity);

                        // TODO If workflowState.WorkflowDefinitionIdentity differs from workflowDefinitionIdentity, we should create a DynamicUpdateMap and update the loaded instance.
                        //      Currently we downgrade the workflowDefinitionIdentity to the loaded value.
                        // NOTE The workflowDefinitionFactory usually yields the same singleton workflow definition (ie. activity) for the same WorkflowDefinitionIdentity,
                        //      what happens with these activity trees during update???
                        // await instance.LoadAsync(workflowState.InstanceValues, GetExtensions(), >>>DynamicUpdateMap: workflowState.WorkflowDefinitionIdentity -> workflowDefinitionIdentity<<<);

                        await instance.LoadAsync(workflowState.InstanceValues, Extensions);

                        workflowDefinitionIdentity = workflowState.WorkflowDefinitionIdentity;
                    }
                    else
                    {
                        completionState = new WorkflowCompletionState();
                        await completionState.LoadAsync(workflowState.InstanceValues, HostExtensions, Parameters);
                    }
                    // Set the the values only, when the instance/completionState was successfully initialized.
                    this.workflowDefinitionIdentity = workflowDefinitionIdentity;
                    this.instance        = instance;
                    this.completionState = completionState;
                }
                if (instance != null && instance.WorkflowInstanceState == WorkflowInstanceState.Runnable)
                {
                    TaskCompletionSource <object> taskCompletionSource = new TaskCompletionSource <object>();
                    try
                    {
                        activeTaskCompletionSources.ProtectionLevel = ActiveTaskCompletionSources.TaskCompletionSourceProtectionLevel.Preparation;
                        activeTaskCompletionSources.Add(taskCompletionSource);
                        await instance.RunAsync();

                        await taskCompletionSource.Task;
                    }
                    finally
                    {
                        activeTaskCompletionSources.ProtectionLevel = ActiveTaskCompletionSources.TaskCompletionSourceProtectionLevel.Normal;
                        activeTaskCompletionSources.Remove(taskCompletionSource);
                    }
                }
            }
        }