Package eu.stratosphere.client.program

Source Code of eu.stratosphere.client.program.Client$ProgramAbortException

/***********************************************************************************************************************
* Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
**********************************************************************************************************************/

package eu.stratosphere.client.program;

import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.common.base.Preconditions;

import eu.stratosphere.api.common.JobExecutionResult;
import eu.stratosphere.api.common.Plan;
import eu.stratosphere.api.java.ExecutionEnvironment;
import eu.stratosphere.compiler.CompilerException;
import eu.stratosphere.compiler.DataStatistics;
import eu.stratosphere.compiler.PactCompiler;
import eu.stratosphere.compiler.contextcheck.ContextChecker;
import eu.stratosphere.compiler.costs.DefaultCostEstimator;
import eu.stratosphere.compiler.plan.OptimizedPlan;
import eu.stratosphere.compiler.plandump.PlanJSONDumpGenerator;
import eu.stratosphere.compiler.plantranslate.NepheleJobGraphGenerator;
import eu.stratosphere.configuration.ConfigConstants;
import eu.stratosphere.configuration.Configuration;
import eu.stratosphere.configuration.GlobalConfiguration;
import eu.stratosphere.core.fs.Path;
import eu.stratosphere.nephele.client.AbstractJobResult.ReturnCode;
import eu.stratosphere.nephele.client.JobClient;
import eu.stratosphere.nephele.client.JobExecutionException;
import eu.stratosphere.nephele.client.JobSubmissionResult;
import eu.stratosphere.nephele.jobgraph.JobGraph;

/**
* Encapsulates the functionality necessary to submit a program to a remote cluster.
*/
public class Client {
 
  private static final Log LOG = LogFactory.getLog(Client.class);
 
 
  private final Configuration configuration;  // the configuration describing the job manager address
 
  private final PactCompiler compiler;    // the compiler to compile the jobs

  private boolean printStatusDuringExecution;
 
  // ------------------------------------------------------------------------
  //                            Construction
  // ------------------------------------------------------------------------
 
  /**
   * Creates a new instance of the class that submits the jobs to a job-manager.
   * at the given address using the default port.
   *
   * @param jobManagerAddress Address and port of the job-manager.
   */
  public Client(InetSocketAddress jobManagerAddress, Configuration config) {
    Preconditions.checkNotNull(config, "Configuration is null");
    this.configuration = config;
    configuration.setString(ConfigConstants.JOB_MANAGER_IPC_ADDRESS_KEY, jobManagerAddress.getAddress().getHostAddress());
    configuration.setInteger(ConfigConstants.JOB_MANAGER_IPC_PORT_KEY, jobManagerAddress.getPort());
   
    this.compiler = new PactCompiler(new DataStatistics(), new DefaultCostEstimator(), jobManagerAddress);
   
    //  Disable Local Execution when using a Client
    ContextEnvironment.disableLocalExecution();
  }

  /**
   * Creates a instance that submits the programs to the job-manager defined in the
   * configuration.
   *
   * @param config The config used to obtain the job-manager's address.
   */
  public Client(Configuration config) {
    Preconditions.checkNotNull(config, "Configuration is null");
    this.configuration = config;
   
    // instantiate the address to the job manager
    final String address = config.getString(ConfigConstants.JOB_MANAGER_IPC_ADDRESS_KEY, null);
    if (address == null) {
      throw new CompilerException("Cannot find address to job manager's RPC service in the global configuration.");
    }
   
    final int port = GlobalConfiguration.getInteger(ConfigConstants.JOB_MANAGER_IPC_PORT_KEY, ConfigConstants.DEFAULT_JOB_MANAGER_IPC_PORT);
    if (port < 0) {
      throw new CompilerException("Cannot find port to job manager's RPC service in the global configuration.");
    }

    final InetSocketAddress jobManagerAddress = new InetSocketAddress(address, port);
    this.compiler = new PactCompiler(new DataStatistics(), new DefaultCostEstimator(), jobManagerAddress);
   
    //  Disable Local Execution when using a Client
    ContextEnvironment.disableLocalExecution();
  }
 
  public void setPrintStatusDuringExecution(boolean print) {
    this.printStatusDuringExecution = print;
  }

