Dashboard > GridGain User Guide > Table Of Contents > Examples Gallery > HelloWorld - Gridify With State
HelloWorld - Gridify With State
Added by morpheus, last edited by morpheus on Mar 08, 2008  (view change)
Labels: 
(None)


Stateful @Gridify Example

This example contains HelloWorld example that is using Gridify Javadoc annotation to grid-enable Java logic on a stateful GridifyHelloWorld instance. For simplicity the state is a plain Java string. The example code initializes GridifyHelloWorld state with String 'Hello World' and then executes GridifyHelloWorld.sayIt() method. Since this method is annotated with @Gridify Javadoc annotation, it is automatically grid-enabled. The GridifyHelloWorldStateTask task specified in @Gridify Javadoc annotation will do the following:

  1. Properly split the GridifyHelloWorld state into multiple words.
  2. Create a GridJob Javadoc for every word to be executed on remote node.
  3. Every job created on remote node will pre-initialize a new instance of GridifyHelloWorld with state received as an argument.
  4. After state initialization, every job will execute GridifyHelloWorld.sayIt() grid-enabled method on pre-initialized instance.

As an outcome, two participating nodes will print out a single word from 'Hello World' string. One node will print out word "Hello" and the other will print out word "World". If there is only one node participating, then it will print out both words.

Package:
org.gridgain.examples.helloworld.gridify.state

There are three 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.

GridifyHelloWorld.java

This class represents a stateful instance that needs to be executed on Grid. For simplicity the state is a simple Java string. Method GridifyHelloWorld.sayIt() simply prints out the state and returns number of characters in the state string.

Add @Gridify Annotation.

We add @Gridify Javadoc annotation specifying custom task class we use responsible for splitting method execution into sub-jobs and properly initializing the state.

@Gridify(taskClass = GridifyHelloWorldStateTask.class, timeout = 3000)
public void sayIt(String arg) {
    // Simply print out the argument.
    System.out.println(">>>");
    System.out.println(">>> Printing '" + state + "' on this node from grid-enabled method.");
    System.out.println(">>>");

    return state.length();
}

Full Source Code.

GridifyHelloWorld.java
package org.gridgain.examples.helloworld.gridify.state;

import org.gridgain.grid.gridify.*;

public class GridifyHelloWorld {
    /** Example state. */
    private String state = null;

    /**
     * Gets example state.
     *
     * @return Example state.
     */
    public String getState() {
        return state;
    }

    /**
     * Sets example state.
     *
     * @param state Example state.
     */
    public void setState(String state) {
        this.state = state;
    }

    /**
     * Method grid-enabled with {@link Gridify} annotation and will be
     * executed on the grid. Simply prints out the state of this instance.
     *
     * @return Number of characters in the phrase.
     */
    @Gridify(taskClass = GridifyHelloWorldStateTask.class, timeout = 3000)
    public int sayIt() {
        // Simply print out the argument.
        System.out.println(">>>");
        System.out.println(">>> Printing '" + state + "' on this node from grid-enabled method.");
        System.out.println(">>>");

        return state.length();
    }
}

GridifyHelloWorldStateExample.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.

Full Source Code

GridifyHelloWorldStateExample.java
package org.gridgain.examples.helloworld.gridify.state;

import org.gridgain.grid.*;
import org.gridgain.grid.gridify.*;

public final class GridifyHelloWorldStateExample {
    /**
     * Ensure singleton.
     */
    private GridifyHelloWorldBasicExample() {
        // No-op.
    }

    /**
     * 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 {
            // Simple example stateful instance to demonstrate
            // how object state can be handled with grid-enabled methods.
            GridifyHelloWorld hello = new GridifyHelloWorld();

            // Set simple state.
            hello.setState("Hello World");

            // This method is grid-enabled and
            // will be executed on remote grid nodes.
            int phraseLen = hello.sayIt();

            System.out.println(">>>");
            System.out.println(">>> Finished executing Gridify \"Hello World\" stateful example.");
            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(">>> Check all nodes for output (this node is also part of the grid).");
            System.out.println(">>>");
        }
        finally {
            GridFactory.stop(true);
        }
    }
}

GridifyHelloWorldStateTask.java

1. Import GridGain classes.

import org.gridgain.grid.*;
import org.gridgain.grid.gridify.*;

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 Javadoc that simplifies API for grid tasks in homogeneous grids (which is often the case). Main two methods that are implemented here are split and reduce. Method reduce aggregates results (sums up numbers returned by jobs) and thus calculates length of initial string.

This grid task is responsible for the following:

  1. Properly splitting the GridifyHelloWorld state into multiple words.
  2. Creating a GridJob Javadoc for every word to be executed on remote node.
  3. Every job created on remote node will pre-initialize a new instance of GridifyHelloWorld with state received as an argument.
  4. After state initialization, every job will execute GridifyHelloWorld.sayIt() grid-enabled method on pre-initialized instance.

Full Source Code

GridifyHelloWorldStateTask.java
package org.gridgain.examples.helloworld.gridify.state;

import java.io.*;
import java.util.*;
import org.gridgain.grid.*;
import org.gridgain.grid.gridify.*;

/**
 * This grid task is responsible for splitting the string state of
 * {@link GridifyHelloWorld} into separate words and then passing
 * each word into its own grid job as an argument for execution on
 * remote nodes. When job receives such argument on remote node,
 * it will set it as state into new {@link GridifyHelloWorld} instance
 * to prepare the instance for execution and then execute grid-enabled
 * {@link GridifyHelloWorld#sayIt()} method on it.
 */
public class GridifyHelloWorldStateTask extends GridifyTaskSplitAdapter<Integer> {
    /**
     * {@inheritDoc}
     */
    @Override
    protected Collection<? extends GridJob> split(int gridSize, GridifyArgument arg) throws GridException {
        // Get target instance on which grid-enabled method was invoked.
        GridifyHelloWorld hello = (GridifyHelloWorld)arg.getTarget();

        // Split internal string state of GridifyHelloWorld into separate words.
        String[] words = hello.getState().split(" ");

        List<GridJobAdapter<String>> jobs = new ArrayList<GridJobAdapter<String>>(words.length);

        for (String word : words) {
            // Every job gets its own word as an argument.
            jobs.add(new GridJobAdapter<String>(word) {
                /*
                 * Simply executes 'GridifyHelloWorld#sayIt(String)' method
                 * with passed in state.
                 */
                public Serializable execute() throws GridException {
                    GridifyHelloWorld hello = new GridifyHelloWorld();

                    // Initialize GridifyHelloWorld for execution by setting
                    // necessary state into it.
                    hello.setState(getArgument());

                    // Execute gridified method.
                    // Note that since we are calling this method from within the grid job
                    // AOP-based grid enabling will not cross-cut it and method will just
                    // execute normally.
                    return hello.sayIt();
                }
            });
        }

        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 characters for the 'phrase' passed into
     *      {@link GridifyHelloWorld#setState(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 letters in the phrase
        // passed into task execution.
        return totalCharCnt;
    }
}

Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.2.10 Build:#528 Nov 29, 2006) - Bug/feature request - Contact Administrators