Windows Service State Publisher

Introduction

ServiceStatePublisher extends the .NET System.ServiceProcess library. The ServiceStatePublisherlibrary introduces the ability to observe or listen for state changes to a Windows Service.

Why create this library extension? To get experience using several design patterns. In particular, this project will incorporate 3 design patterns:

  1. Singleton
  2. State
  3. Observer/Publish-Subscribe

Having been a casual observer of this site for awhile, I know the design patterns topic is one of those religious hotbeds. For me, they represent a nice way to communicate what you’re doing — and if by chance someone recognizes the design pattern…you know, “hey, that’s the fuzzy duck pattern“…then all the better. I don’t take it as criticism or superiority, but rather as a compliment. The observer was excited to recognize something they learned can be used in practice. And, the code was clear enough for them to see the forest through the trees (i.e. beneath the surface of the code). Hopefully, this code will be clear enough. Wink | ;-)

To demonstrate the use of this library, I have constructed the Oracle Service Manager application, found elsewhere on this site. Oracle Service Manager mimics the Microsoft SQL Server Service Manager.

Background

I have listed the references, at the end of this article, from which I derived my work; however, there are many articles on this site, and the Internet, that are excellent sources for the topics covered. Topics covered include the designpatterns identified above as well as .NET Framework topics such as the System.ServiceProcess .NET namespace, delegates, and events.

Problem Analysis

Windows Services are not designed to fire events alerting observers when a service has changed state. This library extension provides a framework to add one or more service observers. For example, if you wanted to create a utility to monitor and control the Oracle Windows services – just like the SQL Server Service Manager – you would need 3 observers: a dialog observer, a tray icon observer, and a timer/polling observer. A change in the state of the server ought to be broadcasted to all listeners, so they can decide if there is any action to take – like updating a user interface.

I have created a project and wrote an article, found elsewhere on CodeProject, for just this purpose – monitoring and controlling Oracle services – it’s called Oracle Service Manager.

Using Design Patterns

There are two primary issues to solve. The first is the state of the service. The operations performed on a service (e.g. Start, Stop, Pause, and Continue) are dependent on the internal state of the service. In other words, a running service can be stopped and, possibly, paused; however it cannot be started or continued. Most of the time, this issue is solved with a big conditional statement. The State pattern puts each branch of the conditional statement in a separate class. [GHJV98]

The second issue concerns notifying interested parties of the change in state. When a running service stops, all parties interested in observing the service should be notified of the new state regardless of whether that party initiated the request. The Observer pattern allows us to notify other objects without making assumptions about who these objects are. In other words, you don’t want these objects tightly coupled. [GHJV98]

Gamma et al, classify both patterns as behavioral. In addition, the two patterns have a relationship to one another in this library. That is, examining the two patterns reveals, the observer pattern means nothing unless the state of a service changes. This implies that the observer pattern has a dependency on the state pattern. Therefore, the observer pattern implementation needs to subclass the state pattern implementation. In short, the observer subject will derive from, or extend, the state context class.

The state pattern declares each state be represented by a concrete class. This introduces a decision of when to allocate and clean up the concrete state objects. Since we are only interested in tracking one service at a time, and we have a limited number of concrete states, we can minimize memory allocations by creating all concrete state objects at startup. This introduces a requirement to ensure and manage a single instance. This problem is solved by a thirdpattern – the Singleton pattern [GHJV98].

Below, I discuss the characteristics of the design pattern implementations. If you are only interested in using this library, your interest will lie in one of two classes: the ServiceContext in the State pattern; or the ServiceSubjectin the Observer pattern.

State Pattern

Figure 1.  Diagram of State Pattern as illustrated in Design Patterns [GHJV98]

The State pattern diagrammed above outlines the participants needed to support the model. The equivalent types needed for the ServiceStatePublisher library are:

Context  ServiceContext.

  • Defines the interface of interest to clients. In other words, as a user of this pattern, this is the class to program against. This class exposes all supported behaviors and properties encapsulated by the ConcreteState classes.
  • Maintains an instance of a ConcreteState subclass that defines the current state
  • Context delegates state-specific requests to the current ConcreteState object†
  • Context passes itself as an argument to the State object handling the request. This lets the State object access the context†
  • Either Context or the ConcreteState subclasses can decide which state succeeds another and under what circumstances†
public class ServiceContext
{
    protected ServiceController _controller;
    protected ServiceState _state;

    public ServiceContext()
    {
        State = ServiceStateUnknown.Instance;
        Controller = null;
    }

    public void Start()
    {
        State.Start( this);
    }

    public void Stop()
    {
        State.Stop( this);
    }

