State.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / TransactionBridge / Microsoft / Transactions / Wsat / StateMachines / State.cs / 1 / State.cs

                            //------------------------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------------------------

// This file contains the base class for all states in all state machines 

using System; 
 
using System.ServiceModel.Channels;
using System.Diagnostics; 
using System.Globalization;
using System.ServiceModel;

using Microsoft.Transactions.Bridge; 
using Microsoft.Transactions.Wsat.Messaging;
using Microsoft.Transactions.Wsat.InputOutput; 
using Microsoft.Transactions.Wsat.Protocol; 

using Fault = Microsoft.Transactions.Wsat.Messaging.Fault; 
using DiagnosticUtility = Microsoft.Transactions.Bridge.DiagnosticUtility;

namespace Microsoft.Transactions.Wsat.StateMachines
{ 
    //
    // States from which non-abstract states should inherit 
    // 

    abstract class InactiveState : State 
    {
        protected InactiveState (ProtocolState state) : base (state) {}
    }
 
    abstract class ActiveState : State
    { 
        protected ActiveState (ProtocolState state) : base (state) {} 
    }
 
    abstract class DecidedState : State
    {
        protected DecidedState (ProtocolState state) : base (state) {}
    } 

    abstract class TerminalState : State 
    { 
        protected TerminalState (ProtocolState state) : base (state) { }
 
        public override void Enter (StateMachine stateMachine)
        {
            base.Enter (stateMachine);
 
            // Clean up any state the state machine is holding open. This may include removing
            // the transaction and its associated resources from all global lookup tables 
            stateMachine.Cleanup(); 
        }
    } 

    abstract class State : IIncomingEventSink
    {
        protected ProtocolState state; 

        protected State (ProtocolState state) 
        { 
            this.state = state;
        } 

        public override string ToString()
        {
            return this.GetType().Name; 
        }
 
        // 
        // Interface
        // 

        public virtual void Enter (StateMachine stateMachine)
        {
            // Do nothing 
        }
 
        public virtual void Leave (StateMachine stateMachine) 
        {
            // Do nothing 
        }

        //
        // Activation events 
        //
 
        public virtual void OnEvent(MsgCreateTransactionEvent e) 
        {
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException()); 
        }

        public virtual void OnEvent(MsgEnlistTransactionEvent e)
        { 
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
        } 
 
        public virtual void OnEvent(TmCreateTransactionResponseEvent e)
        { 
            InvalidTransactionManagerEvent(e);
        }

        public virtual void OnEvent(TmEnlistTransactionResponseEvent e) 
        {
            InvalidTransactionManagerEvent(e); 
        } 

        // 
        // Registration events
        //

        public virtual void OnEvent(MsgRegisterCompletionEvent e) 
        {
            InvalidRegisterCompletionMessage(e); 
        } 

        public virtual void OnEvent(MsgRegisterDurableResponseEvent e) 
        {
            InvalidRegistrationCoordinatorMessage(e);
        }
 
        public virtual void OnEvent(MsgRegisterVolatileResponseEvent e)
        { 
            InvalidRegistrationCoordinatorMessage(e); 
        }
 
        public virtual void OnEvent(MsgRegistrationCoordinatorFaultEvent e)
        {
            // We need the CoordinatorRegistrationFailedFault only
            // for v1.0. For v1.1 we send the default ContextManager.Fault, 
            // which is CannotCreateContext.
            if (this.state.ProtocolVersion == ProtocolVersion.Version10 && 
                e.Coordinator.ContextManager != null) 
            {
                Fault fault = CoordinatorRegistrationFailedFault.CreateFault(e.Fault); 
                e.Coordinator.ContextManager.Fault = fault;
            }

            InvalidFaultEvent(e, e.Coordinator, e.Fault); 
        }
 
        public virtual void OnEvent(MsgRegistrationCoordinatorSendFailureEvent e) 
        {
            // We need the CoordinatorRegistrationFailedFault only 
            // for v1.0. For v1.1 we send the default ContextManager.Fault,
            // which is CannotCreateContext.
            if (this.state.ProtocolVersion == ProtocolVersion.Version10 &&
                e.Coordinator.ContextManager != null) 
            {
                Fault fault = CoordinatorRegistrationFailedFault.CreateFault(null); 
                e.Coordinator.ContextManager.Fault = fault; 
            }
 
            InvalidSendMessageFailureEvent(e, e.Coordinator);
        }

