Gridify With Session
This example contains HelloWorld example that is using @Gridify ![]()
String 'Hello World' is passed as an argument to GridifyHelloWorldSessionExample.sayIt(String) method. Since this method is annotated with @Gridify ![]()
- Print out their own argument, which in this case will be a single word from 'Hello World' string.
- Wait for the other job to set its argument as an attribute into session.
- Concatenate all session attributes (which in this case are all job arguments) into one string and print it out.
Note that GridifyHelloWorldSessionExample.sayIt(String) method is called twice on every node. Once to print out its own argument, and then once again to print out all session attributes. One of the potential outcomes could look as following:
| Output >>> |
Package:
org.gridgain.examples.helloworld.gridify.session
There are two classes implemented for this example:
AspectJ AOP Configuration
We will use AspectJ AOP for this example. To use other AOP implementations (such as JBoss AOP, or Spring AOP), refer to AOP Configuration documentation.
The following configuration needs to be applied to enable AspectJ byte code weaving.
- JVM configuration should include: -javaagent:[GRIDGAIN_HOME]/libs/aspectjweaver-1.5.3.jar
- Classpath should contain the [GRIDGAIN_HOME]/config/aop/aspectj folder.
Running Grid Node
This example will need one remote node to be running. 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 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. It takes 2-3 seconds for grid node to start and if everything worked fine you should see starting log ending with successful start acknowledgment.
GridifyHelloWorldSessionExample.java
1. Import GridGain classes.
import org.gridgain.grid.*; import org.gridgain.grid.gridify.*;
2. Add Grid Start and Stop.
GridFactory.start();
try {
...
}
finally {
GridFactory.stop(true);
}
finally clause allows for graceful grid shutdown in case of the exceptions.
3. Add @Gridify Annotation.
Method grid-enabled with @Gridify ![]()
@Gridify(taskClass = GridifyHelloWorldSessionTask.class, timeout = 3000) public static void sayIt(String arg) { // Simply print out the argument. System.out.println(">>>"); System.out.println(">>> Printing '" + arg + "' on this node from grid-enabled method."); System.out.println(">>>"); return phrase.length(); }
Full Source Code
package org.gridgain.examples.helloworld.gridify.session; import org.gridgain.grid.*; import org.gridgain.grid.gridify.*; import org.gridgain.grid.gridify.aop.spring.*; public final class GridifyHelloWorldSessionExample { /** * Ensure singleton. */ private GridifyHelloWorldSessionExample() { // No-op. } /** * Method grid-enabled with {@link Gridify} annotation. Simply prints * out the argument passed in. Note that in this case instead of * using default task, we provide our own task which will split * the passed in string into separate words to be printed on * remote nodes. * * @param arg String to print. * @return Number of characters in the phrase. */ @Gridify(taskClass = GridifyHelloWorldSessionTask.class, timeout = 3000) public static int sayIt(String phrase) { // Simply print out the argument. System.out.println(">>>"); System.out.println(">>> Printing '" + phrase + "' on this node from grid-enabled method."); System.out.println(">>>"); return phrase.length(); } /** * Execute <tt>HelloWorld</tt> example grid-enabled with * <tt>Gridify</tt> annotation. * * @param args Command line arguments, none required but if provided * first one should point to the Spring configuration file. See * <tt>"examples/config/"</tt> for configuration file examples. * @throws GridException If example execution failed. */ public static void main(String[] args) throws GridException { if (args.length == 0) { GridFactory.start(); } else { GridFactory.start(args[0]); } try { // This method will be executed on a remote grid nodes. int phraseLen = sayIt("Hello World"); System.out.println(">>>"); System.out.println(">>> Finished executing Gridify \"Hello World\" example with task session."); System.out.println(">>> Total number of characters in the phrase is '" + phraseLen + "'."); System.out.println(">>> You should see print out of 'Hello' on one node and 'World' on another node."); System.out.println(">>> Aftewards all nodes should print out all attributes added to session."); System.out.println(">>> Check all nodes for output (this node is also part of the grid)."); System.out.println(">>>"); } finally { GridFactory.stop(true); } } }
GridifyHelloWorldSessionTask.java
1. Import GridGain classes.
import org.gridgain.grid.*; import org.gridgain.grid.gridify.*; import org.gridgain.grid.resources.*;
2. Split Logic.
This is a grid task implementation that is responsible for split and aggregate (a.k.a map/reduce) logic. Note that this implementation uses GridifyTaskSplitAdapter ![]()
This task will split passed in string into separate word and then pass each word into its own job for execution on different nodes. Every job will do the following:
- Execute grid-enabled method with argument passed in.
- Add its argument to the session.
- Wait for other jobs to add their arguments to the session.
- Execute grid-enabled method with all session attributes concatenated into one string as an argument.
Full Source Code
package org.gridgain.examples.helloworld.gridify.session; import java.io.*; import java.util.*; import org.gridgain.grid.*; import org.gridgain.grid.gridify.*; import org.gridgain.grid.resources.*; /** * Grid task for {@link GridifyHelloWorldSessionExample} example. It handles spiting * this example into multiple jobs for execution on remote nodes. * <p> * Every job will do the following: * <ol> * <li>Execute grid-enabled method with argument passed in.</li> * <li>Add its argument to the session.</li> * <li>Wait for other jobs to add their arguments to the session.</li> * <li>Execute grid-enabled method with all session attributes concatenated into one string as an argument.</li> * </ol> */ public class GridifyHelloWorldSessionTask extends GridifyTaskSplitAdapter<Integer> { /** Grid task session will be injected. */ @GridTaskSessionResource private GridTaskSession ses = null; /** * {@inheritDoc} */ @Override protected Collection<? extends GridJob> split(int gridSize, GridifyArgument arg) throws GridException { String[] words = ((String)arg.getMethodParameters()[0]).split(" "); List<GridJobAdapter<String>> jobs = new ArrayList<GridJobAdapter<String>>(words.length); for (String word : words) { jobs.add(new GridJobAdapter<String>(word) { /** Job context will be injected. */ @GridJobContextResource private GridJobContext jobCtx = null; /** * Executes grid-enabled method once with all * session attributes concatenated into string * as an argument and again with passed in argument. */ public Serializable execute() throws GridException { String word = getArgument(); // Set session attribute with value of this job's word. ses.setAttribute(jobCtx.getJobId(), word); try { // Wait for all other jobs within this task to set their attributes on // the session. for (GridJobSibling sibling : ses.getJobSiblings()) { // Waits for attribute with sibling's job ID as a key. if (ses.waitForAttribute(sibling.getJobId()) == null) { throw new GridException("Failed to get session attribute from job: " + sibling.getJobId()); } } } catch (InterruptedException e) { throw new GridException("Got interrupted while waiting for session attributes.", e); } // Create a string containing all attributes set by all jobs // within this task (in this case an argument from every job). StringBuilder msg = new StringBuilder(); // Formatting. msg.append("All session attributes [ "); for (Serializable jobArg : ses.getAttributes().values()) { msg.append(jobArg).append(' '); } // Formatting. msg.append(']'); // For the purpose of example, we simply log session attributes. log.info(msg.toString()); // Execute gridified method again and return the number // characters in the passed in word. return GridifyHelloWorldSessionExample.sayIt(word); } }); } return jobs; } /** * Sums up all characters from all jobs and returns a * total number of characters in the initial phrase. * * @param results Job results. * @return Number of letters for the word passed into * {@link GridifyHelloWorldSessionExample#sayIt(String)} method. * @throws GridException If reduce failed. */ public Integer reduce(List<GridJobResult> results) throws GridException { int totalCharCnt = 0; for (GridJobResult res : results) { // Every job returned a number of letters // for the phrase it was responsible for. Integer charCnt = res.getData(); totalCharCnt += charCnt; } // Account for spaces. For simplicity we assume one space between words. totalCharCnt += results.size() - 1; // Total number of characters in the phrase // passed into task execution. return totalCharCnt; } }