    public void Pause()
    {
        State.Pause( this);
    }

    public void Continue()
    {
        State.Continue( this);
    }
}

State  ServiceState.

  • Defines an interface for encapsulating the behavior associated with a particular state of the Context
  • I did not implement this as an interface because the actual implementation has some important, but not obvious, default behavior. So, instead, I used a public abstract class to indicate this is a base class from which subclasses derive. More importantly, this class cannot be instantiated on its own. Indeed, this class is the base class for the ConcreteState classes discussed below.
  • As a base class, ServiceState is the natural place to put common error logging for each of the subclasses.
  • The important default behavior is the empty body for each virtual function. This means, by default, a call to a method that is not overridden will do nothing. This will ease the burden for each ConcreteState class.
public abstract class ServiceState
{
    public virtual void Start( ServiceContext context) { }
    public virtual void Start( ServiceContext context, string[] args) { }
    public virtual void Stop( ServiceContext context) { }
    public virtual void Pause( ServiceContext context) { }
    public virtual void Continue( ServiceContext context) { }

    …

    protected virtual void LogError( string message, EventLogEntryType entryType)
    {
        if (!EventLog.SourceExists( SSP_SOURCE))
            EventLog.CreateEventSource( SSP_SOURCE, SSP_EVENTLOG);

        EventLog sspLog = new EventLog();
        sspLog.Source = SSP_SOURCE;

        sspLog.WriteEntry( message, entryType);

        sspLog.Close();
    }
}
ConcreteStates ServiceRunningServiceStoppedServicePaused,
ServicePendingStartServicePendingStopServicePendingPause,
ServicePendingContinueServiceStateUnknown
  • Each subclass implements a behavior associated with a state of the Context
  • Each ConcreteState class is derived from ServiceState.
  • Each ConreteState has a one-to-one mapping with the ServiceControllerStatuses in .NET, with one exception.
  • Included is a class to reflect an unknown state, such as when a server or service has not been selected.
  • Because the base class, ServiceState, implements a default behavior, only those methods requiring overrides must be implemented. In other words, the ServiceRunning state need only override the methods that are allowable in that state – Stop() and Pause(). If the client program calls Start() or Continue() when thestate is ServiceRunning, the default behavior is executed – do nothing. This treatment means we do not need to explicitly check for invalid requests, because the invalid request will be dealt with gracefully without error.
public class ServiceRunning : ServiceState
{
    …

    public override void Stop( ServiceContext context)
    {
        try
        {
            context.Controller.Stop();
            context.Controller.WaitForStatus( 
                ServiceControllerStatus.Stopped, new TimeSpan(0,0,30));
            ChangeState( context, ServiceStopped.Instance);
        }
        catch (TimeoutException te)
        {
            LogError( te.Message, EventLogEntryType.Warning);
            throw;
        }
    }

    public override void Pause( ServiceContext context)
    {
        try
            {
            context.Controller.Pause();
            context.Controller.WaitForStatus( 
                ServiceControllerStatus.Paused, new TimeSpan(0,0,30));
            ChangeState( context, ServicePaused.Instance);
        }
        catch (TimeoutException te)
        {
            LogError( te.Message, EventLogEntryType.Warning);
            throw;
        }
    }
}

Observer Pattern

Figure 2.  Diagram of Observer Pattern as illustrated in Design Patterns [GHJV98]

The Observer pattern diagrammed above outlines the participants needed to support the model. The Observerpattern is also known as: Listener and Publish-and-Subscribe. One noteworthy item is how well .NET provides native support for this pattern through built-in functionality found in delegates and events. The equivalent types needed for the ServiceStatePublisher library are:

