private void OnCancellationHandlerComplete(NativeActivityContext context, ActivityInstance completedInstance) { CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context)); Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); if (completedInstance.State == ActivityInstanceState.Closed) { Fx.Assert(compensationToken.CompensationState == CompensationState.Canceling, "CompensationParticipant should be in Canceling State"); this.currentCompensationToken.Set(context, new CompensationToken(compensationToken)); if (compensationToken.ExecutionTracker.Count > 0) { context.ScheduleActivity(DefaultConfirmation, new CompletionCallback(this.OnCompensationComplete)); } else { this.InternalOnCompensationComplete(context, compensationExtension, compensationToken); } } }
private void OnMainRootComplete(NativeActivityContext context, Bookmark bookmark, object value) { CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); CompensationTokenData rootHandle = compensationExtension.Get(CompensationToken.RootCompensationId); Fx.Assert(rootHandle != null, "rootToken must be valid"); ActivityInstanceState completionState = (ActivityInstanceState)value; if (completionState == ActivityInstanceState.Closed) { context.ResumeBookmark(compensationExtension.WorkflowConfirmation, new CompensationToken(rootHandle)); } else if (completionState == ActivityInstanceState.Canceled) { context.ResumeBookmark(compensationExtension.WorkflowCompensation, new CompensationToken(rootHandle)); } else if (completionState == ActivityInstanceState.Faulted) { // Do nothing. Neither Compensate nor Confirm. // Remove the bookmark to complete the WorkflowCompensationBehavior execution. context.RemoveBookmark(compensationExtension.WorkflowConfirmation); context.RemoveBookmark(compensationExtension.WorkflowCompensation); } }
private void AppCompletionCleanup(NativeActivityContext context, CompensationExtension compensationExtension, CompensationTokenData compensationToken) { Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); // Remove the token from the parent! if (compensationToken.ParentCompensationId != CompensationToken.RootCompensationId) { CompensationTokenData parentToken = compensationExtension.Get(compensationToken.ParentCompensationId); Fx.Assert(parentToken != null, "parentToken must be valid"); parentToken.ExecutionTracker.Remove(compensationToken); } else { // remove from workflow root... CompensationTokenData parentToken = compensationExtension.Get(CompensationToken.RootCompensationId); Fx.Assert(parentToken != null, "parentToken must be valid"); parentToken.ExecutionTracker.Remove(compensationToken); } compensationToken.RemoveBookmark(context, CompensationBookmarkName.Canceled); compensationToken.RemoveBookmark(context, CompensationBookmarkName.Compensated); // Remove the token from the extension... compensationExtension.Remove(compensationToken.CompensationId); }
private void OnSecondaryRootScheduled(NativeActivityContext context, Bookmark bookmark, object value) { CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); long compensationId = (long)value; CompensationTokenData compensationToken = compensationExtension.Get(compensationId); Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); if (compensationToken.CompensationState == CompensationState.Canceling) { Fx.Assert(compensationToken.BookmarkTable[CompensationBookmarkName.Canceled] == null, "Bookmark should not be already initialized in the bookmark table."); compensationToken.BookmarkTable[CompensationBookmarkName.Canceled] = context.CreateBookmark(new BookmarkCallback(OnCanceledOrCompensated)); compensationExtension.NotifyMessage(context, compensationToken.CompensationId, CompensationBookmarkName.OnCancellation); } else if (compensationToken.CompensationState == CompensationState.Compensating) { Fx.Assert(compensationToken.BookmarkTable[CompensationBookmarkName.Compensated] == null, "Bookmark should not be already initialized in the bookmark table."); compensationToken.BookmarkTable[CompensationBookmarkName.Compensated] = context.CreateBookmark(new BookmarkCallback(OnCanceledOrCompensated)); compensationExtension.NotifyMessage(context, compensationToken.CompensationId, CompensationBookmarkName.OnCompensation); } }
internal CompensationTokenData Get(long compensationId) { CompensationTokenData compensationToken = null; this.CompensationTokenTable.TryGetValue(compensationId, out compensationToken); return(compensationToken); }
private void OnBodyExecutionComplete(NativeActivityContext context, ActivityInstance completedInstance) { CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); CompensationTokenData token = compensationExtension.Get(_currentCompensationId.Get(context)); Fx.Assert(token != null, "CompensationTokenData must be valid"); if (completedInstance.State == ActivityInstanceState.Closed) { token.CompensationState = CompensationState.Completed; if (TD.CompensationStateIsEnabled()) { TD.CompensationState(token.DisplayName, token.CompensationState.ToString()); } if (context.IsCancellationRequested) { token.CompensationState = CompensationState.Compensating; } } else if (completedInstance.State == ActivityInstanceState.Canceled || completedInstance.State == ActivityInstanceState.Faulted) { // we check for faulted as well for one odd case where an exception can be thrown from the body activity itself. token.CompensationState = CompensationState.Canceling; } else { Fx.Assert(false, "completedInstance in unexpected state"); } ScheduleSecondaryRoot(context, compensationExtension, token); }
private void ScheduleSecondaryRoot(NativeActivityContext context, CompensationExtension compensationExtension, CompensationTokenData token) { if (token.ParentCompensationId != CompensationToken.RootCompensationId) { CompensationTokenData parentToken = compensationExtension.Get(token.ParentCompensationId); Fx.Assert(parentToken != null, "parentToken must be valid"); parentToken.ExecutionTracker.Add(token); } else { CompensationTokenData parentToken = compensationExtension.Get(CompensationToken.RootCompensationId); Fx.Assert(parentToken != null, "parentToken must be valid"); parentToken.ExecutionTracker.Add(token); } // If we are going to Cancel, don't set the out arg... if (Result != null && token.CompensationState == CompensationState.Completed) { Result.Set(context, _currentCompensationToken.Get(context)); } Fx.Assert(token.BookmarkTable[CompensationBookmarkName.OnSecondaryRootScheduled] == null, "Bookmark should not be already initialized in the bookmark table."); token.BookmarkTable[CompensationBookmarkName.OnSecondaryRootScheduled] = context.CreateBookmark(new BookmarkCallback(OnSecondaryRootScheduled)); _compensationId.Set(context, token.CompensationId); context.ScheduleSecondaryRoot(CompensationParticipant, context.Environment); }
private void InternalExecute(NativeActivityContext context, ActivityInstance completedInstance) { CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); if (compensationExtension == null) { throw CoreWf.Internals.FxTrace.Exception.AsError(new InvalidOperationException(SR.CompensateWithoutCompensableActivity(this.DisplayName))); } CompensationToken token = Target.Get(context); CompensationTokenData tokenData = token == null ? null : compensationExtension.Get(token.CompensationId); Fx.Assert(tokenData != null, "CompensationTokenData must be valid"); if (tokenData.ExecutionTracker.Count > 0) { if (_onChildCompensated == null) { _onChildCompensated = new CompletionCallback(InternalExecute); } _toCompensateToken.Set(context, new CompensationToken(tokenData.ExecutionTracker.Get())); Fx.Assert(Body != null, "Body must be valid"); context.ScheduleActivity(Body, _onChildCompensated); } }
private void OnExceptionFromHandler(NativeActivityFaultContext context, Exception propagatedException, ActivityInstance propagatedFrom) { CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context)); Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); InvalidOperationException exception = null; switch (compensationToken.CompensationState) { case CompensationState.Confirming: exception = new InvalidOperationException(SR.ConfirmationHandlerFatalException(compensationToken.DisplayName), propagatedException); break; case CompensationState.Compensating: exception = new InvalidOperationException(SR.CompensationHandlerFatalException(compensationToken.DisplayName), propagatedException); break; case CompensationState.Canceling: exception = new InvalidOperationException(SR.CancellationHandlerFatalException(compensationToken.DisplayName), propagatedException); break; default: Fx.Assert(false, "CompensationState is in unexpected state!"); break; } context.Abort(exception); }
protected override void Execute(NativeActivityContext context) { CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); if (compensationExtension == null) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CompensateWithoutCompensableActivity(this.DisplayName))); } if (Target.IsEmpty) { CompensationToken ambientCompensationToken = (CompensationToken)context.Properties.Find(CompensationToken.PropertyName); CompensationTokenData ambientTokenData = ambientCompensationToken == null ? null : compensationExtension.Get(ambientCompensationToken.CompensationId); if (ambientTokenData != null && ambientTokenData.IsTokenValidInSecondaryRoot) { this.currentCompensationToken.Set(context, ambientCompensationToken); if (ambientTokenData.ExecutionTracker.Count > 0) { context.ScheduleActivity(DefaultCompensation); } } else { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.InvalidCompensateActivityUsage(this.DisplayName))); } } else { CompensationToken compensationToken = Target.Get(context); CompensationTokenData tokenData = compensationToken == null ? null : compensationExtension.Get(compensationToken.CompensationId); if (compensationToken == null) { throw FxTrace.Exception.Argument("Target", SR.InvalidCompensationToken(this.DisplayName)); } if (compensationToken.CompensateCalled) { // No-Op return; } if (tokenData == null || tokenData.CompensationState != CompensationState.Completed) { throw FxTrace.Exception.AsError(new InvalidOperationException(SR.CompensableActivityAlreadyConfirmedOrCompensated)); } // A valid in-arg was passed... tokenData.CompensationState = CompensationState.Compensating; compensationToken.CompensateCalled = true; context.ScheduleActivity(InternalCompensate); } }
private void ScheduleBody(NativeActivityContext context, CompensationExtension compensationExtension) { Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); CompensationToken parentToken = null; long parentCompensationId = CompensationToken.RootCompensationId; parentToken = (CompensationToken)context.Properties.Find(CompensationToken.PropertyName); if (parentToken != null) { if (compensationExtension.Get(parentToken.CompensationId).IsTokenValidInSecondaryRoot) { throw CoreWf.Internals.FxTrace.Exception.AsError(new InvalidOperationException(SR.NoCAInSecondaryRoot)); } parentCompensationId = parentToken.CompensationId; } CompensationTokenData tokenData = new CompensationTokenData(compensationExtension.GetNextId(), parentCompensationId) { CompensationState = CompensationState.Active, DisplayName = this.DisplayName, }; CompensationToken token = new CompensationToken(tokenData); context.Properties.Add(CompensationToken.PropertyName, token); _currentCompensationId.Set(context, token.CompensationId); _currentCompensationToken.Set(context, token); compensationExtension.Add(token.CompensationId, tokenData); if (TD.CompensationStateIsEnabled()) { TD.CompensationState(tokenData.DisplayName, tokenData.CompensationState.ToString()); } if (this.Body != null) { context.ScheduleActivity(this.Body, new CompletionCallback(OnBodyExecutionComplete)); } else { //empty body case. Assume the body has completed successfully tokenData.CompensationState = CompensationState.Completed; if (TD.CompensationStateIsEnabled()) { TD.CompensationState(tokenData.DisplayName, tokenData.CompensationState.ToString()); } ScheduleSecondaryRoot(context, compensationExtension, tokenData); } }
private void OnCompensationComplete(NativeActivityContext context, ActivityInstance completedInstance) { CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context)); Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); InternalOnCompensationComplete(context, compensationExtension, compensationToken); }
internal Bookmark FindBookmark(long compensationId, CompensationBookmarkName bookmarkName) { CompensationTokenData compensationToken = null; Bookmark bookmark = null; if (this.CompensationTokenTable.TryGetValue(compensationId, out compensationToken)) { bookmark = compensationToken.BookmarkTable[bookmarkName]; } return(bookmark); }
private void OnConfirmationComplete(NativeActivityContext context, ActivityInstance completedInstance) { Fx.Assert(context != null, "context must be valid"); Fx.Assert(completedInstance != null, "completedInstance must be valid"); CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); CompensationTokenData compensationToken = compensationExtension.Get(this.compensationId.Get(context)); Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); if (completedInstance.State == ActivityInstanceState.Closed) { compensationExtension.NotifyMessage(context, compensationToken.CompensationId, CompensationBookmarkName.Confirmed); } }
// Successfully received Confirmed response. private void OnConfirmed(NativeActivityContext context, Bookmark bookmark, object value) { CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); CompensationToken compensationToken = Target.Get(context); Fx.Assert(compensationToken != null, "compensationToken must be valid"); // The compensationToken should be a valid one at this point. Ensure its validated in Confirm activity. CompensationTokenData tokenData = compensationExtension.Get(compensationToken.CompensationId); Fx.Assert(tokenData != null, "The compensationToken should be a valid one at this point. Ensure its validated in Confirm activity."); tokenData.CompensationState = CompensationState.Confirmed; if (TD.CompensationStateIsEnabled()) { TD.CompensationState(tokenData.DisplayName, tokenData.CompensationState.ToString()); } // Remove the token from the parent! if (tokenData.ParentCompensationId != CompensationToken.RootCompensationId) { CompensationTokenData parentToken = compensationExtension.Get(tokenData.ParentCompensationId); Fx.Assert(parentToken != null, "parentToken must be valid"); parentToken.ExecutionTracker.Remove(tokenData); } else { // remove from workflow root... CompensationTokenData parentToken = compensationExtension.Get(CompensationToken.RootCompensationId); Fx.Assert(parentToken != null, "parentToken must be valid"); parentToken.ExecutionTracker.Remove(tokenData); } tokenData.RemoveBookmark(context, CompensationBookmarkName.Confirmed); // Remove the token from the extension... compensationExtension.Remove(compensationToken.CompensationId); }
private void OnCancellation(NativeActivityContext context, Bookmark bookmark, object value) { CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); long compensationId = (long)value; Fx.Assert(compensationId != CompensationToken.RootCompensationId, "CompensationId must be passed when resuming the Completed bookmark"); CompensationTokenData compensationToken = compensationExtension.Get(compensationId); Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); Fx.Assert(compensationToken.CompensationState == CompensationState.Canceling, "CompensationState should be in Canceling state"); if (TD.CompensationStateIsEnabled()) { TD.CompensationState(compensationToken.DisplayName, compensationToken.CompensationState.ToString()); } // remove bookmarks. compensationToken.RemoveBookmark(context, CompensationBookmarkName.OnCompensation); compensationToken.RemoveBookmark(context, CompensationBookmarkName.OnConfirmation); this.currentCompensationToken.Set(context, new CompensationToken(compensationToken)); if (CancellationHandler != null) { context.ScheduleActivity(CancellationHandler, new CompletionCallback(this.OnCancellationHandlerComplete), new FaultCallback(OnExceptionFromHandler)); } else { if (compensationToken.ExecutionTracker.Count > 0) { context.ScheduleActivity(DefaultCompensation, new CompletionCallback(this.OnCompensationComplete)); } else { this.InternalOnCompensationComplete(context, compensationExtension, compensationToken); } } }
protected override void Execute(NativeActivityContext context) { CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); CompensationToken compensationToken = Target.Get(context); Fx.Assert(compensationToken != null, "compensationToken must be valid"); // The compensationToken should be a valid one at this point. Ensure its validated in Confirm activity. CompensationTokenData tokenData = compensationExtension.Get(compensationToken.CompensationId); Fx.Assert(tokenData != null, "The compensationToken should be a valid one at this point. Ensure its validated in Confirm activity."); Fx.Assert(tokenData.BookmarkTable[CompensationBookmarkName.Confirmed] == null, "Bookmark should not be already initialized in the bookmark table."); tokenData.BookmarkTable[CompensationBookmarkName.Confirmed] = context.CreateBookmark(new BookmarkCallback(OnConfirmed)); tokenData.CompensationState = CompensationState.Confirming; compensationExtension.NotifyMessage(context, tokenData.CompensationId, CompensationBookmarkName.OnConfirmation); }
protected override void Execute(NativeActivityContext context) { CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); long compensationId = this.compensationId.Get(context); Fx.Assert(compensationId != CompensationToken.RootCompensationId, "CompensationId passed to the SecondaryRoot must be valid"); CompensationTokenData compensationToken = compensationExtension.Get(compensationId); Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); CompensationToken token = new CompensationToken(compensationToken); this.currentCompensationToken.Set(context, token); compensationToken.IsTokenValidInSecondaryRoot = true; context.Properties.Add(CompensationToken.PropertyName, token); Fx.Assert(compensationToken.BookmarkTable[CompensationBookmarkName.OnConfirmation] == null, "Bookmark should not be already initialized in the bookmark table."); compensationToken.BookmarkTable[CompensationBookmarkName.OnConfirmation] = context.CreateBookmark(new BookmarkCallback(OnConfirmation)); Fx.Assert(compensationToken.BookmarkTable[CompensationBookmarkName.OnCompensation] == null, "Bookmark should not be already initialized in the bookmark table."); compensationToken.BookmarkTable[CompensationBookmarkName.OnCompensation] = context.CreateBookmark(new BookmarkCallback(OnCompensation)); Fx.Assert(compensationToken.BookmarkTable[CompensationBookmarkName.OnCancellation] == null, "Bookmark should not be already initialized in the bookmark table."); compensationToken.BookmarkTable[CompensationBookmarkName.OnCancellation] = context.CreateBookmark(new BookmarkCallback(OnCancellation)); Bookmark onSecondaryRootScheduled = compensationToken.BookmarkTable[CompensationBookmarkName.OnSecondaryRootScheduled]; Fx.Assert(onSecondaryRootScheduled != null, "onSecondaryRootScheduled bookmark must be already registered."); compensationToken.BookmarkTable[CompensationBookmarkName.OnSecondaryRootScheduled] = null; context.ResumeBookmark(onSecondaryRootScheduled, compensationId); }
private void OnConfirm(NativeActivityContext context, Bookmark bookmark, object value) { CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); CompensationToken rootToken = (CompensationToken)value; Fx.Assert(rootToken != null, "rootToken must be passed"); _currentCompensationToken.Set(context, rootToken); CompensationTokenData rootTokenData = compensationExtension.Get(rootToken.CompensationId); if (rootTokenData.ExecutionTracker.Count > 0) { context.ScheduleActivity(DefaultConfirmation, new CompletionCallback(OnConfirmationComplete)); } else { OnConfirmationComplete(context, null); } }
private void OnCanceledOrCompensated(NativeActivityContext context, Bookmark bookmark, object value) { CompensationExtension compensationExtension = context.GetExtension <CompensationExtension>(); Fx.Assert(compensationExtension != null, "CompensationExtension must be valid"); long compensationId = (long)value; CompensationTokenData compensationToken = compensationExtension.Get(compensationId); Fx.Assert(compensationToken != null, "CompensationTokenData must be valid"); switch (compensationToken.CompensationState) { case CompensationState.Canceling: compensationToken.CompensationState = CompensationState.Canceled; break; case CompensationState.Compensating: compensationToken.CompensationState = CompensationState.Compensated; break; default: break; } if (TD.CompensationStateIsEnabled()) { TD.CompensationState(compensationToken.DisplayName, compensationToken.CompensationState.ToString()); } AppCompletionCleanup(context, compensationExtension, compensationToken); // Mark the activity as canceled. context.MarkCanceled(); }
public void Add(CompensationTokenData compensationToken) { this.executionOrderedList.Insert(0, compensationToken); }
public void Remove(CompensationTokenData compensationToken) { this.executionOrderedList.Remove(compensationToken); }
private void InternalOnCompensationComplete(NativeActivityContext context, CompensationExtension compensationExtension, CompensationTokenData compensationToken) { switch (compensationToken.CompensationState) { case CompensationState.Canceling: compensationExtension.NotifyMessage(context, compensationToken.CompensationId, CompensationBookmarkName.Canceled); break; case CompensationState.Compensating: compensationExtension.NotifyMessage(context, compensationToken.CompensationId, CompensationBookmarkName.Compensated); break; default: Fx.Assert(false, "CompensationState is in unexpected state!"); break; } }
internal void Add(long compensationId, CompensationTokenData compensationToken) { Fx.Assert(compensationToken != null, "compensationToken must be valid"); this.CompensationTokenTable[compensationId] = compensationToken; }
internal CompensationToken(CompensationTokenData tokenData) { this.CompensationId = tokenData.CompensationId; }