  public String getJobManagerAddress() {
    return this.configuration.getString(ConfigConstants.JOB_MANAGER_IPC_ADDRESS_KEY, null);
  }
 
  public int getJobManagerPort() {
    return this.configuration.getInteger(ConfigConstants.JOB_MANAGER_IPC_PORT_KEY, -1);
  }
 
  // ------------------------------------------------------------------------
  //                      Compilation and Submission
  // ------------------------------------------------------------------------
 
  public String getOptimizedPlanAsJson(PackagedProgram prog, int parallelism) throws CompilerException, ProgramInvocationException {
    PlanJSONDumpGenerator jsonGen = new PlanJSONDumpGenerator();
    return jsonGen.getOptimizerPlanAsJSON(getOptimizedPlan(prog, parallelism));
  }
 
  public OptimizedPlan getOptimizedPlan(PackagedProgram prog, int parallelism) throws CompilerException, ProgramInvocationException {
    Thread.currentThread().setContextClassLoader(prog.getUserCodeClassLoader());
    if (prog.isUsingProgramEntryPoint()) {
      return getOptimizedPlan(prog.getPlanWithJars(), parallelism);
    }
    else if (prog.isUsingInteractiveMode()) {
      // temporary hack to support the optimizer plan preview
      OptimizerPlanEnvironment env = new OptimizerPlanEnvironment(this.compiler);
      if (parallelism > 0) {
        env.setDegreeOfParallelism(parallelism);
      }
      env.setAsContext();
      try {
        prog.invokeInteractiveModeForExecution();
      }
      catch (ProgramInvocationException e) {
        throw e;
      }
      catch (Throwable t) {
        // the invocation gets aborted with the preview plan
        if (env.optimizerPlan != null) {
          return env.optimizerPlan;
        } else {
          throw new ProgramInvocationException("The program caused an error: ", t);
        }
      }
     
      throw new ProgramInvocationException(
          "The program plan could not be fetched. The program silently swallowed the control flow exceptions.");
    }
    else {
      throw new RuntimeException();
    }
  }
 
  public OptimizedPlan getOptimizedPlan(Plan p, int parallelism) throws CompilerException {
    if (parallelism > 0 && p.getDefaultParallelism() <= 0) {
      p.setDefaultParallelism(parallelism);
    }
   
    ContextChecker checker = new ContextChecker();
    checker.check(p);
    return this.compiler.compile(p);
  }
 
 
  /**
   * Creates the optimized plan for a given program, using this client's compiler.
   * 
   * @param prog The program to be compiled.
   * @return The compiled and optimized plan, as returned by the compiler.
   * @throws CompilerException Thrown, if the compiler encounters an illegal situation.
   * @throws ProgramInvocationException Thrown, if the program could not be instantiated from its jar file.
   */
  public OptimizedPlan getOptimizedPlan(JobWithJars prog, int parallelism) throws CompilerException, ProgramInvocationException {
    return getOptimizedPlan(prog.getPlan(), parallelism);
  }
 
  public JobGraph getJobGraph(PackagedProgram prog, OptimizedPlan optPlan) throws ProgramInvocationException {
    return getJobGraph(optPlan, prog.getAllLibraries());
  }
 
  private JobGraph getJobGraph(OptimizedPlan optPlan, List<File> jarFiles) {
    NepheleJobGraphGenerator gen = new NepheleJobGraphGenerator();
    JobGraph job = gen.compileJobGraph(optPlan);
   
    for (File jar : jarFiles) {
      job.addJar(new Path(jar.getAbsolutePath()));
    }
   
    return job;
  }
 
  public JobExecutionResult run(final PackagedProgram prog, int parallelism, boolean wait) throws ProgramInvocationException {
    Thread.currentThread().setContextClassLoader(prog.getUserCodeClassLoader());
    if (prog.isUsingProgramEntryPoint()) {
      return run(prog.getPlanWithJars(), parallelism, wait);
    }
    else if (prog.isUsingInteractiveMode()) {
      ContextEnvironment env = new ContextEnvironment(this, prog.getAllLibraries(), prog.getUserCodeClassLoader());
     
      if (parallelism > 0) {
        env.setDegreeOfParallelism(parallelism);
      }
      env.setAsContext();
     
      if (wait) {
        // invoke here
        prog.invokeInteractiveModeForExecution();
      }
      else {
        // invoke in the background
        Thread backGroundRunner = new Thread("Program Runner") {
          public void run() {
            try {
              prog.invokeInteractiveModeForExecution();
            }
            catch (Throwable t) {
              LOG.error("The program execution failed.", t);
            }
          };
        };
        backGroundRunner.start();
      }
      return null;
    }
    else {
      throw new RuntimeException();
    }
  }
 
