public static void InitializeCorrelationHandles(NativeActivityContext context, CorrelationHandle selectHandle, CorrelationHandle ambientHandle, Collection <CorrelationInitializer> additionalCorrelations, MessageProperties messageProperties)
        {
            CorrelationMessageProperty property;

            if (CorrelationMessageProperty.TryGet(messageProperties, out property))
            {
                InitializeCorrelationHandles(context, selectHandle, ambientHandle, additionalCorrelations, property.CorrelationKey, property.AdditionalKeys);
            }
        }
예제 #2
0
        protected internal virtual Bookmark OnResolveBookmark(WorkflowOperationContext context, out BookmarkScope bookmarkScope, out object value)
        {
            CorrelationMessageProperty property;

            if (CorrelationMessageProperty.TryGet(context.OperationContext.IncomingMessageProperties, out property))
            {
                bookmarkScope = new BookmarkScope(property.CorrelationKey.Value);
            }
            else
            {
                bookmarkScope = BookmarkScope.Default;
            }
            value = context;
            return(this.bookmark);
        }
        protected void GetInstanceKeys(OperationContext operationContext, out InstanceKey instanceKey, out ICollection <InstanceKey> additionalKeys)
        {
            CorrelationMessageProperty property = null;

            instanceKey    = InstanceKey.InvalidKey;
            additionalKeys = new ReadOnlyCollection <InstanceKey>(new InstanceKey[0]);
            if (!CorrelationMessageProperty.TryGet(operationContext.IncomingMessageProperties, out property))
            {
                if (this.keyCalculator != null)
                {
                    InstanceKey key;
                    ICollection <InstanceKey> is2;
                    MessageBuffer             buffer;
                    bool flag;
                    if (operationContext.IncomingMessageProperties.TryGetValue <MessageBuffer>("_RequestMessageBuffer_", out buffer))
                    {
                        flag = this.keyCalculator.CalculateKeys(buffer, operationContext.IncomingMessage, out key, out is2);
                    }
                    else
                    {
                        flag = this.keyCalculator.CalculateKeys(operationContext.IncomingMessage, out key, out is2);
                    }
                    if (flag)
                    {
                        if (key != null)
                        {
                            instanceKey = key;
                        }
                        if (is2 != null)
                        {
                            additionalKeys = is2;
                        }
                        property = new CorrelationMessageProperty(instanceKey, additionalKeys);
                        operationContext.IncomingMessageProperties.Add(CorrelationMessageProperty.Name, property);
                    }
                }
            }
            else
            {
                instanceKey    = property.CorrelationKey;
                additionalKeys = property.AdditionalKeys;
            }
            if (((instanceKey == null) || !instanceKey.IsValid) && !this.CanCreateInstance)
            {
                this.host.RaiseUnknownMessageReceived(operationContext.IncomingMessage);
                throw System.ServiceModel.Activities.FxTrace.Exception.AsError(new FaultException(new DurableDispatcherAddressingFault()));
            }
        }
                protected internal override Bookmark OnResolveBookmark(WorkflowOperationContext context, out BookmarkScope bookmarkScope, out object value)
                {
                    CorrelationMessageProperty property;

                    if (CorrelationMessageProperty.TryGet(context.OperationContext.IncomingMessageProperties, out property))
                    {
                        bookmarkScope = new BookmarkScope(property.CorrelationKey.Value);
                    }
                    else
                    {
                        bookmarkScope = null;
                    }
                    WorkflowHostingResponseContext responseContext = new WorkflowHostingResponseContext(context);
                    Bookmark bookmark = this.hostingEndpoint.OnResolveBookmark(context.Inputs, context.OperationContext, responseContext, out value);

                    if (bookmark == null)
                    {
                        throw System.ServiceModel.Activities.FxTrace.Exception.AsError(WorkflowHostingEndpoint.CreateDispatchFaultException());
                    }
                    return(bookmark);
                }