        public virtual void OnEvent(TmRegisterResponseEvent e) 
        {
            InvalidTransactionManagerEvent(e); 
        } 

        public virtual void OnEvent(TmSubordinateRegisterResponseEvent e) 
        {
            InvalidTransactionManagerEvent(e);
        }
 
        public virtual void OnEvent(TmEnlistPrePrepareEvent e)
        { 
            InvalidTransactionManagerEvent(e); 
        }
 
        //
        // Completion events
        //
 
        public virtual void OnEvent(MsgCompletionCommitEvent e)
        { 
            InvalidCompletionMessage(e); 
        }
 
        public virtual void OnEvent(MsgCompletionRollbackEvent e)
        {
            InvalidCompletionMessage(e);
        } 

        public virtual void OnEvent(TmCompletionCommitResponseEvent e) 
        { 
            InvalidTransactionManagerEvent(e);
        } 

        public virtual void OnEvent(TmCompletionRollbackResponseEvent e)
        {
            InvalidTransactionManagerEvent(e); 
        }
 
        // 
        // TwoPhaseCommit
        // 

        public virtual void OnEvent(MsgVolatilePrepareEvent e)
        {
            InvalidVolatileCoordinatorMessage(e); 
        }
 
        public virtual void OnEvent(MsgDurablePrepareEvent e) 
        {
            InvalidDurableCoordinatorMessage(e); 
        }

        public virtual void OnEvent(MsgVolatileCommitEvent e)
        { 
            InvalidVolatileCoordinatorMessage(e);
        } 
 
        public virtual void OnEvent(MsgDurableCommitEvent e)
        { 
            InvalidDurableCoordinatorMessage(e);
        }

        public virtual void OnEvent(MsgVolatileRollbackEvent e) 
        {
            InvalidVolatileCoordinatorMessage(e); 
        } 

        public virtual void OnEvent(MsgDurableRollbackEvent e) 
        {
            InvalidDurableCoordinatorMessage(e);
        }
 
        public virtual void OnEvent(MsgDurableCoordinatorFaultEvent e)
        { 
            InvalidFaultEvent(e, e.Coordinator, e.Fault); 
        }
 
        public void OnEvent(MsgVolatileCoordinatorFaultEvent e)
        {
            InvalidFaultEvent(e, e.VolatileCoordinator, e.Fault);
        } 

        public virtual void OnEvent(MsgDurableCoordinatorSendFailureEvent e) 
        { 
            InvalidSendMessageFailureEvent(e, e.Coordinator);
        } 

        public virtual void OnEvent(MsgVolatileCoordinatorSendFailureEvent e)
        {
            InvalidSendMessageFailureEvent(e, e.VolatileCoordinator); 
        }
 
        public virtual void OnEvent(MsgPreparedEvent e) 
        {
            InvalidParticipantMessage(e); 
        }

        public virtual void OnEvent(MsgAbortedEvent e)
        { 
            InvalidParticipantMessage(e);
        } 
 
        public virtual void OnEvent(MsgReadOnlyEvent e)
        { 
            InvalidParticipantMessage(e);
        }

        public virtual void OnEvent(MsgCommittedEvent e) 
        {
            InvalidParticipantMessage(e); 
        } 

        public virtual void OnEvent(MsgReplayEvent e) 
        {
            InvalidParticipantMessage(e);
        }
 
        public virtual void OnEvent(MsgParticipantFaultEvent e)
        { 
            InvalidParticipantFaultEvent(e, e.Participant); 
        }
 
        public virtual void OnEvent(MsgParticipantSendFailureEvent e)
        {
            InvalidSendMessageFailureEvent(e, e.Participant);
        } 

        public virtual void OnEvent(TmPrePrepareResponseEvent e) 
        { 
            InvalidTransactionManagerEvent(e);
        } 

        public virtual void OnEvent(TmPrepareResponseEvent e)
        {
            InvalidTransactionManagerEvent(e); 
        }
 
        public virtual void OnEvent(TmCommitResponseEvent e) 
        {
            InvalidTransactionManagerEvent(e); 
        }

        public virtual void OnEvent(TmRollbackResponseEvent e)
        { 
            InvalidTransactionManagerEvent(e);
        } 
 
        public virtual void OnEvent(TmSinglePhaseCommitEvent e)
        { 
            InvalidTransactionManagerEvent(e);
        }