Subject  Not applicable.

  • Knows its observers. Any number of Observer objects may observe a subject
  • Provides an interface for attaching and detaching Observer objects§ (e.g., in C#, the syntax to attach isobject.event += new EventHandler(); to detach, C# uses the -= operator)
  • .NET provides this functionality through its built-in support of delegates and events
  • The ConcreteSubject establishes this contract through .NET’s event support – see below.

ConcreteSubject ServiceSubject.

  • This is the publisher and defines the interface of interest to clients’. In other words, if you want published events, this is the class you should use, or program against, in your application.
  • Stores state of interest to ConcreteObserver objects§
  • Sends a notification to its observers when its state changes§ (i.e., publishes the event to subscribers)
  • .NET supports this functionality through its built-in support of delegates and events
public class ServiceSubject : ServiceContext
{
    public event EventHandler ServerChanged;
    public event EventHandler ServiceChanged;
    public event EventHandler StateChanged;

    protected string _serverName;

    public ServiceSubject() : base() { }

    public ServiceSubject( ServiceController service)
    {
        Controller = service;
    }

    public virtual string ServerName
    {
        get { return _serverName; }
        set
        {
            _serverName = value;
            OnServerChanged( EventArgs.Empty);
            if (Controller != null && _serverName != Controller.MachineName)
                Controller = null;
        }
    }

    public override ServiceController Controller
    {
        get { return _controller; }
        set
        {
            _controller = value;
            _state = QueryServiceState();
            OnServiceChanged( EventArgs.Empty);
        }
    }

    public override ServiceState State
    {
        get { return _state; }
        set
        {
            _state = value;
            OnStateChanged( EventArgs.Empty);
        }
    }

    public virtual void RefreshServices()
    {
        OnServerChanged( EventArgs.Empty);
    }

    protected virtual void OnServerChanged( System.EventArgs e)
    {
        if (ServerChanged != null)
            ServerChanged( this, e);
    }

    protected virtual void OnServiceChanged( System.EventArgs e)
    {
        if (ServiceChanged != null)
            ServiceChanged( this, e);
    }

    protected virtual void OnStateChanged( System.EventArgs e)
    {
        if (StateChanged != null)
            StateChanged( this, e);
    }
}

Observer Not applicable.

  • Defines an updating interface for objects that should be notified of changes in a subject§
  • .NET provides this functionality through its built-in support of delegates and events

ConcreteObservers Implemented in client application.

  • This is the actual subscriber or listener
  • Maintains a reference to a ConcreteSubject object§
  • Stores state that should stay consistent with the subject’s§
  • Implements the Observer updating interface to keep its state consistent with the subject’s§
  • .NET provides this functionality through its built-in support of delegates and events
  • The observers are implemented in the client application. I created an example, Oracle Service Manager, for some “real” world applicability.
using System;
using System.ServiceProcess;
using kae.ServiceStatePublisher;

public class SampleObserver
{
    public SampleObserver( ServiceSubject subject)
    {
        if (subject != null)
        {
            subject.ServerChanged += new EventHandler( this.OnServerChanged);
            subject.ServiceChanged += new EventHandler( this.OnServiceChanged);
            subject.StateChanged += new EventHandler( this.OnStateChanged);
        }
    }

    private void OnServerChanged( object sender, EventArgs e)
    {
        ServiceSubject subject = (ServiceSubject) sender;
        …
    }

    private void OnServiceChanged( object sender, EventArgs e)
    {
        ServiceSubject subject = (ServiceSubject) sender;
        …
    }

    private void OnStateChanged( object sender, EventArgs e)
    {
        ServiceSubject subject = (ServiceSubject) sender;
        …
    }
}

Singleton Pattern

Figure 3.  Diagram of Singleton Pattern as illustrated in Design Patterns [GHJV98]

The Singleton pattern diagrammed above outlines the sole participant needed to support the model. The Singletonpattern is applied differently depending on whether you need a single instance inside a single process or across multiple processes. In the latter case, an operating system level resource must be used. In the former case, a static constructor can be used to create the one and only instance.

Singleton ServiceRunningServiceStoppedServicePaused
ServicePendingStartServicePendingStopServicePendingPause
ServicePendingContinueServiceStateUnknown
  • Defines an Instance operation that lets clients access its unique instance. Instance is a class operation**
  • Responsible for creating its own unique instance**
  • In C#, we use a static property as the accessor
public class ServiceRunning : ServiceState
{
    private static ServiceRunning _instance;

    static ServiceRunning()
    {
        lock (typeof(ServiceRunning))
        {
            if (_instance == null)
                _instance = new ServiceRunning();
        }
    }

    public static ServiceRunning Instance
    {
        get { return _instance; }
    }

    …
}

Future Directions

As I have mentioned above, the ServiceStatePublisher library is used in a companion article, Oracle Service Manager, as an example application that may have some relevance to your development environment. In addition, using this library for a Visual Studio add-in to manage the Windows Services of any database (e.g., Oracle, DB2, MySQL, SQL Server, etc.) could be a nice alternative to the browsing mechanism offered by the Server Explorer in Visual Studio. Perhaps, there is also an enhancement to ensure changes in state happen in a worker thread, allowing the main thread to be more responsive to the interface.

LINK: http://www.codeproject.com/Articles/7043/Windows-Service-State-Publisher

Understanding and Implementing State Pattern in C#

There are times when we find some scenarios in our application when we need to maintain the state of a sub system. This state needs to be changed based on some conditions and/or user actions. One way to keep track of such states is by using the conditional logic in code.

Using conditional logic will get us the desired result but that would result in a code that is less understandable and is harder to maintain. Also, if we need to add more states in the system then that is very difficult and could create problems in existing system too.

To tackle such problems efficiently, GoF suggest use of State pattern. GoF defines state pattern as “Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

It can also be thought of as an object oriented state machine. Let us see the major classes in this pattern.

  • Context: This is the actual object who is accessed by the client. The state of this object needs to be tracked.
  • State: This is an interface or abstract class that defines the common behavior associated with all the possiblestates of the Context.
  • ConcreteState: This class represent a state of the Context. Each state will be represented as one concrete class.

Using the code

Let us try to implement a small example to understand the state pattern in detail. Let us try to implement the software for a dummy ATM machine. The ATM machine is with us and the Bank has decided to have 3 states for this machine.

  1. No card in the machine
  2. Card inserted and has been validated
  3. Cash withdrawn

Now first let us see how we would implement this solution without using the state pattern. We would create a class for the ATM and then have the state of the ATM maintained locally. Following code snippet shows how we could implement such ATM class and keep the state of the machine inside the object itself.

class NoStateATM
{
    public enum MACHINE_STATE
    {
        NO_CARD,
        CARD_VALIDATED,        
        CASH_WITHDRAWN,
    }

    private MACHINE_STATE currentState = MACHINE_STATE.NO_CARD;
    private int dummyCashPresent = 1000;

    public string GetNextScreen()
    {
        switch (currentState)
        {
            case MACHINE_STATE.NO_CARD:
                // Here we will get the pin validated
                return GetPinValidated();
                break;
            case MACHINE_STATE.CARD_VALIDATED:
                // Lets try to withdraw the money
                return WithdrawMoney();
                break;
            case MACHINE_STATE.CASH_WITHDRAWN:
                // Lets let the user go now
                return SayGoodBye();
                break;            
        }
        return string.Empty;
    }

    private string GetPinValidated()
    {
        Console.WriteLine("Please Enter your Pin");
        string userInput = Console.ReadLine();

        // lets check with the dummy pin
        if (userInput.Trim() == "1234")
        {
            currentState = MACHINE_STATE.CARD_VALIDATED;
            return "Enter the Amount to Withdraw";
        }
            
        // Show only message and no change in state
        return "Invalid PIN";
    }

    private string WithdrawMoney()
    {            
        string userInput = Console.ReadLine();

        int requestAmount;
        bool result = Int32.TryParse(userInput, out requestAmount);

        if (result == true)
        {
            if (dummyCashPresent < requestAmount)
            {
                // Show only message and no change in state
                return "Amount not present";
            }

            dummyCashPresent -= requestAmount;
            currentState = MACHINE_STATE.CASH_WITHDRAWN;

            return string.Format(@"Amount of {0} has been withdrawn. Press Enter to proceed", requestAmount);
        }

        // Show only message and no change in state
        return "Invalid Amount";
    }

    private string SayGoodBye()
    {
        currentState = MACHINE_STATE.NO_CARD;
        return string.Format("Thanks you for using us, Amount left in ATM: {0}", dummyCashPresent.ToString());
    }
}

Now when we run the class we can see that this works perfectly from the functionality perspective.

The problem will come when we need to add more states. Whenever we need to add more states to this ATM machine we need to open up the ATM machine code and then add more logic inside this class itself which is a clear violoation of Open-Close priciple. Also since we have all that state managed in form of conditional logic, there are some possibilities that changing code to add new states will break existing functionality too i.e. this way is more error prone.

So, what would be the better way to do this? The better way to do this is by implementing the same solution usingstate pattern. The only thing that we need to do is “encapsulate what varies”. So we will go ahead and pull the staterelated logic from the ATM class and create seprate classes for each state.

Let us start by modifying the ATM class so that it will contain no state related information. It will only keep an handle to the object which keeps track of its state.

public class ATM
{
    public ATMState currentState = null;        

    public ATM()
    {
        currentState = new NoCardState(1000, this);
    }

    public void StartTheATM()
    {
        while (true)
        {
            Console.WriteLine(currentState.GetNextScreen());
        }
    }
}

Now the member variable in this class that is being used as the handle to the state is just an abstract class. This class will point to the actual concrete implementation of state i.e. the real state of the machine dynamically.

public abstract class ATMState
{
    private ATM atm;

    public ATM Atm
    {
        get { return atm; }
        set { atm = value; }
    }
    private int dummyCashPresent = 1000;

    public int DummyCashPresent
    {
        get { return dummyCashPresent; }
        set { dummyCashPresent = value; }
    }

    public abstract string GetNextScreen();
}

And finally we have all the concrete classes, each for one state of the ATM machine. Lets look at all the state classes now

The class for NO_CARD state:

class NoCardState : ATMState
{
    // This constructor will create new state taking values from old state
    public NoCardState(ATMState state)     
        :this(state.DummyCashPresent, state.Atm)
    {
        
    }

    // this constructor will be used by the other one
    public NoCardState(int amountRemaining, ATM atmBeingUsed)
    {
        this.Atm = atmBeingUsed;
        this.DummyCashPresent = amountRemaining;
    }

    public override string GetNextScreen()
    {            
        Console.WriteLine("Please Enter your Pin");
        string userInput = Console.ReadLine();

        // lets check with the dummy pin
        if (userInput.Trim() == "1234")
        {
            UpdateState();
            return "Enter the Amount to Withdraw";
        }

        // Show only message and no change in state
        return "Invalid PIN";
    }

    private void UpdateState()
    {
        Atm.currentState = new CardValidatedState(this);
    }
}

The class for CARD_VALIDATED state:

class CardValidatedState : ATMState
{
    // This constructor will create new state taking values from old state
    public CardValidatedState(ATMState state)    
        :this(state.DummyCashPresent, state.Atm)
    {
        
    }

    // this constructor will be used by the other one
    public CardValidatedState(int amountRemaining, ATM atmBeingUsed)
    {
        this.Atm = atmBeingUsed;
        this.DummyCashPresent = amountRemaining;
    }

    public override string GetNextScreen()
    {
        string userInput = Console.ReadLine();

        int requestAmount;
        bool result = Int32.TryParse(userInput, out requestAmount);

        if (result == true)
        {
            if (this.DummyCashPresent < requestAmount)
            {
                // Show only message and no change in state
                return "Amount not present";
            }

            this.DummyCashPresent -= requestAmount;
            UpdateState();

            return string.Format(@"Amount of {0} has been withdrawn. Press Enter to proceed", requestAmount);
        }

        // Show only message and no change in state
        return "Invalid Amount";
    }

    private void UpdateState()
    {        
        Atm.currentState = new NoCashState(this);        
    }
}

The class for CASH_WITHDRAWN state:

class CashWithdrawnState : ATMState
{
    // This constructor will create new state taking values from old state
    public CashWithdrawnState(ATMState state)      
        :this(state.DummyCashPresent, state.Atm)
    {
        
    }

    // this constructor will be used by the other one
    public CashWithdrawnState(int amountRemaining, ATM atmBeingUsed)
    {
        this.Atm = atmBeingUsed;
        this.DummyCashPresent = amountRemaining;
    }

    public override string GetNextScreen()
    {
        UpdateState();
        return string.Format("Thanks you for using us, Amount left in ATM: {0}", this.DummyCashPresent.ToString());
    }

    private void UpdateState()
    {
        Atm.currentState = new NoCardState(this);
    }
}

Now with this design we are atually achieving the same functionality that we were achieving in the earlier example. This sure looks like more code but this approach is less error prone and using this approach the ATM class will need no modification. So if we need to add a new state then there will be minimal impact on code of existing state classes. So if I need to add a state for NO_CASH in this system, I just have to add a new concrete class that and hook it with the system.

class NoCashState : ATMState
{
    // This constructor will create new state taking values from old state
    public NoCashState(ATMState state)      
        :this(state.DummyCashPresent, state.Atm)
    {
        
    }

    // this constructor will be used by the other one
    public NoCashState(int amountRemaining, ATM atmBeingUsed)
    {
        this.Atm = atmBeingUsed;
        this.DummyCashPresent = amountRemaining;
    }

    public override string GetNextScreen()
    {            
        Console.WriteLine("ATM is EMPTY");
        Console.ReadLine();
        return string.Empty;
    }

    private void UpdateState()
    {
        // nothing here as someone will have to fill in cash and then
        // restart the atm, once restarted it will be in no card state
    }
}

And a minor modification in the UpdateState function of the CardValidatedState class.

private void UpdateState()
{
    if (this.DummyCashPresent == 0)
    {
        Atm.currentState = new NoCashState(this);
    }
    else
    {
        Atm.currentState = new CashWithdrawnState(this);
    }
}

Now let us test this system.

Before wrapping up let us look at the clas diagram of our application and compare it with the class diagram of GoF.

Point of interest

In this article we tried to get an overviwe of the state pattern and when could it be used. We also implemented as small application that contains a rudimentaty implementation of state pattern.

LINK: http://www.codeproject.com/Articles/489136/UnderstandingplusandplusImplementingplusStateplusP