JPPF, java, parallel computing, distributed computing, grid computing, parallel, distributed, cluster, grid, cloud, open source, android, .net
JPPF, java, parallel computing, distributed computing, grid computing, parallel, distributed, cluster, grid, cloud, open source, android, .net
JPPF

The open source
grid computing
solution

 Home   About   Features   Download   Documentation   On Github   Forums 

Defining the node connection strategy

From JPPF 6.2 Documentation

Jump to: navigation, search

Contents

Main Page > Customizing JPPF > Node connection strategy


By default, JPPF nodes rely on their configuration to find out the information required to connect to a server: either via UDP multicast discovery when discovery is enabled, or via manually set configuration properties for the server host, port, whether SSL is enabled, etc... This makes it potentially complex to define what the behavior should be when the node fails to connect to a server. For example this does not allow to define which server(s) a node should fail over to in case a server dies or is no longer reacheable via the network.

The connection strategy add-on provides a simple way to specify which server a node shoud connect to and how to react when it fails to do so.

1 The DriverConnectionStrategy interface

The node's strategy to connect to a driver is defined as an implementation of the interface DriverConnectionStrategy, which is defined as follows:

// Defines which parameters should be used to connect to the driver
public interface DriverConnectionStrategy {
  // Get a new connection information, eventually based on the current one
  DriverConnectionInfo nextConnectionInfo(
    DriverConnectionInfo currentInfo, ConnectionContext context);
}

This interface defines a single method which takes two parameters as input, and returns a DriverConnectionInfo object, which encapsulates the information required to connect to a JPPF driver.

The first parameter represents the current connection information, that is, the information that was used for the last connection attempt. When the node connects for the first time, this parameter will be null. This parameter is an instance of the interface DriverConnectionInfo, defined as follows:

public interface DriverConnectionInfo {
  // determine whether secure SSL/TLS connections should be established
  boolean isSecure();

  // get the driver host name or IP address
  String getHost();

  // get the driver port to connect to
  int getPort();

  // whether the heartbeat (recovery) mechanism is enabled
  boolean isRecoveryEnabled();
}

JPPF provides a ready-to-use implementation of this interface with the class JPPFDriverConnectionInfo.

The second parameter represents the context of the connection or reconnection request, basically explaining why the request is made. It could be due to a management request or to an error occurring within the node, or simply the first connection attempt at node startup time. It is designed to help make a decision about which driver to connect to. It is an instance of the class ConnectionContext, defined as:

public class ConnectionContext {
  // get an explanation text for the reconnection
  public String getMessage()

  // get an eventual Throwable that triggered the reconnection
  public Throwable getThrowable()

  // get the reason for the connection or reconnection
  public ConnectionReason getReason()
}


The getReason() method returns a reason code among those defined in the ConnectionReason enum:

public enum ConnectionReason {
  // indicates the first connection attempt when the node starts up
  INITIAL_CONNECTION_REQUEST,
  // a reconnection was requested via the management APIs or admin console
  MANAGEMENT_REQUEST,
  // An error occurred while initializing the class loader connection
  CLASSLOADER_INIT_ERROR,
  // an error occurred while processing a class loader request
  CLASSLOADER_PROCESSING_ERROR,
  // an error occurred during the job channel initialization
  JOB_CHANNEL_INIT_ERROR,
  // an error occurred on the job channel while processing a job
  JOB_CHANNEL_PROCESSING_ERROR,
  // the heartbeat mechanism failed to receive a message from the server
  HEARTBEAT_FAILURE
}

The following example implementation uses a set of driver connection information objects stored in a queue and performs a round-robin selection at each connection request:

public class MyConnectionStrategy implements DriverConnectionStrategy {
  // the queue in which DriverConnectionInfo objects are stored
  private final Queue<DriverConnectionInfo> queue = new LinkedBlockingQueue<>();

  // initialize the set of drivers to connect to
  public MyConnectionStrategy() {
    queue.offer(new JPPFDriverConnectionInfo(false, "192.168.1.11", 11111, false));
    queue.offer(new JPPFDriverConnectionInfo(false, "192.168.1.12", 11111, false));
    queue.offer(new JPPFDriverConnectionInfo(true,  "192.168.1.13", 11443, false));
  }

  @Override
  public DriverConnectionInfo nextConnectionInfo(
    DriverConnectionInfo currentInfo, ConnectionContext context) {
    DriverConnectionInfo info;
    // if the reconnection is requested via management, keep the current driver info
    if ((currentInfo != null) &&
        (context.getReason() == ConnectionReason.MANAGEMENT_REQUEST)) {
      info = currentInfo;
    } else {
      // extract the next info from the queue
      info = queue.poll();
      // put it back at the end of the queue
      queue.offer(info);
    }
    return info;
  }
}
Note: JPPF can also provide access to the node configuration, by passing it to a constructor that takes a single TypedProperties parameter, as in ths example:
public class MyConnectionStrategy implements DriverConnectionStrategy {
  // the node configuration passed to the constructor
  private final TypedProperties configuration;

  public MyConnectionStrategy(TypedProperties configuration) {
    this. configuration =  configuration;
  }

  @Override
  public DriverConnectionInfo nextConnectionInfo(
    DriverConnectionInfo currentInfo, ConnectionContext context) {
    ... 
  }
}

2 Pluging the strategy into the node

Specifying which connection strategy a node should use is done in the node's configuration as follows:

# fully qualified name of a class implementing DriverConnectionStrategy
jppf.server.connection.strategy = test.MyConnectionStrategy

As stated in the comment, the value of the “jppf.server.connection.strategy” property is the fully qualified name of a class implementing DriverConnectionStrategy, which must also have a no-args constructor. If this property is left unspecified, or if the specified class cannot be instantiated, the node will default to an instance of JPPFDefaultConnectionStrategy, which uses the configuration to find out the connection information, either via server discovery or from the manually specified server-related properties.

3 Built-in strategies

3.1 File-based CSV server definitions

In addition to the default JPPFDefaultConnectionStrategy, JPPF provides a connection strategy which reads a list of driver connection information from a CSV file. As in the example above, it will perform a round-robin selection of the drivers to connect to. Additionally, if the specified CSV file is invalid or cannot be read, or none of its entries is valid, it will default to JPPFDefaultConnectionStrategy.

This implementation is named JPPFCsvFileConnectionStrategy and is configured as follows:

# read the driver connection info from a CSV file
jppf.server.connection.strategy = org.jppf.node.connection.JPPFCsvFileConnectionStrategy
# location of the CSV file
jppf.server.connection.strategy.file = /home/me/data/drivers.csv

The file is first looked up in the file system at the specified location, then in the classpath if not found in the file system.

The syntax and format for the entries in the CSV files are as in the following example:

# CSV columns: ssl_enabled, server_host, server_port, recovery_enabled

# server 1
false, 192.168.1.15, 11111, false
# server 2, with recovery enabled
false, 192.168.1.16, 11111, true
# server 3, with SSL enabled
true, 192.168.1.17, 11443, false

Please note that any line starting with a '#' (after trimming) is considered a comment.

3.2 Configuration-based CSV server definitions

JPPFCsvPropertyConnectionStrategy is very similar to JPPFCsvFileConnectionStrategy, with the difference that it takes the values from a single configuration property instead of from a file, with the following format:

jppf.server.connection.strategy.definitions = \
  secure1, host1, port1, recovery_enabled1 | \
  ... | \
  secureN, hostN, portN, recovery_enabledN

where:

  • each connection definition is represented as a group of comma-separated values
  • csv groups are separated with the '|' (pipe) character
  • in each csv group:
    • securei is a boolean value (either 'true' or 'false', case-insensitive) indicating whether SSL/TLS connectivity is enabled. Any value that is not 'true' is interpreted as 'false'.
    • hosti is the host name or ip address of the driver to connect to
    • porti is the port to connect to on the driver host
    • recovery_enabledi determines whether the recovery (heartbeat) mechanism should be enabled for the node
    • if the first character is a '#' then the group is considered a comment and ignored.


Here is an example configuration:

# read the driver connection info from a configuration property
jppf.server.connection.strategy = \
  org.jppf.node.connection.JPPFCsvPropertyConnectionStrategy

# definitions of the server connections
jppf.server.connection.strategy.definitions = \
   # definition for server 1 |\
   false, my.host1.org, 11111, false |\
   # definition for server 2 |\
   true, my.host2.org, 11443, true

Note the multiline syntax that makes the configuration easier to read.

Main Page > Customizing JPPF > Node connection strategy



JPPF Copyright © 2005-2020 JPPF.org Powered by MediaWiki