Esempio n. 1
0
 // This happens out-of-band of ReceiveAsyncResult.
 // When transaction was aborted, we best-effort abandon the context.
 void OnTransactionComplete(object sender, TransactionEventArgs e)
 {
     if (e.Transaction.TransactionInformation.Status != TransactionStatus.Committed)
     {
         BufferedReceiveManager.AbandonReceiveContext(this.context.receiveContext);
     }
 }
Esempio n. 2
0
        bool ProcessReply()
        {
            bool completed = false;

            this.workflowInstance.ReleaseContext(this);
            this.RemovePendingOperation();

            if (this.CurrentState == State.BookmarkResumption) //We are still in Bookmark Resume
            {
                this.CurrentState = State.ResultReceived;      //HandleEndResumeBookmark will take care of Completing AsyncResult.
            }
            else if (this.CurrentState == State.WaitForResult) //We already finished the bookmarkOperation; Now have to signal the AsynResult.
            {
                this.CurrentState = State.Completed;
                completed         = true;
            }

            // we are not really completed until the ReceiveContext finishes its work
            if (completed)
            {
                if (this.pendingException == null)
                {
                    completed = ProcessReceiveContext();
                }
                else
                {
                    // if there's a pendingException, we let the RC abandon async so there's no need
                    // to affect the completed status
                    BufferedReceiveManager.AbandonReceiveContext(this.receiveContext);
                }
            }

            return(completed);
        }
        private bool ProcessReply()
        {
            bool flag = false;

            this.workflowInstance.ReleaseContext(this);
            this.RemovePendingOperation();
            if (this.CurrentState == State.BookmarkResumption)
            {
                this.CurrentState = State.ResultReceived;
            }
            else if (this.CurrentState == State.WaitForResult)
            {
                this.CurrentState = State.Completed;
                flag = true;
            }
            if (flag)
            {
                if (this.pendingException == null)
                {
                    return(this.ProcessReceiveContext());
                }
                BufferedReceiveManager.AbandonReceiveContext(this.receiveContext);
            }
            return(flag);
        }
        private static bool HandleEndResumeBookmark(IAsyncResult result)
        {
            WorkflowOperationContext asyncState = (WorkflowOperationContext)result.AsyncState;
            bool flag  = false;
            bool flag2 = true;

            try
            {
                if (asyncState.workflowInstance.EndResumeProtocolBookmark(result) != BookmarkResumptionResult.Success)
                {
                    asyncState.OperationContext.Host.RaiseUnknownMessageReceived(asyncState.OperationContext.IncomingMessage);
                    if ((asyncState.workflowInstance.BufferedReceiveManager != null) && asyncState.workflowInstance.BufferedReceiveManager.BufferReceive(asyncState.OperationContext, asyncState.receiveContext, asyncState.bookmark.Name, BufferedReceiveState.WaitingOnBookmark, false))
                    {
                        if (System.ServiceModel.Activities.TD.BufferOutOfOrderMessageNoBookmarkIsEnabled())
                        {
                            System.ServiceModel.Activities.TD.BufferOutOfOrderMessageNoBookmark(asyncState.workflowInstance.Id.ToString(), asyncState.bookmark.Name);
                        }
                        flag2 = false;
                    }
                    throw System.ServiceModel.Activities.FxTrace.Exception.AsError(new FaultException(OperationExecutionFault.CreateOperationNotAvailableFault(asyncState.workflowInstance.Id, asyncState.bookmark.Name)));
                }
                lock (asyncState.thisLock)
                {
                    if (asyncState.CurrentState == State.ResultReceived)
                    {
                        asyncState.CurrentState = State.Completed;
                        if (asyncState.pendingException != null)
                        {
                            throw System.ServiceModel.Activities.FxTrace.Exception.AsError(asyncState.pendingException);
                        }
                        flag = true;
                    }
                    else
                    {
                        asyncState.CurrentState = State.WaitForResult;
                        flag = false;
                    }
                    if (flag)
                    {
                        flag = asyncState.ProcessReceiveContext();
                    }
                    flag2 = false;
                }
            }
            finally
            {
                if (flag2)
                {
                    BufferedReceiveManager.AbandonReceiveContext(asyncState.receiveContext);
                }
                asyncState.RemovePendingOperation();
            }
            return(flag);
        }
        public ControlOperationInvoker(OperationDescription description, ServiceEndpoint endpoint,
            CorrelationKeyCalculator correlationKeyCalculator, IOperationInvoker innerInvoker, ServiceHostBase host)
        {
            Fx.Assert(host is WorkflowServiceHost, "ControlOperationInvoker must be used with a WorkflowServiceHost");

            this.host = (WorkflowServiceHost)host;
            this.instanceManager = this.host.DurableInstanceManager;
            this.operationName = description.Name;
            this.isOneWay = description.IsOneWay;
            this.endpoint = endpoint;
            this.innerInvoker = innerInvoker;
            this.keyCalculator = correlationKeyCalculator;
            this.persistTimeout = this.host.PersistTimeout;

            if (description.DeclaringContract == WorkflowControlEndpoint.WorkflowControlServiceContract ||
                description.DeclaringContract == WorkflowControlEndpoint.WorkflowControlServiceBaseContract)
            {
                //Mode1: This invoker belongs to IWorkflowInstanceManagement operation.
                this.isControlOperation = true;
                switch (this.operationName)
                {
                    case XD2.WorkflowInstanceManagementService.Cancel:
                    case XD2.WorkflowInstanceManagementService.TransactedCancel:
                    case XD2.WorkflowInstanceManagementService.Run:
                    case XD2.WorkflowInstanceManagementService.TransactedRun:
                    case XD2.WorkflowInstanceManagementService.Unsuspend:
                    case XD2.WorkflowInstanceManagementService.TransactedUnsuspend:
                        this.inputParameterCount = 1;
                        break;
                    case XD2.WorkflowInstanceManagementService.Abandon:
                    case XD2.WorkflowInstanceManagementService.Suspend:
                    case XD2.WorkflowInstanceManagementService.TransactedSuspend:
                    case XD2.WorkflowInstanceManagementService.Terminate:
                    case XD2.WorkflowInstanceManagementService.TransactedTerminate:
                    case XD2.WorkflowInstanceManagementService.Update:
                    case XD2.WorkflowInstanceManagementService.TransactedUpdate:
                        this.inputParameterCount = 2;
                        break;
                    default:
                        throw Fx.AssertAndThrow("Unreachable code");
                }
            }
            else if (endpoint is WorkflowHostingEndpoint)
            {
                this.CanCreateInstance = true;
            }
            else
            {
                this.bufferedReceiveManager = this.host.Extensions.Find<BufferedReceiveManager>();
            }
        }
        WorkflowServiceInstance(Activity workflowDefinition, WorkflowIdentity definitionIdentity, Guid instanceId, WorkflowServiceHost serviceHost, PersistenceContext persistenceContext)
            : base(workflowDefinition, definitionIdentity)
        {
            this.serviceHost = serviceHost;
            this.instanceId = instanceId;
            this.persistTimeout = serviceHost.PersistTimeout;
            this.trackTimeout = serviceHost.TrackTimeout;
            this.bufferedReceiveManager = serviceHost.Extensions.Find<BufferedReceiveManager>();

            if (persistenceContext != null)
            {
                this.persistenceContext = persistenceContext;
                this.persistenceContext.Closed += this.OnPersistenceContextClosed;
            }

            this.thisLock = new object();
            this.pendingRequests = new List<WorkflowOperationContext>();
            this.executorLock = new WorkflowExecutionLock(this);
            this.activeOperationsLock = new object();
            this.acquireReferenceSemaphore = new ThreadNeutralSemaphore(1);
            this.acquireLockTimeout = TimeSpan.MaxValue;

            // Two initial references are held:
            // The first referenceCount is owned by UnloadInstancePolicy (ReleaseInstance)
            this.referenceCount = 1;
            // The second referenceCount is owned by the loader / creator of the instance.
            this.TryAddReference();
        }
