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
![Network programming in C#, Network Programming in VB.NET, Network Programming in .NET](/images/book.jpg)
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SecurityElement.cs
- cryptoapiTransform.cs
- XmlName.cs
- PageCatalogPart.cs
- ObjectStorage.cs
- TemplateAction.cs
- CodeTypeParameterCollection.cs
- Stack.cs
- DecimalKeyFrameCollection.cs
- X500Name.cs
- SqlStatistics.cs
- Menu.cs
- CompensationParticipant.cs
- ControlSerializer.cs
- CompilationRelaxations.cs
- HttpProfileGroupBase.cs
- HostSecurityManager.cs
- ILGen.cs
- SourceFilter.cs
- MembershipValidatePasswordEventArgs.cs
- DataControlExtensions.cs
- _NegoState.cs
- UpdatableGenericsFeature.cs
- WizardPanel.cs
- WebBrowserBase.cs
- Accessors.cs
- UrlAuthFailureHandler.cs
- Bidi.cs
- CRYPTPROTECT_PROMPTSTRUCT.cs
- ProviderUtil.cs
- RewritingPass.cs
- ConfigDefinitionUpdates.cs
- HTTP_SERVICE_CONFIG_URLACL_KEY.cs
- RegistrationServices.cs
- _ShellExpression.cs
- HandlerBase.cs
- DrawListViewSubItemEventArgs.cs
- XPathNodeIterator.cs
- JoinSymbol.cs
- _UriTypeConverter.cs
- TablePatternIdentifiers.cs
- SnapshotChangeTrackingStrategy.cs
- WebBrowserEvent.cs
- ReachObjectContext.cs
- SHA1Managed.cs
- ReferenceSchema.cs
- TextEmbeddedObject.cs
- ColorConverter.cs
- ConnectivityStatus.cs
- DataSourceControlBuilder.cs
- RefreshPropertiesAttribute.cs
- StylusPointPropertyUnit.cs
- DesignerOptionService.cs
- WpfWebRequestHelper.cs
- SocketConnection.cs
- assertwrapper.cs
- LinearKeyFrames.cs
- Keyboard.cs
- SizeF.cs
- NetCodeGroup.cs
- PersistenceTypeAttribute.cs
- SafeFileHandle.cs
- XPathExpr.cs
- MimeTypeMapper.cs
- StatusBar.cs
- CurrentChangedEventManager.cs
- SoapMessage.cs
- IdleTimeoutMonitor.cs
- DataGridPagerStyle.cs
- SoapBinding.cs
- ModuleConfigurationInfo.cs
- OleDbMetaDataFactory.cs
- BamlLocalizableResource.cs
- EventProvider.cs
- EpmSyndicationContentSerializer.cs
- ImportOptions.cs
- TableItemPattern.cs
- PointLightBase.cs
- X509CertificateTrustedIssuerElementCollection.cs
- ServerType.cs
- Win32.cs
- DataObjectSettingDataEventArgs.cs
- DockProviderWrapper.cs
- RelationshipConverter.cs
- EdmComplexPropertyAttribute.cs
- EmbeddedMailObjectsCollection.cs
- IdentityModelDictionary.cs
- XmlSchemaSimpleTypeUnion.cs
- XmlExceptionHelper.cs
- Stack.cs
- XmlSortKey.cs
- CapabilitiesAssignment.cs
- PageOutputQuality.cs
- SafeCertificateContext.cs
- SchemaTypeEmitter.cs
- XmlFormatWriterGenerator.cs
- MessageQueueCriteria.cs
- ChooseAction.cs
- RefreshEventArgs.cs
- MessageSmuggler.cs