        public virtual void OnEvent(TmCommitEvent e) 
        {
            InvalidTransactionManagerEvent(e); 
        } 

        public virtual void OnEvent(TmRollbackEvent e) 
        {
            InvalidTransactionManagerEvent(e);
        }
 
        public virtual void OnEvent(TmParticipantForgetEvent e)
        { 
            InvalidTransactionManagerEvent(e); 
        }
 
        public virtual void OnEvent(TmPrePrepareEvent e)
        {
            InvalidTransactionManagerEvent(e);
        } 

        public virtual void OnEvent(TmPrepareEvent e) 
        { 
            InvalidTransactionManagerEvent(e);
        } 

        public virtual void OnEvent(TmRejoinEvent e)
        {
            InvalidTransactionManagerEvent(e); 
        }
 
        public virtual void OnEvent(TmReplayEvent e) 
        {
            InvalidTransactionManagerEvent(e); 
        }

        public virtual void OnEvent(TmCoordinatorForgetEvent e)
        { 
            InvalidTransactionManagerEvent(e);
        } 
 
        public virtual void OnEvent(TmAsyncRollbackEvent e)
        { 
            InvalidTransactionManagerEvent(e);
        }

        // 
        // Timers
        // 
 
        public virtual void OnEvent(TimerCoordinatorEvent e)
        { 
            InvalidTimerEvent(e);
        }

        public virtual void OnEvent(TimerParticipantEvent e) 
        {
            InvalidTimerEvent(e); 
        } 

        // 
        // Internal events
        //

        public virtual void OnEvent(InternalEnlistSubordinateTransactionEvent e) 
        {
            InvalidInternalEvent(e); 
        } 

        // 
        // Transaction context events
        //

        public virtual void OnEvent(TransactionContextEnlistTransactionEvent e) 
        {
            InvalidInternalEvent(e); 
        } 

        public virtual void OnEvent(TransactionContextCreatedEvent e) 
        {
            InvalidInternalEvent(e);
        }
 
        public virtual void OnEvent(TransactionContextTransactionDoneEvent e)
        { 
            InvalidInternalEvent(e); 
        }
 
        ////////////////////////////
        // Invalid event handling //
        ////////////////////////////
 
        void InvalidEventFailfast (SynchronizationEvent e)
        { 
            string text = string.Format(CultureInfo.InvariantCulture, 
                                        "Failfasting due to unexpected event {0} for state {1}",
                                        e, this); 

            // For some unhandled events, we deliberately FailFast. This function
            // does that work.
            DiagnosticUtility.FailFast(text); 
        }
 
        void InvalidTransactionManagerEvent(SynchronizationEvent e) 
        {
            TraceInvalidEvent(e, true); 
            InvalidEventFailfast(e);
        }

        void InvalidRegisterCompletionMessage(MsgRegisterCompletionEvent e) 
        {
            TraceInvalidEvent(e, false); 
            TryToAbortTransaction(e, e.Completion); 

            if (RegisterParticipantFailureRecord.ShouldTrace) 
            {
                RegisterParticipantFailureRecord.Trace(
                    e.Completion.EnlistmentId,
                    e.Completion.Enlistment.RemoteTransactionId, 
                    ControlProtocol.Completion,
                    e.ParticipantService, 
                    SR.GetString(SR.RegisterFailureInvalidState, e.StateMachine.State.ToString()), 
                    this.state.ProtocolVersion
                    ); 
            }

            state.RegistrationCoordinator.SendFault(e.Result, this.state.Faults.InvalidState);
        } 

        void InvalidRegistrationCoordinatorMessage(MsgRegisterDurableResponseEvent e) 
        { 
            TraceInvalidEvent(e, false);
            TryToAbortTransaction(e, e.Coordinator); 
        }

        void InvalidRegistrationCoordinatorMessage(MsgRegisterVolatileResponseEvent e)
        { 
            TraceInvalidEvent(e, false);
            TryToAbortTransaction(e, e.VolatileCoordinator); 
        } 

        void InvalidCompletionMessage(CompletionParticipantEvent e) 
        {
            TraceInvalidEvent(e, false);
            TryToAbortTransaction(e, e.Completion);
 
            state.CompletionCoordinator.SendFault(e.FaultTo, e.MessageId, this.state.Faults.InvalidState);
        } 
 