  public JobExecutionResult run(PackagedProgram prog, OptimizedPlan optimizedPlan, boolean wait) throws ProgramInvocationException {
    return run(optimizedPlan, prog.getAllLibraries(), wait);

  }
 
  /**
   * Runs a program on the nephele system whose job-manager is configured in this client's configuration.
   * This method involves all steps, from compiling, job-graph generation to submission.
   *
   * @param prog The program to be executed.
   * @param wait A flag that indicates whether this function call should block until the program execution is done.
   * @throws CompilerException Thrown, if the compiler encounters an illegal situation.
   * @throws ProgramInvocationException Thrown, if the program could not be instantiated from its jar file,
   *                                    or if the submission failed. That might be either due to an I/O problem,
   *                                    i.e. the job-manager is unreachable, or due to the fact that the execution
   *                                    on the nephele system failed.
   * @throws JobInstantiationException Thrown, if the plan assembler function causes an exception.
   */
  public JobExecutionResult run(JobWithJars prog, int parallelism, boolean wait) throws CompilerException, ProgramInvocationException {
    return run(getOptimizedPlan(prog, parallelism), prog.getJarFiles(), wait);
  }
 

  public JobExecutionResult run(OptimizedPlan compiledPlan, List<File> libraries, boolean wait) throws ProgramInvocationException {
    JobGraph job = getJobGraph(compiledPlan, libraries);
    return run(job, wait);
  }

  public JobExecutionResult run(JobGraph jobGraph, boolean wait) throws ProgramInvocationException {
    JobClient client;
    try {
      client = new JobClient(jobGraph, configuration);
    }
    catch (IOException e) {
      throw new ProgramInvocationException("Could not open job manager: " + e.getMessage());
    }
   
    client.setConsoleStreamForReporting(this.printStatusDuringExecution ? System.out : null);

    try {
      if (wait) {
        return client.submitJobAndWait();
      }
      else {
        JobSubmissionResult result = client.submitJob();
       
        if (result.getReturnCode() != ReturnCode.SUCCESS) {
          throw new ProgramInvocationException("The job was not successfully submitted to the nephele job manager"
            + (result.getDescription() == null ? "." : ": " + result.getDescription()));
        }
      }
    }
    catch (IOException e) {
      throw new ProgramInvocationException("Could not submit job to job manager: " + e.getMessage());
    }
    catch (JobExecutionException jex) {
      if(jex.isJobCanceledByUser()) {
        throw new ProgramInvocationException("The program has been canceled");
      } else {
        throw new ProgramInvocationException("The program execution failed: " + jex.getMessage());
      }
    }
    return new JobExecutionResult(-1, null);
  }
 
  // --------------------------------------------------------------------------------------------
 
  private static final class OptimizerPlanEnvironment extends ExecutionEnvironment {
   
    private final PactCompiler compiler;
   
    private OptimizedPlan optimizerPlan;
   
   
    private OptimizerPlanEnvironment(PactCompiler compiler) {
      this.compiler = compiler;
    }
   
    @Override
    public JobExecutionResult execute(String jobName) throws Exception {
      Plan plan = createProgramPlan(jobName);
      this.optimizerPlan = compiler.compile(plan);
     
      // do not go on with anything now!
      throw new ProgramAbortException();
    }

    @Override
    public String getExecutionPlan() throws Exception {
      Plan plan = createProgramPlan();
      this.optimizerPlan = compiler.compile(plan);
     
      // do not go on with anything now!
      throw new ProgramAbortException();
    }
   
    private void setAsContext() {
      initializeContextEnvironment(this);
    }
  }
 
  static final class ProgramAbortException extends Error {
    private static final long serialVersionUID = 1L;
  }
}
TOP

Related Classes of eu.stratosphere.client.program.Client$ProgramAbortException

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.