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
- Single.cs
- TraceFilter.cs
- FixedSOMPage.cs
- LinqDataView.cs
- DuplicateWaitObjectException.cs
- EnumValAlphaComparer.cs
- ResXFileRef.cs
- StringDictionary.cs
- DbDataAdapter.cs
- Vector.cs
- XmlSchemaSimpleContentRestriction.cs
- WorkflowWebService.cs
- CompressStream.cs
- TextServicesManager.cs
- FileChangesMonitor.cs
- BitVec.cs
- UpdatePanelTrigger.cs
- NonClientArea.cs
- DebugManager.cs
- bindurihelper.cs
- FormViewPageEventArgs.cs
- ParamArrayAttribute.cs
- DataGridViewRowErrorTextNeededEventArgs.cs
- SafeProcessHandle.cs
- Root.cs
- DesignerAttribute.cs
- XPathParser.cs
- DataFormat.cs
- HighlightComponent.cs
- SystemResourceKey.cs
- TraceEventCache.cs
- GlyphCache.cs
- MDIControlStrip.cs
- KeyGestureConverter.cs
- MergeLocalizationDirectives.cs
- Misc.cs
- CollectionEditor.cs
- DesignerTextWriter.cs
- QilIterator.cs
- ResourceExpressionBuilder.cs
- BinaryNode.cs
- VerificationException.cs
- TCPListener.cs
- DataDesignUtil.cs
- MeasureItemEvent.cs
- cookie.cs
- ImageList.cs
- xdrvalidator.cs
- Win32SafeHandles.cs
- UriSection.cs
- DesignConnection.cs
- UdpSocketReceiveManager.cs
- DecoderFallback.cs
- ParallelTimeline.cs
- ListViewTableRow.cs
- CorrelationManager.cs
- SchemaAttDef.cs
- DataControlPagerLinkButton.cs
- CultureSpecificStringDictionary.cs
- AjaxFrameworkAssemblyAttribute.cs
- FormsAuthenticationUser.cs
- CodeIdentifiers.cs
- tibetanshape.cs
- TripleDESCryptoServiceProvider.cs
- IdentityReference.cs
- DesignerActionListCollection.cs
- StickyNote.cs
- TerminateDesigner.cs
- WebPartEditorApplyVerb.cs
- SendMailErrorEventArgs.cs
- XmlResolver.cs
- XmlValidatingReader.cs
- FutureFactory.cs
- RSACryptoServiceProvider.cs
- Drawing.cs
- XsdBuilder.cs
- TagPrefixInfo.cs
- SqlInternalConnectionSmi.cs
- UrlRoutingHandler.cs
- SoapIgnoreAttribute.cs
- XmlSchemaSet.cs
- FormatControl.cs
- MemberProjectionIndex.cs
- DiscardableAttribute.cs
- PerformanceCounterPermission.cs
- FixedSOMContainer.cs
- RegexNode.cs
- TextDecorationCollection.cs
- PageBuildProvider.cs
- Types.cs
- SecuritySessionSecurityTokenProvider.cs
- WebPartUtil.cs
- UnsafeNativeMethods.cs
- BitmapMetadata.cs
- CommandID.cs
- GenericsInstances.cs
- EventLogPermissionEntry.cs
- SynchronizedReadOnlyCollection.cs
- PaginationProgressEventArgs.cs
- AdRotator.cs