예제 #5
0
                protected internal override Bookmark OnResolveBookmark(WorkflowOperationContext context, out BookmarkScope bookmarkScope, out object value)
                {
                    CorrelationMessageProperty correlationMessageProperty;

                    if (CorrelationMessageProperty.TryGet(context.OperationContext.IncomingMessageProperties, out correlationMessageProperty))
                    {
                        bookmarkScope = new BookmarkScope(correlationMessageProperty.CorrelationKey.Value);
                    }
                    else
                    {
                        bookmarkScope = null;
                    }

                    WorkflowHostingResponseContext responseContext = new WorkflowHostingResponseContext(context);

                    Fx.Assert(context.ServiceEndpoint is WorkflowHostingEndpoint, "serviceEnpoint must be of WorkflowHostingEndpoint type!");
                    Bookmark bookmark = ((WorkflowHostingEndpoint)context.ServiceEndpoint).OnResolveBookmark(context.Inputs, context.OperationContext, responseContext, out value);

                    if (bookmark == null)
                    {
                        throw FxTrace.Exception.AsError(CreateDispatchFaultException());
                    }
                    return(bookmark);
                }
예제 #6
0
        public bool BufferReceive(OperationContext operationContext, ReceiveContext receiveContext, string bookmarkName, BufferedReceiveState state, bool retry)
        {
            Fx.Assert(receiveContext != null, "ReceiveContext must be present in order to perform buffering");

            bool success = false;

            BufferedReceiveMessageProperty property = null;

            if (BufferedReceiveMessageProperty.TryGet(operationContext.IncomingMessageProperties, out property))
            {
                CorrelationMessageProperty correlation = null;
                if (CorrelationMessageProperty.TryGet(operationContext.IncomingMessageProperties, out correlation))
                {
                    InstanceKey instanceKey = correlation.CorrelationKey;
                    int         channelKey  = operationContext.Channel.GetHashCode();
                    if (this.throttle.Acquire(channelKey))
                    {
                        try
                        {
                            // Tag the property with identifying data to be used during later processing
                            if (UpdateProperty(property, receiveContext, channelKey, bookmarkName, state))
                            {
                                // Cleanup if we are notified the ReceiveContext faulted underneath us
                                receiveContext.Faulted += delegate(object sender, EventArgs e)
                                {
                                    lock (this.thisLock)
                                    {
                                        if (this.bufferedProperties.ContainsKey(instanceKey))
                                        {
                                            if (this.bufferedProperties[instanceKey].Remove(property))
                                            {
                                                try
                                                {
                                                    property.RequestContext.DelayClose(false);
                                                    property.RequestContext.Abort();
                                                }
                                                catch (Exception exception)
                                                {
                                                    if (Fx.IsFatal(exception))
                                                    {
                                                        throw;
                                                    }

                                                    // ---- these exceptions as we are already on the error path
                                                }

                                                this.throttle.Release(channelKey);
                                            }
                                        }
                                    }
                                };

                                // Actual Buffering
                                lock (this.thisLock)
                                {
                                    // Optimistic state check in case we just raced with the receiveContext
                                    // faulting. If the receiveContext still faults after the state check, the above
                                    // cleanup routine will handle things correctly. In both cases, a double-release
                                    // of the throttle is protected.
                                    if (receiveContext.State == ReceiveContextState.Received)
                                    {
                                        bool found = false;
                                        // if the exception indicates retry-able (such as RetryException),
                                        // we will simply retry.  This happens when racing with abort and
                                        // WF informing the client to retry (BufferedReceiveManager is a
                                        // client in this case).
                                        if (retry)
                                        {
                                            property.RequestContext.DelayClose(true);
                                            property.RegisterForReplay(operationContext);
                                            property.ReplayRequest();
                                            property.Notification.NotifyInvokeReceived(property.RequestContext.InnerRequestContext);
                                            found = true;
                                        }
                                        else
                                        {
                                            ReadOnlyCollection <BookmarkInfo> bookmarks = this.host.DurableInstanceManager.PersistenceProviderDirectory.GetBookmarksForInstance(instanceKey);
                                            // Retry in case match the existing bookmark
                                            if (bookmarks != null)
                                            {
                                                for (int i = 0; i < bookmarks.Count; ++i)
                                                {
                                                    BookmarkInfo bookmark = bookmarks[i];
                                                    if (bookmark.BookmarkName == bookmarkName)
                                                    {
                                                        // Found it so retry...
                                                        property.RequestContext.DelayClose(true);
                                                        property.RegisterForReplay(operationContext);
                                                        property.ReplayRequest();
                                                        property.Notification.NotifyInvokeReceived(property.RequestContext.InnerRequestContext);
                                                        found = true;
                                                        break;
                                                    }
                                                }
                                            }
                                        }

                                        if (!found)
                                        {
                                            List <BufferedReceiveMessageProperty> properties;
                                            if (!this.bufferedProperties.TryGetValue(instanceKey, out properties))
                                            {
                                                properties = new List <BufferedReceiveMessageProperty>();
                                                this.bufferedProperties.Add(instanceKey, properties);
                                            }
                                            property.RequestContext.DelayClose(true);
                                            property.RegisterForReplay(operationContext);
                                            properties.Add(property);
                                        }
                                        else
                                        {
                                            this.throttle.Release(channelKey);
                                        }
                                        success = true;
                                    }
                                }
                            }
                        }
                        finally
                        {
                            if (!success)
                            {
                                this.throttle.Release(channelKey);
                            }
                        }
                    }
                }
            }

            return(success);
        }
        public bool BufferReceive(OperationContext operationContext, ReceiveContext receiveContext, string bookmarkName, BufferedReceiveState state, bool retry)
        {
            bool flag = false;
            BufferedReceiveMessageProperty property = null;

            if (BufferedReceiveMessageProperty.TryGet(operationContext.IncomingMessageProperties, out property))
            {
                CorrelationMessageProperty property = null;
                if (!CorrelationMessageProperty.TryGet(operationContext.IncomingMessageProperties, out property))
                {
                    return(flag);
                }
                EventHandler handler     = null;
                InstanceKey  instanceKey = property.CorrelationKey;
                int          channelKey  = operationContext.Channel.GetHashCode();
                if (!this.throttle.Acquire(channelKey))
                {
                    return(flag);
                }
                try
                {
                    if (!this.UpdateProperty(property, receiveContext, channelKey, bookmarkName, state))
                    {
                        return(flag);
                    }
                    if (handler == null)
                    {
                        handler = delegate(object sender, EventArgs e) {
                            lock (this.thisLock)
                            {
                                if (this.bufferedProperties.ContainsKey(instanceKey) && this.bufferedProperties[instanceKey].Remove(property))
                                {
                                    try
                                    {
                                        property.RequestContext.DelayClose(false);
                                        property.RequestContext.Abort();
                                    }
                                    catch (Exception exception)
                                    {
                                        if (Fx.IsFatal(exception))
                                        {
                                            throw;
                                        }
                                    }
                                    this.throttle.Release(channelKey);
                                }
                            }
                        };
                    }
                    receiveContext.Faulted += handler;
                    lock (this.thisLock)
                    {
                        if (receiveContext.State != ReceiveContextState.Received)
                        {
                            return(flag);
                        }
                        bool flag2 = false;
                        if (retry)
                        {
                            property.RequestContext.DelayClose(true);
                            property.RegisterForReplay(operationContext);
                            property.ReplayRequest();
                            property.Notification.NotifyInvokeReceived(property.RequestContext.InnerRequestContext);
                            flag2 = true;
                        }
                        else
                        {
                            ReadOnlyCollection <BookmarkInfo> bookmarksForInstance = this.host.DurableInstanceManager.PersistenceProviderDirectory.GetBookmarksForInstance(instanceKey);
                            if (bookmarksForInstance != null)
                            {
                                for (int i = 0; i < bookmarksForInstance.Count; i++)
                                {
                                    BookmarkInfo info = bookmarksForInstance[i];
                                    if (info.BookmarkName == bookmarkName)
                                    {
                                        property.RequestContext.DelayClose(true);
                                        property.RegisterForReplay(operationContext);
                                        property.ReplayRequest();
                                        property.Notification.NotifyInvokeReceived(property.RequestContext.InnerRequestContext);
                                        flag2 = true;
                                        break;
                                    }
                                }
                            }
                        }
                        if (!flag2)
                        {
                            List <BufferedReceiveMessageProperty> list;
                            if (!this.bufferedProperties.TryGetValue(instanceKey, out list))
                            {
                                list = new List <BufferedReceiveMessageProperty>();
                                this.bufferedProperties.Add(instanceKey, list);
                            }
                            property.RequestContext.DelayClose(true);
                            property.RegisterForReplay(operationContext);
                            list.Add(property);
                        }
                        else
                        {
                            this.throttle.Release(channelKey);
                        }
                        return(true);
                    }
                }
                finally
                {
                    if (!flag)
                    {
                        this.throttle.Release(channelKey);
                    }
                }
            }
            return(flag);
        }