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