        void InvalidParticipantMessage(TwoPhaseCommitParticipantEvent e)
        { 
            TraceInvalidEvent(e, false);
            TryToAbortTransaction(e, e.Participant);

            state.TwoPhaseCommitCoordinator.SendFault(e.FaultTo, e.MessageId, this.state.Faults.InvalidState); 
        }
 
        void InvalidDurableCoordinatorMessage(DurableTwoPhaseCommitCoordinatorEvent e) 
        {
            TraceInvalidEvent(e, false); 
            TryToAbortTransaction(e, e.Coordinator);
            TrySendFault(e, this.state.Faults.InvalidState);
        }
 
        void InvalidVolatileCoordinatorMessage(VolatileTwoPhaseCommitCoordinatorEvent e)
        { 
            TraceInvalidEvent(e, false); 
            TryToAbortTransaction(e, e.VolatileCoordinator);
            TrySendFault(e, this.state.Faults.InvalidState); 
        }

        void InvalidFaultEvent(SynchronizationEvent e, TransactionEnlistment enlistment, MessageFault fault)
        { 
            TraceInvalidEvent(e, false);
            TryToAbortTransaction(e, enlistment); 
        } 

        void InvalidParticipantFaultEvent(SynchronizationEvent e, ParticipantEnlistment participant) 
        {
            TraceInvalidEvent(e, false);
            TryToAbortTransaction(e, participant);
        } 

        void InvalidSendMessageFailureEvent(SynchronizationEvent e, TransactionEnlistment enlistment) 
        { 
            TraceInvalidEvent(e, false);
            TryToAbortTransaction(e, enlistment); 
        }

        void InvalidTimerEvent(SynchronizationEvent e)
        { 
            TraceInvalidEvent(e, true);
            InvalidEventFailfast (e); 
        } 

        void InvalidInternalEvent(SynchronizationEvent e) 
        {
            TraceInvalidEvent(e, true);
            InvalidEventFailfast(e);
        } 

        // 
        // Shared invalid event handling 
        //
 
        protected void TraceInvalidEvent(SynchronizationEvent e, bool fatal)
        {
            // The state machine does the dirty work of handling this
            e.StateMachine.TraceInvalidEvent(e, fatal); 
        }
 
        protected void TrySendAborted(CoordinatorEnlistment coordinator) 
        {
            if (coordinator.CoordinatorProxy != null) 
            {
                state.TwoPhaseCommitParticipant.SendDurableAborted(coordinator);
            }
        } 

        protected void TrySendAborted(VolatileCoordinatorEnlistment coordinator) 
        { 
            if (coordinator.CoordinatorProxy != null)
            { 
                state.TwoPhaseCommitParticipant.SendVolatileAborted(coordinator);
            }
        }
 
        protected void TrySendFault(DurableTwoPhaseCommitCoordinatorEvent e, Fault fault)
        { 
            state.TwoPhaseCommitParticipant.SendFault(e.FaultTo, e.MessageId, fault); 
        }
 
        protected void TrySendFault(VolatileTwoPhaseCommitCoordinatorEvent e, Fault fault)
        {
            state.TwoPhaseCommitParticipant.SendFault(e.FaultTo, e.MessageId, fault);
        } 

        void TryToAbortTransaction(SynchronizationEvent e, TransactionEnlistment enlistment) 
        { 
            // Decide what to do, given our state type
            // Yes, we should use inheritance for this, but it's good to have all the code in one place 
            if (this is InactiveState)
            {
                // This always means that we don't have an enlistment yet, but we may in the future
                // Transition to the aborted state, which will handle aborting if we get an enlistment 
                enlistment.StateMachine.ChangeState(enlistment.StateMachine.AbortedState);
            } 
            else if (this is ActiveState) 
            {
                // Abort the local transaction 
                state.TransactionManagerSend.Rollback(enlistment);

                // Transition to the aborted state
                enlistment.StateMachine.ChangeState(enlistment.StateMachine.AbortedState); 
            }
            else 
            { 
                // We cannot influence the outcome of the transaction.
                // Our caller will send a fault if necessary 
            }
        }

        //////////////////// 
        // Shared methods //
        //////////////////// 
 
