Package co.cask.cdap.internal.app.runtime.service

Source Code of co.cask.cdap.internal.app.runtime.service.InMemoryProgramRuntimeService

/*
* Copyright © 2014 Cask Data, Inc.
*
* 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 co.cask.cdap.internal.app.runtime.service;

import co.cask.cdap.app.program.Program;
import co.cask.cdap.app.program.Programs;
import co.cask.cdap.app.runtime.AbstractProgramRuntimeService;
import co.cask.cdap.app.runtime.ProgramController;
import co.cask.cdap.app.runtime.ProgramOptions;
import co.cask.cdap.common.async.ExecutorUtils;
import co.cask.cdap.common.conf.CConfiguration;
import co.cask.cdap.common.conf.Constants;
import co.cask.cdap.internal.app.runtime.AbstractListener;
import co.cask.cdap.internal.app.runtime.ProgramRunnerFactory;
import co.cask.cdap.proto.Id;
import co.cask.cdap.proto.InMemoryProgramLiveInfo;
import co.cask.cdap.proto.NotRunningProgramLiveInfo;
import co.cask.cdap.proto.ProgramLiveInfo;
import co.cask.cdap.proto.ProgramType;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Inject;
import org.apache.commons.io.FileUtils;
import org.apache.twill.api.RunId;
import org.apache.twill.common.Threads;
import org.apache.twill.discovery.Discoverable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
*
*/
public final class InMemoryProgramRuntimeService extends AbstractProgramRuntimeService {

  private static final Logger LOG = LoggerFactory.getLogger(InMemoryProgramRuntimeService.class);

  private final CConfiguration cConf;

  @Inject
  public InMemoryProgramRuntimeService(ProgramRunnerFactory programRunnerFactory, CConfiguration cConf) {
    super(programRunnerFactory);
    this.cConf = cConf;
  }

  @Override
  public synchronized RuntimeInfo run(Program program, ProgramOptions options) {
    try {
      File tmpDir = new File(cConf.get(Constants.CFG_LOCAL_DATA_DIR), cConf.get(Constants.AppFabric.TEMP_DIR));
      final File destinationUnpackedJarDir = new File(tmpDir, String.format("%s.%s",
                                                                      program.getName(), UUID.randomUUID().toString()));
      Preconditions.checkState(!destinationUnpackedJarDir.exists());
      destinationUnpackedJarDir.mkdirs();

      Program bundleJarProgram = Programs.createWithUnpack(program.getJarLocation(), destinationUnpackedJarDir);
      RuntimeInfo info = super.run(bundleJarProgram, options);
      info.getController().addListener(new AbstractListener() {
        @Override
        public void stopped() {
          try {
            FileUtils.deleteDirectory(destinationUnpackedJarDir);
          } catch (IOException e) {
            LOG.warn("Failed to cleanup temporary program directory {}.", destinationUnpackedJarDir, e);
          }
        }

        @Override
        public void error(Throwable cause) {
          try {
            FileUtils.deleteDirectory(destinationUnpackedJarDir);
          } catch (IOException e) {
            LOG.warn("Failed to cleanup temporary program directory {}.", destinationUnpackedJarDir, e);
          }
        }
      }, ExecutorUtils.newThreadExecutor(Threads.createDaemonThreadFactory("program-clean-up-%d")));

      return info;

    } catch (IOException e) {
      throw new RuntimeException("Error unpackaging program " + program.getName());
    }
  }

  @Override
  public ProgramLiveInfo getLiveInfo(Id.Program programId, ProgramType type) {
    if (!isRunning(programId, type)) {
      return new NotRunningProgramLiveInfo(programId, type);
    }

    if (type.equals(ProgramType.SERVICE)) {
      Set<String> discoverableNames = new HashSet<String>();
      for (Map.Entry<RunId, RuntimeInfo> entry : list(type).entrySet()) {
        RuntimeInfo runtimeInfo = entry.getValue();
        InMemoryServiceRunner.ServiceProgramController controller = (InMemoryServiceRunner.ServiceProgramController)
                                                                      runtimeInfo.getController();
        List<ProgramController> programControllers = controller.getProgramControllers();
        for (ProgramController programController : programControllers) {
          List<Discoverable> discoverables = ((InMemoryRunnableProgramController) programController).getDiscoverables();
          for (Discoverable discoverable : discoverables) {
            discoverableNames.add(discoverable.getName());
          }
        }
      }
      return new InMemoryProgramLiveInfo(programId, type, Lists.newArrayList(discoverableNames));
    } else {
      return new InMemoryProgramLiveInfo(programId, type);
    }
  }

  @Override
  protected void shutDown() throws Exception {
    stopAllPrograms();
  }

  private void stopAllPrograms() {

    LOG.info("Stopping all running programs.");

    List<ListenableFuture<ProgramController>> futures = Lists.newLinkedList();
    for (ProgramType type : ProgramType.values()) {
      for (Map.Entry<RunId, RuntimeInfo> entry : list(type).entrySet()) {
        RuntimeInfo runtimeInfo = entry.getValue();
        if (isRunning(runtimeInfo.getProgramId(), type)) {
          futures.add(runtimeInfo.getController().stop());
        }
      }
    }
    // unchecked because we cannot do much if it fails. We will still shutdown the standalone CDAP instance.
    try {
      Futures.successfulAsList(futures).get(60, TimeUnit.SECONDS);
      LOG.info("All programs have been stopped.");
    } catch (ExecutionException e) {
      // note this should not happen because we wait on a successfulAsList
      LOG.warn("Got exception while waiting for all programs to stop", e.getCause());
    } catch (InterruptedException e) {
      LOG.warn("Got interrupted exception while waiting for all programs to stop", e);
      Thread.currentThread().interrupt();
    } catch (TimeoutException e) {
      // can't do much more than log it. We still want to exit.
      LOG.warn("Timeout while waiting for all programs to stop.");
    }
  }
}
TOP

Related Classes of co.cask.cdap.internal.app.runtime.service.InMemoryProgramRuntimeService

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.