Search code examples
ignite

Calling remotely tasks deployed via a GAR file


I use UriDeploymentSpi bean to load GAR files from a directory in one of my nodes

I have following GAR ignite.xml file (took me a while to figure this one out btw, nowhere documented?)

<?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-3.0.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">


    <util:list id="myList" value-type="java.lang.String">
        <value>myproject.HelloWorldTask</value>
        <value>myproject.SimpleTask</value>
    </util:list>

</beans>

HelloWorldTask:

package myproject;

public class HelloWorldTask extends ComputeTaskAdapter<String, Integer> {

    static {
        System.out.println("TheGlue: Loading HelloWorldTask ");
    }

    public HelloWorldTask() {
    }

    @Nullable
    @Override
    public Map<? extends ComputeJob, ClusterNode> map(List<ClusterNode> nodes, @Nullable String arg) throws IgniteException {
        System.out.println("Hello from GAR file");
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Nullable
    @Override
    public Integer reduce(List<ComputeJobResult> results) throws IgniteException {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }
}

SimpleTask:

package myproject;

@ComputeTaskName("SimpleTaskName")
public class SimpleTask implements ComputeTask<String, Integer> {


    static {
        System.out.println("Loading SimpleTask");
    }

    public SimpleTask() {
    }

    @Override
    public Map<? extends ComputeJob, ClusterNode> map(List<ClusterNode> subgrid, String arg) throws IgniteException {
        System.out.println("Computing Job in SimpleTask ");
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public ComputeJobResultPolicy result(ComputeJobResult res, List<ComputeJobResult> rcvd) throws IgniteException {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public Integer reduce(List<ComputeJobResult> results) throws IgniteException {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }
}

The 2 classes can be found by Ignite (debugged through GridUriDeploymentSpringDocument and GridUriDeploymentFileProcessor and they are found and loaded). Ignite says that it found the GAR, but as far as I can see, the classes are not instantiated. No errors in the log files, no indications that the Tasks are deployed either.

I am trying to execute the following code on a node where the GAR file is not deployed (ie. client node of the cluster), but the Task is not executed on the cluster:

public class _03GarTest {

    public static void main(String[] args) {

        System.out.println("Start urideployment test");

        IgniteConfiguration cfg = new IgniteConfiguration();
        cfg.setPeerClassLoadingEnabled(true); //needs to be the same as in the XML for the server
        cfg.setClientMode(true);

        try(Ignite ignite = Ignition.start(cfg)) {
            ignite.compute(ignite.cluster().forRemotes()).execute("SimpleTaskName", null);
        }

    }
}

Log file where I execute the _03GarTest class (same if I run with "SimpleTaskName" or "myproject.SimpleTaskName"), dumps the following stacktraces on the client node:

Exception in thread "main" class org.apache.ignite.IgniteDeploymentException: Unknown task name or failed to auto-deploy task (was task (re|un)deployed?): SimpleTaskName
    at org.apache.ignite.internal.util.IgniteUtils$7.apply(IgniteUtils.java:761)
    at org.apache.ignite.internal.util.IgniteUtils$7.apply(IgniteUtils.java:759)
    at org.apache.ignite.internal.util.IgniteUtils.convertException(IgniteUtils.java:877)
    at org.apache.ignite.internal.IgniteComputeImpl.execute(IgniteComputeImpl.java:154)
    at _03GarTest.main(_03GarTest.java:55)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: class org.apache.ignite.internal.IgniteDeploymentCheckedException: Unknown task name or failed to auto-deploy task (was task (re|un)deployed?): SimpleTaskName
    at org.apache.ignite.internal.processors.task.GridTaskProcessor.startTask(GridTaskProcessor.java:515)
    at org.apache.ignite.internal.processors.task.GridTaskProcessor.execute(GridTaskProcessor.java:447)
    at org.apache.ignite.internal.IgniteComputeImpl.execute(IgniteComputeImpl.java:151)
    ... 6 more

And on the server, following logs are produced:

[13:13:33,057][INFO][disco-event-worker-#48%null%][GridDiscoveryManager] Added new node to topology: TcpDiscoveryNode [id=b70dce5e-c0fd-4ffe-8dc2-b72b18db76da, addrs=[0:0:0:0:0:0:0:1, 10.1.26.59, 127.0.0.1, 192.168.8.103, 192.168.99.1], sockAddrs=[/192.168.8.103:0, /0:0:0:0:0:0:0:1:0, /192.168.99.1:0, /10.1.26.59:0, /10.1.26.59:0, /127.0.0.1:0, /192.168.8.103:0, /192.168.99.1:0], discPort=0, order=12, intOrder=7, lastExchangeTime=1452600812926, loc=false, ver=1.5.0#20151229-sha1:f1f8cda2, isClient=true]
    [13:13:33,063][INFO][disco-event-worker-#48%null%][GridDiscoveryManager] Topology snapshot [ver=12, servers=1, clients=1, CPUs=8, heap=1.5GB]
    [13:13:33,085][WARNING][disco-event-worker-#48%null%][CourtesyConfigNotice] 

    >>> +-------------------------------------------------------------------+
    >>> + Courtesy notice that joining node has inconsistent configuration. +
    >>> + Ignore this message if you are sure that this is done on purpose. +
    >>> +-------------------------------------------------------------------+
    >>> Remote Node ID: B70DCE5E-C0FD-4FFE-8DC2-B72B18DB76DA
    >>> Remote SPI with the same name is not configured: UriDeploymentSpi
    >>> => Local node:  o.a.i.spi.deployment.uri.UriDeploymentSpi

    [13:13:33,103][INFO][exchange-worker-#51%null%][GridCachePartitionExchangeManager] Skipping rebalancing (nothing scheduled) [top=AffinityTopologyVersion [topVer=12, minorTopVer=0], evt=NODE_JOINED, node=b70dce5e-c0fd-4ffe-8dc2-b72b18db76da]
    [13:13:33,907][INFO][disco-event-worker-#48%null%][GridDiscoveryManager] Node left topology: TcpDiscoveryNode [id=b70dce5e-c0fd-4ffe-8dc2-b72b18db76da, addrs=[0:0:0:0:0:0:0:1, 10.1.26.59, 127.0.0.1, 192.168.8.103, 192.168.99.1], sockAddrs=[/192.168.8.103:0, /0:0:0:0:0:0:0:1:0, /192.168.99.1:0, /10.1.26.59:0, /10.1.26.59:0, /127.0.0.1:0, /192.168.8.103:0, /192.168.99.1:0], discPort=0, order=12, intOrder=7, lastExchangeTime=1452600812926, loc=false, ver=1.5.0#20151229-sha1:f1f8cda2, isClient=true]
    [13:13:33,908][INFO][disco-event-worker-#48%null%][GridDiscoveryManager] Topology snapshot [ver=13, servers=1, clients=0, CPUs=8, heap=1.0GB]
    [13:13:33,918][INFO][exchange-worker-#51%null%][GridCachePartitionExchangeManager] Skipping rebalancing (nothing scheduled) [top=AffinityTopologyVersion [topVer=13, minorTopVer=0], evt=NODE_LEFT, node=b70dce5e-c0fd-4ffe-8dc2-b72b18db76da]
    [13:14:03,193][INFO][grid-timeout-worker-#33%null%][IgniteKernal] 

Any ideas on how to call a task deployed via a GAR file on another node?

----UPDATE----

As suggested in one of the answers, I have added the following code in the client

        System.out.println("Start urideployment test");

        IgniteConfiguration cfg = new IgniteConfiguration();
        cfg.setPeerClassLoadingEnabled(true); //needs to be the same as in the XML for the server
        cfg.setClientMode(true);

        UriDeploymentSpi deploymentSpi = new UriDeploymentSpi();

        deploymentSpi.setUriList(Arrays.asList("file:///Users/sbeaupre/Dropbox/prorabel/Projects/IgniteTests/ignite/gar"));

        cfg.setDeploymentSpi(deploymentSpi);

        try(Ignite ignite = Ignition.start(cfg)) {
...

But this doesn't work either, I got following stack trace on the client node and nothing on the server node:

Jan 14, 2016 5:42:23 PM org.apache.ignite.logger.java.JavaLogger info
INFO: Topology snapshot [ver=4, servers=1, clients=1, CPUs=8, heap=1.5GB]
Jan 14, 2016 5:42:23 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from resource loaded from byte array
Jan 14, 2016 5:42:23 PM org.apache.ignite.logger.java.JavaLogger info
INFO: User version is not explicitly defined (will use default version) [file=META-INF/ignite.xml, clsLdr=GridUriDeploymentClassLoader [urls=[file:/var/folders/t3/595tz_px2j9__wl37f0b5nw40000gn/T/gg.uri.deployment.tmp/301a4cb8-6fc7-4aa9-b050-3083183f4cd0/dirzip_Archive8035449106801616883.gar/]]]
Jan 14, 2016 5:42:23 PM org.apache.ignite.logger.java.JavaLogger info
INFO: Task locally deployed: class myproject.SimpleTask
Loading SimpleTask
Computing Job in SimpleTask 
Jan 14, 2016 5:42:23 PM org.apache.ignite.logger.java.JavaLogger error
SEVERE: Failed to map task jobs to nodes: GridTaskSessionImpl [taskName=SimpleTaskName, dep=GridDeployment [ts=1452789743727, depMode=SHARED, clsLdr=GridUriDeploymentClassLoader [urls=[file:/var/folders/t3/595tz_px2j9__wl37f0b5nw40000gn/T/gg.uri.deployment.tmp/301a4cb8-6fc7-4aa9-b050-3083183f4cd0/dirzip_Archive8035449106801616883.gar/]], clsLdrId=cc234014251-301a4cb8-6fc7-4aa9-b050-3083183f4cd0, userVer=0, loc=true, sampleClsName=myproject.SimpleTask, pendingUndeploy=false, undeployed=false, usage=1], taskClsName=myproject.SimpleTask, sesId=bc234014251-301a4cb8-6fc7-4aa9-b050-3083183f4cd0, startTime=1452789743638, endTime=9223372036854775807, taskNodeId=301a4cb8-6fc7-4aa9-b050-3083183f4cd0, clsLdr=GridUriDeploymentClassLoader [urls=[file:/var/folders/t3/595tz_px2j9__wl37f0b5nw40000gn/T/gg.uri.deployment.tmp/301a4cb8-6fc7-4aa9-b050-3083183f4cd0/dirzip_Archive8035449106801616883.gar/]], closed=false, cpSpi=null, failSpi=null, loadSpi=null, usage=1, fullSup=false, subjId=301a4cb8-6fc7-4aa9-b050-3083183f4cd0, mapFut=IgniteFuture [orig=GridFutureAdapter [resFlag=0, res=null, startTime=1452789743739, endTime=0, ignoreInterrupts=false, lsnr=null, state=INIT]]]
class org.apache.ignite.IgniteCheckedException: Task map operation produced no mapped jobs: GridTaskSessionImpl [taskName=SimpleTaskName, dep=GridDeployment [ts=1452789743727, depMode=SHARED, clsLdr=GridUriDeploymentClassLoader [urls=[file:/var/folders/t3/595tz_px2j9__wl37f0b5nw40000gn/T/gg.uri.deployment.tmp/301a4cb8-6fc7-4aa9-b050-3083183f4cd0/dirzip_Archive8035449106801616883.gar/]], clsLdrId=cc234014251-301a4cb8-6fc7-4aa9-b050-3083183f4cd0, userVer=0, loc=true, sampleClsName=myproject.SimpleTask, pendingUndeploy=false, undeployed=false, usage=1], taskClsName=myproject.SimpleTask, sesId=bc234014251-301a4cb8-6fc7-4aa9-b050-3083183f4cd0, startTime=1452789743638, endTime=9223372036854775807, taskNodeId=301a4cb8-6fc7-4aa9-b050-3083183f4cd0, clsLdr=GridUriDeploymentClassLoader [urls=[file:/var/folders/t3/595tz_px2j9__wl37f0b5nw40000gn/T/gg.uri.deployment.tmp/301a4cb8-6fc7-4aa9-b050-3083183f4cd0/dirzip_Archive8035449106801616883.gar/]], closed=false, cpSpi=null, failSpi=null, loadSpi=null, usage=1, fullSup=false, subjId=301a4cb8-6fc7-4aa9-b050-3083183f4cd0, mapFut=IgniteFuture [orig=GridFutureAdapter [resFlag=0, res=null, startTime=1452789743739, endTime=0, ignoreInterrupts=false, lsnr=null, state=INIT]]]
    at org.apache.ignite.internal.processors.task.GridTaskWorker.body(GridTaskWorker.java:497)
    at org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:110)
    at org.apache.ignite.internal.processors.task.GridTaskProcessor.startTask(GridTaskProcessor.java:678)
    at org.apache.ignite.internal.processors.task.GridTaskProcessor.execute(GridTaskProcessor.java:447)
    at org.apache.ignite.internal.IgniteComputeImpl.execute(IgniteComputeImpl.java:151)
    at _03GarTest.main(_03GarTest.java:55)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

Solution

  • Sven,

    You should configure URI deployment SPI on client node as well to make GAR deployment work properly.

    When you call compute.execute("taskName"); a lot of things have to be done locally on client prior to first request is sent to any of the node in your topology and after results start coming back. At least, Ignite should be able to get mapped jobs and be able to process results from all remote jobs and reduce all the results - please see ComputeTask.map() and ComputeTask.result() and ComputeTask.reduce(). So, you should be able to instantiate task on client node and that is why you should have task classes available.

    I think after you configure URI deployment on client nodes you should have your code work fine.

    Please post a comment here if you need any additional info.

    Thanks!

    UPDATE Jan, 18 2016

    This is update in response to question update.

    Please note that task in question returns null from map() method which is illegal. You can refer to org.apache.ignite.examples.computegrid.ComputeTaskMapExample in binary release or directly via https://git-wip-us.apache.org/repos/asf?p=ignite.git;a=blob;f=examples/src/main/java/org/apache/ignite/examples/computegrid/ComputeTaskMapExample.java;h=3de5293a814e527b57e3984f6d3ab96bb1b62daf;hb=HEAD