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);
            }
        }
示例#2
0
        public BookmarkResumptionResult TryGenerateWorkItem(ActivityExecutor executor, bool isExternal, ref Bookmark bookmark, object value, ActivityInstance isolationInstance, out ActivityExecutionWorkItem workItem)
        {
            Bookmark internalBookmark = null;
            BookmarkCallbackWrapper callbackWrapper = null;

            if (!this.TryGetBookmarkFromInternalList(bookmark, out internalBookmark, out callbackWrapper))
            {
                workItem = null;
                return(BookmarkResumptionResult.NotFound);
            }

            bookmark = internalBookmark;
            if (!ActivityUtilities.IsInScope(callbackWrapper.ActivityInstance, isolationInstance))
            {
                workItem = null;

                // We know about the bookmark, but we can't resume it yet
                return(BookmarkResumptionResult.NotReady);
            }

            workItem = callbackWrapper.CreateWorkItem(executor, isExternal, bookmark, value);

            if (!BookmarkOptionsHelper.SupportsMultipleResumes(callbackWrapper.Options))
            {
                // cleanup bookmark on resumption unless the user opts into multi-resume
                Remove(bookmark, callbackWrapper);
            }

            return(BookmarkResumptionResult.Success);
        }