Esempio n. 7
0
        static bool HandleEndResumeBookmark(IAsyncResult result)
        {
            WorkflowOperationContext thisPtr = (WorkflowOperationContext)result.AsyncState;

            bool completed     = false;
            bool shouldAbandon = true;

            try
            {
                BookmarkResumptionResult resumptionResult = thisPtr.workflowInstance.EndResumeProtocolBookmark(result);
                if (resumptionResult != BookmarkResumptionResult.Success)
                {
                    // Raise UnkownMessageReceivedEvent when we fail to resume bookmark
                    thisPtr.OperationContext.Host.RaiseUnknownMessageReceived(thisPtr.OperationContext.IncomingMessage);

                    // Only delay-retry this operation once (and only if retries are supported). Future calls will ensure the bookmark is set.
                    if (thisPtr.workflowInstance.BufferedReceiveManager != null)
                    {
                        bool bufferSuccess = thisPtr.workflowInstance.BufferedReceiveManager.BufferReceive(
                            thisPtr.OperationContext, thisPtr.receiveContext, thisPtr.bookmark.Name, BufferedReceiveState.WaitingOnBookmark, false);
                        if (bufferSuccess)
                        {
                            if (TD.BufferOutOfOrderMessageNoBookmarkIsEnabled())
                            {
                                TD.BufferOutOfOrderMessageNoBookmark(thisPtr.eventTraceActivity, thisPtr.workflowInstance.Id.ToString(), thisPtr.bookmark.Name);
                            }

                            shouldAbandon = false;
                        }
                    }

                    // The throw exception is intentional whether or not BufferedReceiveManager is set.
                    // This is to allow exception to bubble up the stack to WCF to cleanup various state (like Transaction).
                    // This is queue scenario and as far as the client is concerned, the client will not see any exception.
                    throw FxTrace.Exception.AsError(new FaultException(OperationExecutionFault.CreateOperationNotAvailableFault(thisPtr.workflowInstance.Id, thisPtr.bookmark.Name)));
                }

                lock (thisPtr.thisLock)
                {
                    if (thisPtr.CurrentState == State.ResultReceived)
                    {
                        thisPtr.CurrentState = State.Completed;
                        if (thisPtr.pendingException != null)
                        {
                            throw FxTrace.Exception.AsError(thisPtr.pendingException);
                        }
                        completed = true;
                    }
                    else
                    {
                        thisPtr.CurrentState = State.WaitForResult;
                        completed            = false;
                    }

                    // we are not really completed until the ReceiveContext finishes its work
                    if (completed)
                    {
                        completed = thisPtr.ProcessReceiveContext();
                    }

                    shouldAbandon = false;
                }
            }
            finally
            {
                if (shouldAbandon)
                {
                    BufferedReceiveManager.AbandonReceiveContext(thisPtr.receiveContext);
                }
                thisPtr.RemovePendingOperation();
            }

            return(completed);
        }