Click here to Skip to main content
Click here to Skip to main content

Proactor Pattern

By , 2 Feb 2009
 

Introduction

The Proactor Pattern is an asynchronous event handling pattern. This pattern dispatches multiple events from multiple threads to the corresponding event handlers. This allows the application to have multiple operations running simultaneously without requiring the application to have a corresponding number of threads. Besides, it creates a "low coupling" and "high cohesion" between objects or a layered architecture.

Detailed information

Detailed information can be found in this book: Pattern-Oriented Software Architecture (Volume 2).

Background

Some time ago, I implemented the Proactor pattern in C++ (STL), and wondered if I could make this pattern in C# and .NET. Since the .NET framework already provides a set of functionality, it became less time consuming than expected.

Required skills

I'm sure (almost) every programmer could understand this pattern.

However, a set of programming and design skills are required which makes it easier to understand and to use this event handling pattern. Here is the set of skills which makes it easier to understand:

You should know a bit about:

  • Semaphores
  • Singleton Pattern (see the GoF book)
  • Locking shared data which can be accessed from multiple threads
  • Bridge Pattern (GoF)
  • Threads
  • How to realize a "low coupling" and "high cohesion" relationship between objects
  • UML

Don't get daunted by me. It's reasonable, I think...

When to use this pattern?

Use this pattern if:

  • you like to have an asynchronous event handling
  • your objects should independently transport events
  • your events should be delivered with different priority levels
  • you like to realize "low coupling" and "high cohesion" between layers or objects

UML class diagram

This is the class diagram of the Proactor pattern.

The idea of this example is to let the Bird fly (in software, of course). The Bird will receive a FlyEvent from another Bird and will call its "fly away" method.

Main.jpg

  • Dispatcher: the dispatcher dispatches the received events to the Dispatchables.
  • Dispatchable: a Dispatchable object could receive events from the dispatcher.
  • PriorityQueue: this queue contains the enqueued events (ordered in separate priority queues).
  • Registry: contains the registered Dispatchable objects.
  • IDipatchable: the interface to the Dispatchable objects.
  • Bird: the Dispatchable object which will receive asynchronous events from the dispatcher.

Sequence diagrams

Here are the sequence diagrams:

Registering

Register.jpg

Enqueue event

Dispatch Event

Using the Proactor

Here is a set of instructions which must be done before using the Proactor Pattern.

  1. Every object which can receive an event must implement a Dispatchable object and inherit from the IDispatchable.
  2. public class Bird : IDispatchable
    {
        /// <summary>
        /// The dispatchable of the bird.
        /// </summary>
        private Dispatchable _dispatchable = new Dispatchable();

    Why not inherit directly from the Dispatchable object?

    • Reason 1: this is high coupling and low cohesion, which we rather not want.
    • Reason 2: data encapsulation.
  3. You should now implement the methods provided in the IDispatchable interface.
  4. /// <summary>
    /// The handle event of the dispatchable
    /// </summary>
    /// <param name="ievent">the event to handle</param>
    public void HandleEvent(IEvent ievent)
    {
        Debug.Assert(ievent != null);
    
        if (ievent is FlyEvent)
        {
  5. Register the IDispatchable at the dispatcher (the Bird does this in its constructor).
  6. /// <summary>
    /// Constructor
    /// </summary>
    public Bird()
    {
         // this will register the Bird
          Dispatcher.GetInstance.Register(this);
    }

    What does this Dispatcher do?

    The heart of the Proactor Pattern is the Dispatcher. This Dispatcher dispatches the enqueued events to the registered Dispatchables in a (separate) thread.

    /// <summary>
    /// Dispatches the events to the dispatchable items
    /// </summary>
    private void Dispatch()
    {
          // thread must be running.
          while (_dispachThread.ThreadState == System.Threading.ThreadState.Running)
          {
                // wait for signal
              _autoResetEvent.WaitOne();    
            
              // the queue should have at least one queue item available
              if( _queue.Count >= 1 )
              {

    The Dispatcher is a Singleton.

    /// <summary>
    /// This method will return the Dispatchers instance
    /// This is a Singleton pattern.
    /// </summary>
    public static Dispatcher GetInstance
    {
       get
       {
            lock (_instanceLock)
            {
                // if the instance exists, then return the
                // already created disptacher
                if (_instance == null)
                {
                      // first time for the singleton
                    _instance = new Dispatcher();
                }
                return _instance;
            }
        }
    }

    Keep in mind that events with a higher priority will be dispatched first. Be careful not to create starvation.

    Example:

    Time x: The Dispatcher’s queue contains 210938 events with priority "Very High".

    Time x + 1 millisecond: A "Very Low" priority event has been enqueued (and no further events will be enqueued).

    Time x + 32365 milliseconds: the Dispatcher's queue still contains 21 events with a priority "Very High".

    The event enqueued at (Time + 1 ms) could be outdated. Don't get disappointed. There are mechanisms to prevent starvation, like a dynamic priority queue. The best part of having your own event handling mechanism is that such problems become suddenly...a challenge.

  7. Get the Dispatcher's instance.
  8. Create an event and enqueue it to the Dispatcher. Decide the priority level of the event to enqueue.
  9. // event fired to the eagle
    FlyEvent fly = new FlyEvent();
    Dispatcher.GetInstance.Enqueue(_eagle.DISPATCHABLE_ID, 
               fly, Dispatcher.Priority.Normal );

Don't do

  1. Do not process too much in the HandleEvent of the Dispatcher.
  2. For the heroes, don’t be pessimistic prematurely.

To be continued

This Proactor Pattern could be extended with multiple patterns. I’ll wait on the responses first before I make a "Part 2" of this Pattern.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

About the Author

Hamed Ebrahimmalek
Software Developer
Netherlands Netherlands
Member
I'm a C++ and C# .Net software engineer.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionUse Double Check Locking Pattern on the Singleton Dispatchermemberwubly19 Dec '12 - 3:57 
The singleton Dispatcher should use the Double Check locking pattern to avoid excessive locks. I.e.,
 
if ( instance == null )
{
lock ( _lock )
{

if ( instance == null )
{
instance = new Dispatcher();
}
}
}
return instance;
AnswerRe: Use Double Check Locking Pattern on the Singleton DispatchermemberHamed Ebrahimmalek6 May '13 - 9:50 
Thank you for your message.
 
The dispatcher does not necessary needs to be Double Checked. Depends whether aggressive locking is taking place. By the way, since the Dispatcher is initialized before it's used by multiple threads, and the Dispatcher exists during the lifetime of the application, we can even remove the lock Wink | ;) I wanted the readers see the critical section clearly.
 
I've learned two lesson from a C++ expert. The first rule of optimization is "don’t do it". The second rule is "don’t do it yet". Measure twice, optimize once.
 
Read this article first http://www.codeproject.com/Articles/33246/Double-Checked-Locking-Optimization before ever thinking of using the Double Checked pattern in combination with Singleton pattern in a multi thread environment where the singleton can be created and destroyed at runtime.
Kind regards,
Hamed

GeneralThe Reactor Pattern using C#memberLuciferUk12 Jun '11 - 7:48 
If you are interested in the Proactor Pattern you might also want to read about the Reactor Pattern, check out this: The Reactor Pattern using C#
 
Cheers
GeneralMy vote of 2memberSana Gang5 Nov '09 - 18:00 
incorrect design
QuestionRe: My vote of 2memberHamed Ebrahimmalek5 Nov '09 - 20:46 
Incorrect design and that's it? Are you scared to explain why or where? Or was it just the feeling you had when you wrote your message...Sana, come on the playground, don't be scared. I love those messages, empty without an impact.
 
Hamed

GeneralNot badmemberDonsw4 Mar '09 - 11:13 
Not bad, worth a bookmark.
 
cheers,
Donsw
My Recent Article : Optimistic Concurrency with C# using the IOC and DI Design Patterns

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 2 Feb 2009
Article Copyright 2009 by Hamed Ebrahimmalek
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid