TechDoc: Changing the Class Structure for the Auto Discovery Process

Posted on July 10, 2011



HotForestGreen has an auto-detection process running to assure connections to be re-established when they are broken and new Servers to be found for the Data Streams when the old ones collapse, crash or die.

Creation and refactoring phases

Phase 1: Making it work

Auto Discovery - Phase 1

This first model assumed we wanted to keep a list of found “Hubs” based on the pings we did within the local network.

As the project progressed, the benefits of Hubs turned out to be minimal, as each time we re-connected or connected a SandBox, we would do a network wide scan anyway.

Also, there were too many steps and too many classes involved, leading to spaghetti code with a lot of entanglements which were close to impossible to understand on first sight.

Phase 2: Cleaning up and cutting out the fluff

Phase 2: Cutting out the fluff

In the second phase, I removed the Hub and simplified the model to find and recognize a Server.

There is one Class less and the relationship between objects is more clear.

Once a Hub was found, we would immediately ask it for a Server Manifest. Instead of the Server Manifest registering the ServerConnection to a Hub, we simply registered the ServerConnection to the Sandbox.

Instead of using three different type of connections and protocoles, we would only use two:

  1. The initial ping – Which is the simplest protocol to find a live machine
  2. The ServerConnection – Using Messages to receive the Server Manifest, requesting for an IP address and initializing the Server Side SandBox

Phase 3: Expanding the connection types

Phase 3: Expanding the connection types

As we require to support more (including connections to a remote IP address) than just Local Connections and standard Socket Connections (we also want to support Web Sockets and HTTP calls) I started a third phase: adding ConnectionParameters.

From only a Port and scanning the Local Area Network (LAN), it now needed:

  1. A port – To connect to
  2. An IP Address – Being a static constant: IP_LOCALNETWORK  or any IP online.
  3. The Connecton Type – Being WebSockets, Normal Sockets, HTTP Connections and anything you can imagine.

Explicitly instantiating a specific type of SandBox Connection

I added methods to ConnectionParameters to instantiate the ApplicationSandBox for a specific type of Connection, to reduce coding, to reduce the required knowledge of all involved parameters and combinations you can use and to clarify what options you have when you want to create a SandBox connection.  It also dramatically reduces repetition of actions and the required boilerplate code to create a specific connection.

Introduction of the ServerConnectionManager

As I was unhappy with the role and responsibility of the SandBox in keeping its connections alive I started moving the responsibility to check for connections to a separate Class, called the ServerConnectionManager.

Phase 4: Making it ServerConnection Centric

Phase 4: Making it ServerConnection Centric

Three things happened due to the addition of more conneection options:

  1. Shift of weight away from Application SandBox – As the Framework started as a SandBox Centric system, the added options for specific type of connections moved the weight or importance more and more towards the ServerConnection.
  2. Change in the role of Application SandBox – The role of the Application SandBox started to shift. As stated before, the code inside the SandBox related to keep the connections alive, started to feel more and more misplaced. Where it once instantiated the connection, it now seemed more logical to have the Connection instantiate the Application SandBox.
  3. Reduction of complexity – To maintain the old setup, where the Sandbox carried the responsibility of connecting to Servers and keep those connections alive (by re-wiring when connections got broken) included more and more complex thinking to keep things sane.

The solution was to make the Connection the center of the Auto Connection process.

The steps in the new setup are as follows:

  1. You define and create a Server Connection – Which can run in the Local Area Network, or can point to a specific location.
  2. The Server Connection Object:
    1.  Instantiates the SandBox – Which is stored in a Lookup Table, so if it is already existing, nothing is done and the connection is added
  3. You start ServerConnectionManager – To start the auto-discovery process. If the process is already running, this request is queed and started when the previous scan is done.
  4. The ServerConnectionManager – Is a Singleton object with a heartbeat of 20 seconds. When triggered it will start:
    1. The DisposableNodeScanner – Which will:
      1. Check – Existing active  connections per SandBox if we already have a Connection running in that IP range.
      2. Ping – When connections are broken to all given IP ranges of Local Networks
      3. Try – And establish a Server Connection via the ServerConnection for each responding IP address

By Extending the ServerConnection with the ConnectionParameters we simplify the model and chain of Classes. As each ServerConnection is specifically linked to the Connection Parameters this is a logical step.

Phase 5: Finalizing it

Phase 5: Finalizing it

To extend the ConnectionParameters did not work out as Local Area Connections can run over multiple IP numbers. Therefore one ConnectionParameters object can relate to multiple ServerConnections.

Enter the SandBoxServerConnector: a general purpose definition object in which we can set the type of connection and use to establish and keep connections to all Sandboxes on all Servers.

What changed from the model in Step 3 and 4 is the following:

  1. Sandbox ServerConnector – Is now the central element and abstracts and shields the actual Server Connections
    1. Starts the Server Connection Manager – Via an explicit call made at the end of all configurations
    2. Can instantiate the Appication SandBox – Through local methods, saving you the work of setting the SandBox name again
  2. The Applicaton SandBox – Which was hidden by abstraction
    1. Has become visible again – To use specific methods
    2. Lost its methods to connect to Servers – As this has become the full responsibility of the Server Connection Manager
    3. No longer stores references to Connections – As this is moved to the objects themselves, following my own rules on refactoring

Separately initializing the SandBox

To avoid explicit methods for all types of connections and SandBoxes and to avoid the implementation of all kind of exceptions (we have LAN connections and explicit connections. Then – per connection type – we can request a dominantly WebSocket type connection or a normal one. Then we can ask for public, trusted and secured SandBoxes) we extract the initialization methods for each specific Sandbox.

It adds one extra line of code to your initialization process, which becomes like this (for a standard Socket Connection in our LAN):

// Define the connector
SandBoxServerConnector connector =
     SandBoxServerConnector.standardSocketInLAN("sandBox", 821);

// Initialize a public sandBox called "sandBox"  // on the given port in our connector
connector.initializeOpenPublicSandBox(onconnectedHandler, null);

// Start the Connecton Manager to create the connections

Manual start of the Server Connection Manager

As the Server Connection Manager will do a forced scan of all IP addresses within the range of your LAN connection, we want to reduce the overhead as much as possible.

Initially the scan would be performed automatically on registration of a SandBox.

The disadvantage of this is clear: when you register multiple SandBoxes, multiple scans will be performed, unless some extra mechanism is added to the scanning process – leading to a lot of added complexity and never being completely fail safe.

Instead we use the most simple of solutions:

When you are done creating and registering your SandBoxes, you start the discovery process of the Server Connection Manager.

Posted in: refactoring, techdoc