        protected void ProcessTmRegisterResponse (TmRegisterResponseEvent e)
        { 
            ParticipantEnlistment participant = e.Participant;
            MsgRegisterEvent source = e.SourceEvent;

            if (e.Status != Status.Success) 
            {
                // Send a fault back to the registrant 
                Fault fault = this.state.Faults.ParticipantTMRegistrationFailed(e.Status); 
                state.RegistrationCoordinator.SendFault(source.Result, fault);
 
                if (RegisterParticipantFailureRecord.ShouldTrace)
                {
                    RegisterParticipantFailureRecord.Trace(
                        participant.EnlistmentId, 
                        participant.Enlistment.RemoteTransactionId,
                        participant.ControlProtocol, 
                        participant.ParticipantProxy.To, 
                        SR.GetString(SR.PplCreateSubordinateEnlistmentFailed, e.Status.ToString()),
                        this.state.ProtocolVersion 
                        );
                }

                // It is worth noting that we don't rollback the transaction at this point 
                // This matches behavior elsewhere in the protocol where we don't rollback
                // when a new participant can't be registered. 
            } 
            else
            { 
                participant.OnParticipantRegistered();

                // Send success response
                state.RegistrationCoordinator.SendRegisterResponse(participant, 
                                                                   source.Result,
                                                                   source.Protocol, 
                                                                   participant.CoordinatorService); 
                if (RegisterParticipantRecord.ShouldTrace)
                { 
                    RegisterParticipantRecord.Trace (
                        participant.EnlistmentId,
                        participant.Enlistment.RemoteTransactionId,
                        participant.ControlProtocol, 
                        participant.ParticipantProxy.To,
                        this.state.ProtocolVersion 
                        ); 
                }
            } 
        }

        protected void ProcessTmAsyncRollback(TmAsyncRollbackEvent e)
        { 
            CoordinatorEnlistment coordinator = (CoordinatorEnlistment)e.Enlistment;
 
            // Tell the TM we aborted 
            coordinator.SetCallback(e.Callback, e.CallbackState);
            state.TransactionManagerSend.Aborted(coordinator); 

            e.StateMachine.ChangeState(state.States.CoordinatorAborted);
        }
 
        protected void SetDurableCoordinatorActive(MsgRegisterDurableResponseEvent e)
        { 
            CoordinatorEnlistment coordinator = e.Coordinator; 
            coordinator.SetCoordinatorProxy(e.Proxy);
 
            coordinator.OnDurableCoordinatorActive();

            if (RegisterCoordinatorRecord.ShouldTrace)
            { 
                RegisterCoordinatorRecord.Trace(
                    coordinator.EnlistmentId, 
                    coordinator.SuperiorContext, 
                    ControlProtocol.Durable2PC,
                    e.Proxy.To, 
                    this.state.ProtocolVersion
                    );
            }
        } 

        protected void EnlistPrePrepare(TmEnlistPrePrepareEvent e) 
        { 
            CoordinatorEnlistment coordinator = e.Coordinator;
            coordinator.OnEnlistPrePrepare(e); 

            // Ask our superior for a volatile pipe
            state.RegistrationParticipant.SendVolatileRegister(coordinator.RegisterVolatileCoordinator);
        } 

        // We received a CCC w/ context and found nothing in the context lookup table 
        // We tried to be superior to DTC. 
        // DTC told us that it already knew about the transaction.
        // We're going to create a dummy enlistment that is subordinate to DTC, 
        // in order to learn about the transaction and send a context back
        protected void ForwardEnlistmentEventToSubordinate(MsgEnlistTransactionEvent e)
        {
            CoordinatorEnlistment coordinator = e.Coordinator; 

            // Give up ownership of the context manager 
            TransactionContextManager contextManager = coordinator.ContextManager; 
            coordinator.ContextManager = null;
 
            ParticipantEnlistment participant = new ParticipantEnlistment(state,
                                                                          coordinator.Enlistment,
                                                                          contextManager);
 
            participant.StateMachine.Enqueue(new InternalEnlistSubordinateTransactionEvent(participant, e));
        } 
 
        // We use the Query* functions for the average elapsed time
        // counters. 
        public static long QueryStartTime()
        {
            return State.QueryTime(-1);
        } 

        public static long QueryStopTime() 
        { 
            return State.QueryTime(0);
        } 

        static long QueryTime(long failureDefault)
        {
            long retval = 0; 
            if (0 == System.ServiceModel.Channels.UnsafeNativeMethods.QueryPerformanceCounter(out retval))
            { 
                retval = failureDefault; 
            }
            return retval; 
        }
    }
}

// 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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK