Multiple topology SPIs example
| Segmentation note Before you started reading this example we strongly recommend you to read Segmenting Grid Nodes |
This example shows how different topology SPIs can be used with different tasks. Lets imagine the case when task A should be executed on sub-grid which includes nodes that have attribute A and task B should be mapped only to the nodes with attribute B. This now can be done by properly configured topology SPIs. Of course one can map them properly in runtime by filtering out nodes without attributes but when you decide to change this logic you need to change the code as well and this is very inconvenient. So the best way to assign topology to the task in configuration file.
This example will use two remote nodes one with attribute segment and value A and another one with attribute segment and value B
After you ran this example you should see on node with attribute value A
| Node A Output >>> |
and on node with attribute value B
| Node B Output >>> |
Package:
org.gridgain.examples.topology
There are three classes implemented for this example and three configuration files:
GridSegmentATask.java and GridSegmentBTask.java have different output message the rest code is the same.
Running Grid Node
This example requires two remote nodes to be started: one with nodeA.xml configuration file and another one with nodeB.xml configuration file. Note that you don't need another machine for it - you can start remote node on the same machine you are running example on.
To start a remote node with nodeA.xml configuration file open the terminal window on Linux/Mac OS X or Command Prompt on Windows, change directory to ${GRIDGAIN_HOME}/bin and run the gridgain.{sh|bat} script script with path to the nodeA.xml configuration.
To start a remote node with nodeB.xml configuration file open the terminal window on Linux/Mac OS X or Command Prompt on Windows, change directory to ${GRIDGAIN_HOME}/bin and run the gridgain.{sh|bat} script with path to the nodeB.xml configuration.
It takes 2-3 seconds for grid node to start and if everything worked fine you should see starting log ending with successful start acknowledgement.
GridMultipleTopologyExample.java
1. Import GridGain classes.
import org.gridgain.grid.*;
2. Load master node configuration file and start/stop Grid instance.
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("org/gridgain/examples/topology/master.xml"); // Get configuration from Spring. GridConfiguration cfg = (GridConfiguration)ctx.getBean("grid.cfg", GridConfiguration.class); GridFactory.start(cfg); try { Grid grid = GridFactory.getGrid(); ... } finally { GridFactory.stop(true); }
3. Execute different tasks.
// Execute task on segment "A". GridTaskFuture<Integer> futureA = grid.execute(GridSegmentATask.class, null); // Execute task on segment "B". GridTaskFuture<Integer> futureB = grid.execute(GridSegmentBTask.class, null); // Wait for task completion. futureA.get(); futureB.get();
Source Code (edited)
package org.gridgain.examples.topology; import org.gridgain.grid.*; import org.springframework.context.support.*; public final class GridMultipleTopologyExample { private GridMultipleTopologyExample() { // No-op. } public static void main(String[] args) throws GridException { AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("org/gridgain/examples/topology/master.xml"); // Get configuration from Spring. GridConfiguration cfg = (GridConfiguration)ctx.getBean("grid.cfg", GridConfiguration.class); GridFactory.start(cfg); try { Grid grid = GridFactory.getGrid(); // Execute task on segment "A". GridTaskFuture<Integer> futureA = grid.execute(GridSegmentATask.class, null); // Execute task on segment "B". GridTaskFuture<Integer> futureB = grid.execute(GridSegmentBTask.class, null); // Wait for task completion. futureA.get(); futureB.get(); } finally { GridFactory.stop(true); } } }
GridSegmentATask.java
This task simply prints out message about execution on node with attribute segment and value A.
Choose SPI name to use with the task.
@GridTaskSpis(topologySpi="segA")
Source Code (edited)
package org.gridgain.examples.topology; import java.io.*; import java.util.*; import org.gridgain.grid.*; import org.gridgain.grid.logger.*; import org.gridgain.grid.resources.*; @GridTaskSpis(topologySpi="segA") public class GridSegmentATask extends GridTaskSplitAdapter<String, Integer> { @GridLoggerResource private GridLogger log = null; @Override public Collection<? extends GridJob> split(int gridSize, String arg) throws GridException { return Collections.singletonList(new GridJobAdapter<String>() { @GridInstanceResource private Grid grid = null; public Serializable execute() throws GridException { assert grid != null; String segVal = (String)grid.getLocalNode().getAttribute("segment"); if (segVal == null || segVal.equals("A") == false){ throw new GridException("Wrong node \"segment\" attribute value. Expected \"A\" got " + segVal); } if (log.isInfoEnabled() == true) { log.info(">>>"); log.info(">>> Executing job on node that is from segment A."); log.info(">>>"); } return null; } }); } public Integer reduce(List<GridJobResult> results) { return null; } }
GridSegmentBTask.java
This task simply prints out message about execution on node with attribute segment and value B.
Choose SPI name to use with the task.
@GridTaskSpis(topologySpi="segB")
Source Code (edited)
package org.gridgain.examples.topology; import java.io.*; import java.util.*; import org.gridgain.grid.*; import org.gridgain.grid.logger.*; import org.gridgain.grid.resources.*; @GridTaskSpis(topologySpi="segB") public class GridSegmentBTask extends GridTaskSplitAdapter<String, Integer> { @GridLoggerResource private GridLogger log = null; @Override public Collection<? extends GridJob> split(int gridSize, String arg) throws GridException { return Collections.singletonList(new GridJobAdapter<String>() { /** Injected grid instance. */ private Grid grid = null; public Serializable execute() throws GridException { assert grid != null; String segVal = (String)grid.getLocalNode().getAttribute("segment"); if (segVal == null || segVal.equals("B") == false){ throw new GridException("Wrong node \"segment\" attribute value. Expected \"B\" got " + segVal); } if (log.isInfoEnabled() == true) { log.info(">>>"); log.info(">>> Executing job on node that is from segment B."); log.info(">>>"); } return null; } }); } public Integer reduce(List<GridJobResult> results) { return null; } }
master.xml
Grid master node Spring configuration file that describes two named topology SPIs (segA and segB). Each topology SPI collects nodes with appropriate node attribute named segment and values either A or B
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd"> <description>Main Spring file for grid configuration.</description> <bean id="grid.cfg" class="org.gridgain.grid.GridConfigurationAdapter" scope="singleton"> <property name="topologySpi"> <list> <bean class="org.gridgain.grid.spi.topology.attributes.GridAttributesTopologySpi"> <property name="name" value="segA"/> <property name="attributes"> <map> <entry key="segment" value="A"/> </map> </property> </bean> <bean class="org.gridgain.grid.spi.topology.attributes.GridAttributesTopologySpi"> <property name="name" value="segB"/> <property name="attributes"> <map> <entry key="segment" value="B"/> </map> </property> </bean> </list> </property> </bean> </beans>
nodeA.xml
Node A configuration file. Defines attribute with name segment and value A.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd"> <description>Main Spring file for grid configuration.</description> <bean id="grid.cfg" class="org.gridgain.grid.GridConfigurationAdapter" scope="singleton"> <property name="userAttributes"> <map> <entry key="segment" value="A"/> </map> </property> </bean> </beans>
nodeB.xml
Node B configuration file. Defines attribute with name segment and value B.
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd"> <description>Main Spring file for grid configuration.</description> <bean id="grid.cfg" class="org.gridgain.grid.GridConfigurationAdapter" scope="singleton"> <property name="userAttributes"> <map> <entry key="segment" value="B"/> </map> </property> </bean> </beans>
