Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / TransactionBridge / Microsoft / Transactions / Wsat / StateMachines / StateMachineTimers.cs / 1 / StateMachineTimers.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- // This file contains timer logic for WS-AT state machines using System; using System.Diagnostics; using System.Threading; using Microsoft.Transactions.Bridge; using Microsoft.Transactions.Wsat.InputOutput; using Microsoft.Transactions.Wsat.Messaging; using Microsoft.Transactions.Wsat.Protocol; namespace Microsoft.Transactions.Wsat.StateMachines { enum TimerProfile { None, Preparing, Prepared, Replaying, Committing, VolatileOutcomeAssurance, } class TimerInstance { TimerProfile profile; public TimerInstance(TimerProfile profile) { this.profile = profile; } public TimerProfile Profile { get { return this.profile; } } public static readonly TimerInstance Preparing = new TimerInstance(TimerProfile.Preparing); public static readonly TimerInstance Prepared = new TimerInstance(TimerProfile.Prepared); public static readonly TimerInstance Replaying = new TimerInstance(TimerProfile.Replaying); public static readonly TimerInstance Committing = new TimerInstance(TimerProfile.Committing); public static readonly TimerInstance VolatileOutcomeAssurance = new TimerInstance(TimerProfile.VolatileOutcomeAssurance); } abstract partial class StateMachine : ITimerRecipient { public TimeSpan NextNotification { get { return this.timer.NextNotification; } } protected virtual void OnTimer(TimerProfile profile) { // Do nothing } struct TimerState { public TimerInstance Instance; public TimerPolicy Policy; public long Notifications; public bool Active; public TimeSpan CurrentInterval; public TimeSpan NextNotification; } TimerState timer; object timerLock = new object(); public bool StartTimer(TimerProfile profile) { lock (this.timerLock) { // Cancel any existing policy we might have CancelTimer(); if (!ChooseProfile(profile)) { return false; } this.timer.Active = true; this.timer.Notifications = 0; this.timer.CurrentInterval = this.timer.Policy.InitialDelay; this.timer.NextNotification = state.ElapsedTime + this.timer.CurrentInterval; this.state.TimerManager.Add(this, this.timer.Instance); } return true; } public void OnTimerNotification(object token) { TimerInstance instance = (TimerInstance) token; lock (this.timerLock) { // If we were cancelled, discard the notification if (!this.timer.Active) { DebugTrace.Trace(TraceLevel.Verbose, "Notification discarded due to inactive timer"); return; } // If the notification has a different policy, discard it if (!ReferenceEquals(instance, this.timer.Instance)) { DebugTrace.Trace(TraceLevel.Verbose, "Notification discarded due to mismatched policy"); return; } // Increment the number of real notifications received this.timer.Notifications++; if (this.timer.Policy.MaxNotifications == 0 || this.timer.Notifications < this.timer.Policy.MaxNotifications) { if (this.timer.Notifications == 1) { // Use the first interval specified by the policy this.timer.CurrentInterval = this.timer.Policy.NotificationInterval; } else { int increase = this.timer.Policy.IntervalIncreasePercentage; long nextIntervalTicks = this.timer.CurrentInterval.Ticks; nextIntervalTicks += nextIntervalTicks / 100 * increase; if (nextIntervalTicks < 0) { nextIntervalTicks = long.MaxValue - 1; } TimeSpan nextInterval = new TimeSpan(nextIntervalTicks); if (nextInterval > this.timer.Policy.MaxNotificationInterval) { nextInterval = this.timer.Policy.MaxNotificationInterval; } this.timer.CurrentInterval = nextInterval; } this.timer.NextNotification = state.ElapsedTime + this.timer.CurrentInterval; // Re-add the timer to the timer manager state.TimerManager.Add(this, timer.Instance); } else { this.timer.Active = false; // Don't dispatch if this is an extra notification if (this.timer.Notifications > this.timer.Policy.MaxNotifications) { return; } } } // Finally dispatch the notification OnTimer(instance.Profile); } public void CancelTimer() { lock (this.timerLock) { if (this.timer.Active) { if (DebugTrace.Verbose) { DebugTrace.TxTrace(TraceLevel.Verbose, this.enlistment.EnlistmentId, "Removing active timer"); } // Remove ourselves from the timer manager. We may still receive // a notification after making this call. Such is life. this.state.TimerManager.Remove(this); this.timer.Instance = null; this.timer.Active = false; } } } bool ChooseProfile(TimerProfile profile) { bool active = true; switch (profile) { case TimerProfile.Preparing: // We are superior to a participant that has been asked to prepare // When the timer fires, we retry the prepare message ParticipantEnlistment participant = (ParticipantEnlistment)this.enlistment; TimeSpan remaining = participant.TimeoutEstimate - state.ElapsedTime; if (remaining < state.Config.PreparePolicy.InitialDelay) { // There isn't a realistic amount of time remaining on the transaction // for a new prepare retry timer to make sense active = false; } else { this.timer.Instance = TimerInstance.Preparing; this.timer.Policy = state.Config.PreparePolicy; } break; case TimerProfile.Committing: // We are superior to a participant that is in failed to notify. // We keep sending commit messages until we hear a response. this.timer.Instance = TimerInstance.Committing; this.timer.Policy = state.Config.CommitPolicy; break; case TimerProfile.Prepared: // We are subordinate to a coordinator that has not sent us outcome // We are indoubt. We keep sending replay until we hear outcome this.timer.Instance = TimerInstance.Prepared; this.timer.Policy = state.Config.PreparedPolicy; break; case TimerProfile.Replaying: // We are subordinate to a coordinator that has not sent us outcome // We are indoubt. We keep sending prepared until we hear outcome this.timer.Instance = TimerInstance.Replaying; this.timer.Policy = state.Config.ReplayPolicy; break; case TimerProfile.VolatileOutcomeAssurance: // We are superior to a volatile participant to whom we have sent outcome // If we don't hear back from the participant for three minutes, we give up this.timer.Instance = TimerInstance.VolatileOutcomeAssurance; this.timer.Policy = state.Config.VolatileOutcomePolicy; break; default: // An invalid Enum value on this internal code path indicates // a product bug and violates assumptions about // valid values in MSDTC. DiagnosticUtility.FailFast("Invalid TimerProfile"); break; // Keep the compiler happy } return active; } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- AutomationPatternInfo.cs
- SQLDoubleStorage.cs
- WebCodeGenerator.cs
- TextBox.cs
- BinaryReader.cs
- EndpointAddress.cs
- BaseAsyncResult.cs
- DoWorkEventArgs.cs
- mediapermission.cs
- SiteMap.cs
- InternalsVisibleToAttribute.cs
- DelayLoadType.cs
- ResourcePropertyMemberCodeDomSerializer.cs
- WindowsAltTab.cs
- Light.cs
- Cell.cs
- ExpressionNormalizer.cs
- LogicalTreeHelper.cs
- MdiWindowListItemConverter.cs
- PeerApplicationLaunchInfo.cs
- HierarchicalDataSourceDesigner.cs
- XmlnsDictionary.cs
- TickBar.cs
- SqlMetaData.cs
- ObjectCacheSettings.cs
- DnsElement.cs
- AdobeCFFWrapper.cs
- RepeaterDataBoundAdapter.cs
- HtmlUtf8RawTextWriter.cs
- DispatcherExceptionEventArgs.cs
- StandardToolWindows.cs
- DLinqAssociationProvider.cs
- LocatorGroup.cs
- SiteOfOriginContainer.cs
- ExecutedRoutedEventArgs.cs
- HeaderedItemsControl.cs
- PrimitiveSchema.cs
- ComponentConverter.cs
- OleDbException.cs
- Assert.cs
- DomainConstraint.cs
- HttpValueCollection.cs
- DataViewSetting.cs
- Dictionary.cs
- ContractTypeNameElement.cs
- ScaleTransform3D.cs
- ConfigXmlComment.cs
- CachedBitmap.cs
- DurationConverter.cs
- WizardForm.cs
- StringFunctions.cs
- SafeRegistryHandle.cs
- GetPageNumberCompletedEventArgs.cs
- Classification.cs
- PrtTicket_Base.cs
- HttpRuntimeSection.cs
- RegexNode.cs
- DataSvcMapFileSerializer.cs
- SynchronizationContext.cs
- InstanceKeyView.cs
- Win32Native.cs
- PropertyEntry.cs
- SQLMoneyStorage.cs
- RequestQueryParser.cs
- Privilege.cs
- DataSourceControlBuilder.cs
- SqlFunctionAttribute.cs
- XmlSerializerFactory.cs
- CreateRefExpr.cs
- WmpBitmapDecoder.cs
- RequestCacheManager.cs
- ConfigXmlElement.cs
- ColumnHeaderConverter.cs
- StructuralCache.cs
- SessionMode.cs
- _NegotiateClient.cs
- MailMessage.cs
- SimpleBitVector32.cs
- XamlStyleSerializer.cs
- ProxyFragment.cs
- XmlSchemaAttributeGroup.cs
- ScrollChrome.cs
- Label.cs
- ActivityIdHeader.cs
- StylusEditingBehavior.cs
- Point.cs
- WebRequest.cs
- WebPermission.cs
- ButtonBase.cs
- WebServiceClientProxyGenerator.cs
- CodeTypeReference.cs
- ProfileInfo.cs
- XPathNavigator.cs
- DocumentViewer.cs
- ResourceReferenceExpression.cs
- UidManager.cs
- DrawTreeNodeEventArgs.cs
- VirtualDirectoryMapping.cs
- Context.cs
- DataGridViewAutoSizeModeEventArgs.cs