internal BookmarkScopeHandle(BookmarkScope bookmarkScope) { this.bookmarkScope = bookmarkScope; if (bookmarkScope != null) { this.bookmarkScope.IncrementHandleReferenceCount(); } }
public void CreateBookmarkScope(NativeActivityContext context) { this.ThrowIfContextIsNullOrDisposed(context); if (this.bookmarkScope != null) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CreateBookmarkScopeFailed)); } this.ThrowIfUninitialized(); this.bookmarkScope = context.CreateBookmarkScope(Guid.Empty, this); this.bookmarkScope.IncrementHandleReferenceCount(); }
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; }
public bool RemoveBookmark(Bookmark bookmark, BookmarkScope scope, ActivityInstance instanceAttemptingRemove) { Fx.Assert(scope != null, "We should never have a null scope."); BookmarkScope lookupScope = scope; if (scope.IsDefault) { lookupScope = this.defaultScope; } BookmarkManager manager; if (this.bookmarkManagers.TryGetValue(lookupScope, out manager)) { return(manager.Remove(bookmark, instanceAttemptingRemove)); } else { return(false); } }
internal void InitializeBookmarkScope(NativeActivityContext context, InstanceKey instanceKey) { Fx.Assert(context != null, "executionContext cannot be null"); Fx.Assert(instanceKey != null, "instanceKey cannot be null"); if (context.GetExtension <SendReceiveExtension>() != null) { if (this.InstanceKey != null && this.InstanceKey.Value != instanceKey.Value) { throw FxTrace.Exception.AsError( new InvalidOperationException(SR.CorrelationHandleInUse(this.InstanceKey.Value, instanceKey.Value))); } this.InstanceKey = instanceKey; } else { if (this.Scope == null) { this.bookmarkScopeHandle.CreateBookmarkScope(context, instanceKey.Value); this.Scope = this.bookmarkScopeHandle.BookmarkScope; } else { if (this.Scope.IsInitialized) { if (this.Scope.Id != instanceKey.Value) { throw FxTrace.Exception.AsError( new InvalidOperationException(SR.CorrelationHandleInUse(this.Scope.Id, instanceKey.Value))); } } else { this.Scope.Initialize(context, instanceKey.Value); } } } }
private void PurgeBookmark(Bookmark bookmark, BookmarkManager nonScopedBookmarkManager) { BookmarkManager manager = null; if (bookmark.Scope != null) { BookmarkScope lookupScope = bookmark.Scope; if (bookmark.Scope.IsDefault) { lookupScope = _defaultScope; } Fx.Assert(_bookmarkManagers.ContainsKey(bookmark.Scope), "We should have the single bookmark's sub instance registered"); manager = _bookmarkManagers[bookmark.Scope]; } else { manager = nonScopedBookmarkManager; } manager.PurgeSingleBookmark(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 void UnregisterScope(BookmarkScope scope) { if ((this.bookmarkManagers == null) || !this.bookmarkManagers.ContainsKey(scope)) { throw FxTrace.Exception.AsError(new InvalidOperationException(System.Activities.SR.BookmarkScopeNotRegisteredForUnregister)); } if (this.bookmarkManagers[scope].HasBookmarks) { throw FxTrace.Exception.AsError(new InvalidOperationException(System.Activities.SR.BookmarkScopeHasBookmarks)); } this.bookmarkManagers.Remove(scope); if (!scope.IsInitialized) { this.uninitializedScopes.Remove(scope); } else { if (this.keysToDisassociate == null) { this.keysToDisassociate = new List <InstanceKey>(2); } this.keysToDisassociate.Add(new InstanceKey(scope.Id)); } }
internal BookmarkScope CreateAndRegisterScope(Guid scopeId, BookmarkScopeHandle scopeHandle) { if (_bookmarkManagers == null) { _bookmarkManagers = new Dictionary <BookmarkScope, BookmarkManager>(); } BookmarkScope scope = null; if (scopeId == Guid.Empty) { // // This is the very first activity which started the sub-instance // scope = new BookmarkScope(GetNextTemporaryId()); _bookmarkManagers.Add(scope, new BookmarkManager(scope, scopeHandle)); if (TD.CreateBookmarkScopeIsEnabled()) { TD.CreateBookmarkScope(ActivityUtilities.GetTraceString(scope)); } if (_uninitializedScopes == null) { _uninitializedScopes = new List <BookmarkScope>(); } _uninitializedScopes.Add(scope); } else { // // Try to find one in the existing sub-instances // foreach (BookmarkScope eachScope in _bookmarkManagers.Keys) { if (eachScope.Id.Equals(scopeId)) { scope = eachScope; break; } } // // We did not find one, e.g. the first receive will get the correlation id from the // correlation channel // if (scope == null) { scope = new BookmarkScope(scopeId); _bookmarkManagers.Add(scope, new BookmarkManager(scope, scopeHandle)); if (TD.CreateBookmarkScopeIsEnabled()) { TD.CreateBookmarkScope(string.Format(CultureInfo.InvariantCulture, "Id: {0}", ActivityUtilities.GetTraceString(scope))); } } CreateAssociatedKey(scope); } return(scope); }
public BookmarkResumptionResult TryGenerateWorkItem(ActivityExecutor executor, ref Bookmark bookmark, BookmarkScope scope, object value, ActivityInstance isolationInstance, bool nonScopedBookmarksExist, out ActivityExecutionWorkItem workItem) { Fx.Assert(scope != null, "We should never have a null sub instance."); BookmarkManager manager = null; workItem = null; BookmarkScope lookupScope = scope; if (scope.IsDefault) { lookupScope = _defaultScope; } // We don't really care about the return value since we'll // use null to know we should check uninitialized sub instances _bookmarkManagers.TryGetValue(lookupScope, out manager); if (manager == null) { Fx.Assert(lookupScope != null, "The sub instance should not be default if we are here."); BookmarkResumptionResult finalResult = BookmarkResumptionResult.NotFound; // Check the uninitialized sub instances for a matching bookmark if (_uninitializedScopes != null) { for (int i = 0; i < _uninitializedScopes.Count; i++) { BookmarkScope uninitializedScope = _uninitializedScopes[i]; Fx.Assert(_bookmarkManagers.ContainsKey(uninitializedScope), "We must always have the uninitialized sub instances."); Bookmark internalBookmark; BookmarkCallbackWrapper callbackWrapper; BookmarkResumptionResult resumptionResult; if (!_bookmarkManagers[uninitializedScope].TryGetBookmarkFromInternalList(bookmark, out internalBookmark, out callbackWrapper)) { resumptionResult = BookmarkResumptionResult.NotFound; } else if (IsExclusiveScopeUnstable(internalBookmark)) { resumptionResult = BookmarkResumptionResult.NotReady; } else { resumptionResult = _bookmarkManagers[uninitializedScope].TryGenerateWorkItem(executor, true, ref bookmark, value, isolationInstance, out workItem); } if (resumptionResult == BookmarkResumptionResult.Success) { // We are using InitializeBookmarkScopeWithoutKeyAssociation because we know this is a new uninitialized scope and // the key we would associate is already associated. And if we did the association here, the subsequent call to // FlushBookmarkScopeKeys would try to flush it out, but it won't have the transaction correct so will hang waiting for // the transaction that has the PersistenceContext locked to complete. But it won't complete successfully until // we finish processing here. InitializeBookmarkScopeWithoutKeyAssociation(uninitializedScope, scope.Id); // We've found what we were looking for return(BookmarkResumptionResult.Success); } else if (resumptionResult == BookmarkResumptionResult.NotReady) { // This uninitialized sub-instance has a matching bookmark but // it can't currently be resumed. We won't return BookmarkNotFound // because of this. finalResult = BookmarkResumptionResult.NotReady; } else { if (finalResult == BookmarkResumptionResult.NotFound) { // If we still are planning on returning failure then // we'll incur the cost of seeing if this scope is // stable or not. if (!IsStable(uninitializedScope, nonScopedBookmarksExist)) { // There exists an uninitialized scope which is unstable. // At the very least this means we'll return NotReady since // this uninitialized scope might eventually contain this // bookmark. finalResult = BookmarkResumptionResult.NotReady; } } } } } return(finalResult); } else { Bookmark bookmarkFromList; BookmarkCallbackWrapper callbackWrapper; BookmarkResumptionResult resumptionResult; if (!manager.TryGetBookmarkFromInternalList(bookmark, out bookmarkFromList, out callbackWrapper)) { resumptionResult = BookmarkResumptionResult.NotFound; } else { if (IsExclusiveScopeUnstable(bookmarkFromList)) { resumptionResult = BookmarkResumptionResult.NotReady; } else { resumptionResult = manager.TryGenerateWorkItem(executor, true, ref bookmark, value, isolationInstance, out workItem); } } if (resumptionResult == BookmarkResumptionResult.NotFound) { if (!IsStable(lookupScope, nonScopedBookmarksExist)) { resumptionResult = BookmarkResumptionResult.NotReady; } } return(resumptionResult); } }
bool IsStable(BookmarkScope scope, bool nonScopedBookmarksExist) { Fx.Assert(this.bookmarkManagers.ContainsKey(scope), "The caller should have made sure this scope exists in the bookmark managers dictionary."); if (nonScopedBookmarksExist) { return false; } if (this.bookmarkManagers != null) { foreach (KeyValuePair<BookmarkScope, BookmarkManager> scopeBookmarks in this.bookmarkManagers) { IEquatable<BookmarkScope> comparison = scopeBookmarks.Key; if (!comparison.Equals(scope)) { if (scopeBookmarks.Value.HasBookmarks) { return false; } } } } return true; }
void CreateAssociatedKey(BookmarkScope newScope) { if (this.keysToAssociate == null) { this.keysToAssociate = new List<InstanceKey>(2); } this.keysToAssociate.Add(new InstanceKey(newScope.Id)); }
public BookmarkScope InitializeBookmarkScopeWithoutKeyAssociation(BookmarkScope scope, Guid id) { Fx.Assert(!scope.IsInitialized, "This should have been checked by the caller."); BookmarkScope lookupScope = scope; if (scope.IsDefault) { lookupScope = this.defaultScope; } if (this.uninitializedScopes == null || !this.uninitializedScopes.Contains(lookupScope)) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.BookmarkScopeNotRegisteredForInitialize)); } Fx.Assert(this.bookmarkManagers != null, "This is never null if uninitializedScopes is non-null."); if (this.bookmarkManagers.ContainsKey(new BookmarkScope(id))) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.BookmarkScopeWithIdAlreadyExists(id))); } BookmarkManager bookmarks = this.bookmarkManagers[lookupScope]; this.bookmarkManagers.Remove(lookupScope); this.uninitializedScopes.Remove(lookupScope); long temporaryId = lookupScope.TemporaryId; // We initialize and re-add to our dictionary. We have to // re-add because the hash has changed. lookupScope.Id = id; this.bookmarkManagers.Add(lookupScope, bookmarks); if (TD.BookmarkScopeInitializedIsEnabled()) { TD.BookmarkScopeInitialized(temporaryId.ToString(CultureInfo.InvariantCulture), lookupScope.Id.ToString()); } return lookupScope; }
public ResumeProtocolBookmarkAsyncResult(WorkflowServiceInstance instance, Bookmark bookmark, object value, BookmarkScope bookmarkScope, bool isResumeProtocolBookmark, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.instance = instance; this.bookmark = bookmark; this.value = value; this.bookmarkScope = bookmarkScope; this.timeoutHelper = new TimeoutHelper(timeout); this.nextIdleTimeoutHelper = new TimeoutHelper(instance.serviceHost.FilterResumeTimeout); this.isResumeProtocolBookmark = isResumeProtocolBookmark; base.OnCompleting = onCompleting; Exception exception = null; bool flag = true; try { if (this.isResumeProtocolBookmark) { flag = this.DoResumeBookmark(); } else { flag = this.WaitForInstanceToBeReady(); } } catch (Exception exception2) { if (Fx.IsFatal(exception2)) { throw; } exception = exception2; } if (flag) { base.Complete(true, exception); } }
public ResumeProtocolBookmarkAsyncResult(WorkflowServiceInstance instance, Bookmark bookmark, object value, BookmarkScope bookmarkScope, bool isResumeProtocolBookmark, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.instance = instance; this.bookmark = bookmark; this.value = value; this.bookmarkScope = bookmarkScope; this.timeoutHelper = new TimeoutHelper(timeout); // The value for WorkflowServiceHost.FilterResumeTimeout comes from the AppSetting // "microsoft:WorkflowServices:FilterResumeTimeoutInSeconds" this.nextIdleTimeoutHelper = new TimeoutHelper(instance.serviceHost.FilterResumeTimeout); this.isResumeProtocolBookmark = isResumeProtocolBookmark; this.OnCompleting = onCompleting; Exception completionException = null; bool completeSelf = true; try { if (this.isResumeProtocolBookmark) { completeSelf = DoResumeBookmark(); } else { completeSelf = WaitForInstanceToBeReady(); } } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } completionException = e; } if (completeSelf) { this.Complete(true, completionException); } }
internal BookmarkScopeHandle (BookmarkScope scope) { BookmarkScope = scope; }
public BookmarkResumptionResult TryGenerateWorkItem(ActivityExecutor executor, ref Bookmark bookmark, BookmarkScope scope, object value, System.Activities.ActivityInstance isolationInstance, bool nonScopedBookmarksExist, out ActivityExecutionWorkItem workItem) { BookmarkManager manager = null; Bookmark bookmark3; BookmarkCallbackWrapper wrapper2; BookmarkResumptionResult result3; workItem = null; BookmarkScope key = scope; if (scope.IsDefault) { key = this.defaultScope; } this.bookmarkManagers.TryGetValue(key, out manager); if (manager == null) { BookmarkResumptionResult notFound = BookmarkResumptionResult.NotFound; if (this.uninitializedScopes != null) { for (int i = 0; i < this.uninitializedScopes.Count; i++) { Bookmark bookmark2; BookmarkCallbackWrapper wrapper; BookmarkResumptionResult notReady; BookmarkScope scope3 = this.uninitializedScopes[i]; if (!this.bookmarkManagers[scope3].TryGetBookmarkFromInternalList(bookmark, out bookmark2, out wrapper)) { notReady = BookmarkResumptionResult.NotFound; } else if (this.IsExclusiveScopeUnstable(bookmark2)) { notReady = BookmarkResumptionResult.NotReady; } else { notReady = this.bookmarkManagers[scope3].TryGenerateWorkItem(executor, true, ref bookmark, value, isolationInstance, out workItem); } switch (notReady) { case BookmarkResumptionResult.Success: this.InitializeBookmarkScopeWithoutKeyAssociation(scope3, scope.Id); return(BookmarkResumptionResult.Success); case BookmarkResumptionResult.NotReady: notFound = BookmarkResumptionResult.NotReady; break; default: if ((notFound == BookmarkResumptionResult.NotFound) && !this.IsStable(scope3, nonScopedBookmarksExist)) { notFound = BookmarkResumptionResult.NotReady; } break; } } } return(notFound); } if (!manager.TryGetBookmarkFromInternalList(bookmark, out bookmark3, out wrapper2)) { result3 = BookmarkResumptionResult.NotFound; } else if (this.IsExclusiveScopeUnstable(bookmark3)) { result3 = BookmarkResumptionResult.NotReady; } else { result3 = manager.TryGenerateWorkItem(executor, true, ref bookmark, value, isolationInstance, out workItem); } if ((result3 == BookmarkResumptionResult.NotFound) && !this.IsStable(key, nonScopedBookmarksExist)) { result3 = BookmarkResumptionResult.NotReady; } return(result3); }
public BookmarkScopeManager() { this.defaultScope = this.CreateAndRegisterScope(Guid.Empty); }
public void InitializeScope(BookmarkScope scope, Guid id) { BookmarkScope newScope = this.InitializeBookmarkScopeWithoutKeyAssociation(scope, id); this.CreateAssociatedKey(newScope); }
internal BookmarkManager(BookmarkScope scope, BookmarkScopeHandle scopeHandle) : this() { this.scope = scope; this.scopeHandle = scopeHandle; }
private BookmarkResumptionResult ResumeProtocolBookmarkCore(Bookmark bookmark, object value, BookmarkScope bookmarkScope, bool bufferedReceiveEnabled, ref AsyncWaitHandle waitHandle, ref bool ownsLock) { BookmarkResumptionResult result; if (bookmarkScope == null) { result = base.Controller.ScheduleBookmarkResumption(bookmark, value); } else { result = base.Controller.ScheduleBookmarkResumption(bookmark, value, bookmarkScope); } if ((result == BookmarkResumptionResult.NotReady) && !bufferedReceiveEnabled) { if (waitHandle == null) { waitHandle = new AsyncWaitHandle(); } else { waitHandle.Reset(); } if (this.nextIdleWaiters == null) { this.nextIdleWaiters = new List<AsyncWaitHandle>(); } lock (this.activeOperationsLock) { this.nextIdleWaiters.Add(waitHandle); } this.ReleaseLock(ref ownsLock); } return result; }
public BookmarkResumptionResult ScheduleBookmarkResumption(Bookmark bookmark, object value, BookmarkScope scope) { throw new NotImplementedException(); }
public BookmarkResumptionResult ScheduleBookmarkResumption(Bookmark bookmark, object value, BookmarkScope scope) { bool resetRequired = false; try { this.instance.StartOperation(ref resetRequired); return(this.instance.ScheduleBookmarkResumption(bookmark, value, scope)); } finally { this.instance.FinishOperation(ref resetRequired); } }
public ReadOnlyCollection <BookmarkInfo> GetBookmarks(BookmarkScope scope) { throw new NotImplementedException(); }
public void InitializeScope(BookmarkScope scope, Guid id) { Fx.Assert(!scope.IsInitialized, "This should have been checked by the caller."); BookmarkScope lookupScope = InitializeBookmarkScopeWithoutKeyAssociation(scope, id); CreateAssociatedKey(lookupScope); }
public BookmarkResumptionResult ScheduleBookmarkResumption (Bookmark bookmark,object value,BookmarkScope scope) { throw new NotImplementedException (); }
internal BookmarkScope CreateAndRegisterScope(Guid scopeId, BookmarkScopeHandle scopeHandle) { if (this.bookmarkManagers == null) { this.bookmarkManagers = new Dictionary<BookmarkScope, BookmarkManager>(); } BookmarkScope scope = null; if (scopeId == Guid.Empty) { // // This is the very first activity which started the sub-instance // scope = new BookmarkScope(GetNextTemporaryId()); this.bookmarkManagers.Add(scope, new BookmarkManager(scope, scopeHandle)); if (TD.CreateBookmarkScopeIsEnabled()) { TD.CreateBookmarkScope(ActivityUtilities.GetTraceString(scope)); } if (this.uninitializedScopes == null) { this.uninitializedScopes = new List<BookmarkScope>(); } this.uninitializedScopes.Add(scope); } else { // // Try to find one in the existing sub-instances // foreach (BookmarkScope eachScope in this.bookmarkManagers.Keys) { if (eachScope.Id.Equals(scopeId)) { scope = eachScope; break; } } // // We did not find one, e.g. the first receive will get the correlation id from the // correlation channel // if (scope == null) { scope = new BookmarkScope(scopeId); this.bookmarkManagers.Add(scope, new BookmarkManager(scope, scopeHandle)); if (TD.CreateBookmarkScopeIsEnabled()) { TD.CreateBookmarkScope(string.Format(CultureInfo.InvariantCulture, "Id: {0}", ActivityUtilities.GetTraceString(scope))); } } CreateAssociatedKey(scope); } return scope; }
public ReadOnlyCollection<BookmarkInfo> GetBookmarks (BookmarkScope scope) { throw new NotImplementedException (); }
public void UnregisterScope(BookmarkScope scope) { Fx.Assert(!scope.IsDefault, "Cannot unregister the default sub instance."); if (this.bookmarkManagers == null || !this.bookmarkManagers.ContainsKey(scope)) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.BookmarkScopeNotRegisteredForUnregister)); } if (this.bookmarkManagers[scope].HasBookmarks) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.BookmarkScopeHasBookmarks)); } this.bookmarkManagers.Remove(scope); if (!scope.IsInitialized) { Fx.Assert(this.uninitializedScopes != null && this.uninitializedScopes.Contains(scope), "Something is wrong with our housekeeping."); this.uninitializedScopes.Remove(scope); } else { if (this.keysToDisassociate == null) { this.keysToDisassociate = new List<InstanceKey>(2); } this.keysToDisassociate.Add(new InstanceKey(scope.Id)); Fx.Assert(this.uninitializedScopes == null || !this.uninitializedScopes.Contains(scope), "We shouldn't have this in the uninitialized list."); } }
private BookmarkResumptionResult ScheduleBookmarkResumption(Bookmark bookmark, object value, BookmarkScope scope) { this.ValidateScheduleResumeBookmark(); this.TrackResumed(); return(this.executor.TryResumeBookmark(bookmark, value, scope)); }
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; }
public BookmarkScopeManager() { _nextTemporaryId = 1; _defaultScope = CreateAndRegisterScope(Guid.Empty); }
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); }
internal BookmarkScope EnsureBookmarkScope(NativeActivityContext executionContext) { if (this.Scope == null) { this.Scope = executionContext.DefaultBookmarkScope; } return this.Scope; }
BookmarkResumptionResult ResumeProtocolBookmarkCore(Bookmark bookmark, object value, BookmarkScope bookmarkScope, bool bufferedReceiveEnabled, ref AsyncWaitHandle waitHandle, ref bool ownsLock) { Fx.Assert(this.state == State.Active, "WorkflowServiceInstance.State should be State.Active at this point."); BookmarkResumptionResult result; if (bookmarkScope == null) { result = this.Controller.ScheduleBookmarkResumption(bookmark, value); } else { result = this.Controller.ScheduleBookmarkResumption(bookmark, value, bookmarkScope); } if (result == BookmarkResumptionResult.NotReady && !bufferedReceiveEnabled) { if (waitHandle == null) { waitHandle = new AsyncWaitHandle(); } else { waitHandle.Reset(); } // Creation doesn't require the lock since it is guarded // by the executor lock. if (this.nextIdleWaiters == null) { this.nextIdleWaiters = new List<AsyncWaitHandle>(); } lock (this.activeOperationsLock) { this.nextIdleWaiters.Add(waitHandle); } // We release the lock here so that the workflow will continue to process // until the NextIdle waiters get notified ReleaseLock(ref ownsLock); } return result; }
protected internal virtual Bookmark OnResolveBookmark(WorkflowOperationContext context, out BookmarkScope bookmarkScope, out object value) { Fx.Assert(this.bookmark != null, "bookmark must not be null!"); CorrelationMessageProperty correlationMessageProperty; if (CorrelationMessageProperty.TryGet(context.OperationContext.IncomingMessageProperties, out correlationMessageProperty)) { bookmarkScope = new BookmarkScope(correlationMessageProperty.CorrelationKey.Value); } else { bookmarkScope = BookmarkScope.Default; } value = context; return(this.bookmark); }
public ResumeProtocolBookmarkAsyncResult(WorkflowServiceInstance instance, Bookmark bookmark, object value, BookmarkScope bookmarkScope, bool isResumeProtocolBookmark, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.instance = instance; this.bookmark = bookmark; this.value = value; this.bookmarkScope = bookmarkScope; this.timeoutHelper = new TimeoutHelper(timeout); // we are using default hard coded timeout of 1 minutes this.nextIdleTimeoutHelper = new TimeoutHelper(instance.serviceHost.FilterResumeTimeout); this.isResumeProtocolBookmark = isResumeProtocolBookmark; this.OnCompleting = onCompleting; Exception completionException = null; bool completeSelf = true; try { if (this.isResumeProtocolBookmark) { completeSelf = DoResumeBookmark(); } else { completeSelf = WaitForInstanceToBeReady(); } } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } completionException = e; } if (completeSelf) { this.Complete(true, completionException); } }
public Bookmark CreateBookmark(string name, BookmarkScope scope, BookmarkCallback callback, ActivityInstance owningInstance, BookmarkOptions options) { Fx.Assert(scope != null, "We should never have a null scope."); BookmarkManager manager = null; BookmarkScope lookupScope = scope; if (scope.IsDefault) { lookupScope = this.defaultScope; } if (!this.bookmarkManagers.TryGetValue(lookupScope, out manager)) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.RegisteredBookmarkScopeRequired)); } return manager.CreateBookmark(name, callback, owningInstance, options); }
public IAsyncResult BeginResumeProtocolBookmark(Bookmark bookmark, BookmarkScope bookmarkScope, object value, TimeSpan timeout, AsyncCallback callback, object state) { object bookmarkValue = value; WorkflowOperationContext item = value as WorkflowOperationContext; if (item != null) { if (!item.HasResponse) { lock (this.thisLock) { this.pendingRequests.Add(item); } } bookmarkValue = item.BookmarkValue; } return new ResumeProtocolBookmarkAsyncResult(this, bookmark, bookmarkValue, bookmarkScope, true, timeout, callback, state); }
internal void InitializeBookmarkScope(NativeActivityContext context, InstanceKey instanceKey) { Fx.Assert(context != null, "executionContext cannot be null"); Fx.Assert(instanceKey != null, "instanceKey cannot be null"); if (context.GetExtension<SendReceiveExtension>() != null) { if (this.InstanceKey != null && this.InstanceKey.Value != instanceKey.Value) { throw FxTrace.Exception.AsError( new InvalidOperationException(SR.CorrelationHandleInUse(this.InstanceKey.Value, instanceKey.Value))); } this.InstanceKey = instanceKey; } else { if (this.Scope == null) { this.bookmarkScopeHandle.CreateBookmarkScope(context, instanceKey.Value); this.Scope = this.bookmarkScopeHandle.BookmarkScope; } else { if (this.Scope.IsInitialized) { if (this.Scope.Id != instanceKey.Value) { throw FxTrace.Exception.AsError( new InvalidOperationException(SR.CorrelationHandleInUse(this.Scope.Id, instanceKey.Value))); } } else { this.Scope.Initialize(context, instanceKey.Value); } } } }
public bool RemoveBookmark(Bookmark bookmark, BookmarkScope scope, ActivityInstance instanceAttemptingRemove) { Fx.Assert(scope != null, "We should never have a null scope."); BookmarkScope lookupScope = scope; if (scope.IsDefault) { lookupScope = this.defaultScope; } BookmarkManager manager; if (this.bookmarkManagers.TryGetValue(lookupScope, out manager)) { return manager.Remove(bookmark, instanceAttemptingRemove); } else { return false; } }
public IAsyncResult BeginResumeProtocolBookmark(Bookmark bookmark, BookmarkScope bookmarkScope, object value, TimeSpan timeout, AsyncCallback callback, object state) { Fx.Assert(bookmark != null, "bookmark must not be null!"); object bookmarkValue = value; WorkflowOperationContext context = value as WorkflowOperationContext; if (context != null) { if (!context.HasResponse) { lock (this.thisLock) { this.pendingRequests.Add(context); } } bookmarkValue = context.BookmarkValue; } return new ResumeProtocolBookmarkAsyncResult(this, bookmark, bookmarkValue, bookmarkScope, true, timeout, callback, state); }
public BookmarkResumptionResult TryGenerateWorkItem(ActivityExecutor executor, ref Bookmark bookmark, BookmarkScope scope, object value, ActivityInstance isolationInstance, bool nonScopedBookmarksExist, out ActivityExecutionWorkItem workItem) { Fx.Assert(scope != null, "We should never have a null sub instance."); BookmarkManager manager = null; workItem = null; BookmarkScope lookupScope = scope; if (scope.IsDefault) { lookupScope = this.defaultScope; } // We don't really care about the return value since we'll // use null to know we should check uninitialized sub instances this.bookmarkManagers.TryGetValue(lookupScope, out manager); if (manager == null) { Fx.Assert(lookupScope != null, "The sub instance should not be default if we are here."); BookmarkResumptionResult finalResult = BookmarkResumptionResult.NotFound; // Check the uninitialized sub instances for a matching bookmark if (this.uninitializedScopes != null) { for (int i = 0; i < this.uninitializedScopes.Count; i++) { BookmarkScope uninitializedScope = this.uninitializedScopes[i]; Fx.Assert(this.bookmarkManagers.ContainsKey(uninitializedScope), "We must always have the uninitialized sub instances."); Bookmark internalBookmark; BookmarkCallbackWrapper callbackWrapper; BookmarkResumptionResult resumptionResult; if (!this.bookmarkManagers[uninitializedScope].TryGetBookmarkFromInternalList(bookmark, out internalBookmark, out callbackWrapper)) { resumptionResult = BookmarkResumptionResult.NotFound; } else if (IsExclusiveScopeUnstable(internalBookmark)) { resumptionResult = BookmarkResumptionResult.NotReady; } else { resumptionResult = this.bookmarkManagers[uninitializedScope].TryGenerateWorkItem(executor, true, ref bookmark, value, isolationInstance, out workItem); } if (resumptionResult == BookmarkResumptionResult.Success) { // We are using InitializeBookmarkScopeWithoutKeyAssociation because we know this is a new uninitialized scope and // the key we would associate is already associated. And if we did the association here, the subsequent call to // FlushBookmarkScopeKeys would try to flush it out, but it won't have the transaction correct so will hang waiting for // the transaction that has the PersistenceContext locked to complete. But it won't complete successfully until // we finish processing here. InitializeBookmarkScopeWithoutKeyAssociation(uninitializedScope, scope.Id); // We've found what we were looking for return BookmarkResumptionResult.Success; } else if (resumptionResult == BookmarkResumptionResult.NotReady) { // This uninitialized sub-instance has a matching bookmark but // it can't currently be resumed. We won't return BookmarkNotFound // because of this. finalResult = BookmarkResumptionResult.NotReady; } else { if (finalResult == BookmarkResumptionResult.NotFound) { // If we still are planning on returning failure then // we'll incur the cost of seeing if this scope is // stable or not. if (!IsStable(uninitializedScope, nonScopedBookmarksExist)) { // There exists an uninitialized scope which is unstable. // At the very least this means we'll return NotReady since // this uninitialized scope might eventually contain this // bookmark. finalResult = BookmarkResumptionResult.NotReady; } } } } } return finalResult; } else { Bookmark bookmarkFromList; BookmarkCallbackWrapper callbackWrapper; BookmarkResumptionResult resumptionResult; if (!manager.TryGetBookmarkFromInternalList(bookmark, out bookmarkFromList, out callbackWrapper)) { resumptionResult = BookmarkResumptionResult.NotFound; } else { if (IsExclusiveScopeUnstable(bookmarkFromList)) { resumptionResult = BookmarkResumptionResult.NotReady; } else { resumptionResult = manager.TryGenerateWorkItem(executor, true, ref bookmark, value, isolationInstance, out workItem); } } if (resumptionResult == BookmarkResumptionResult.NotFound) { if (!IsStable(lookupScope, nonScopedBookmarksExist)) { resumptionResult = BookmarkResumptionResult.NotReady; } } return resumptionResult; } }
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 BookmarkScopeManager() { this.nextTemporaryId = 1; this.defaultScope = CreateAndRegisterScope(Guid.Empty); }
BookmarkResumptionResult ScheduleBookmarkResumption(Bookmark bookmark, object value, BookmarkScope scope) { // validate we're in an ok state ValidateScheduleResumeBookmark(); TrackResumed(); return(this.executor.TryResumeBookmark(bookmark, value, scope)); }
public ReadOnlyCollection<BookmarkInfo> GetBookmarks(BookmarkScope scope) { Fx.Assert(scope != null, "We should never be passed null here."); BookmarkManager manager = null; BookmarkScope lookupScope = scope; if (scope.IsDefault) { lookupScope = this.defaultScope; } if (this.bookmarkManagers.TryGetValue(lookupScope, out manager)) { if (!manager.HasBookmarks) { manager = null; } } if (manager != null) { List<BookmarkInfo> bookmarks = new List<BookmarkInfo>(); manager.PopulateBookmarkInfo(bookmarks); return new ReadOnlyCollection<BookmarkInfo>(bookmarks); } else { return null; } }