org.apache.hadoop.yarn.client.api.async.NMClientAsync.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.hadoop.yarn.client.api.async.NMClientAsync.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.hadoop.yarn.client.api.async;

import java.nio.ByteBuffer;
import java.util.Map;

import org.apache.hadoop.classification.InterfaceAudience.Private;
import org.apache.hadoop.classification.InterfaceAudience.Public;
import org.apache.hadoop.classification.InterfaceStability.Stable;
import org.apache.hadoop.service.AbstractService;
import org.apache.hadoop.yarn.api.records.Container;
import org.apache.hadoop.yarn.api.records.ContainerId;
import org.apache.hadoop.yarn.api.records.ContainerLaunchContext;
import org.apache.hadoop.yarn.api.records.ContainerStatus;
import org.apache.hadoop.yarn.api.records.NodeId;
import org.apache.hadoop.yarn.api.records.Resource;
import org.apache.hadoop.yarn.client.api.NMClient;
import org.apache.hadoop.yarn.client.api.async.impl.NMClientAsyncImpl;
import org.apache.hadoop.yarn.client.api.impl.NMClientImpl;
import org.apache.hadoop.yarn.conf.YarnConfiguration;

import com.google.common.annotations.VisibleForTesting;

/**
 * <code>NMClientAsync</code> handles communication with all the NodeManagers
 * and provides asynchronous updates on getting responses from them. It
 * maintains a thread pool to communicate with individual NMs where a number of
 * worker threads process requests to NMs by using {@link NMClientImpl}. The max
 * size of the thread pool is configurable through
 * {@link YarnConfiguration#NM_CLIENT_ASYNC_THREAD_POOL_MAX_SIZE}.
 *
 * It should be used in conjunction with a CallbackHandler. For example
 *
 * <pre>
 * {@code
 * class MyCallbackHandler extends NMClientAsync.AbstractCallbackHandler {
 *   public void onContainerStarted(ContainerId containerId,
 *       Map<String, ByteBuffer> allServiceResponse) {
 *     [post process after the container is started, process the response]
 *   }
    
 *   public void onContainerResourceIncreased(ContainerId containerId,
 *       Resource resource) {
 *     [post process after the container resource is increased]
 *   }
 *
 *   public void onContainerStatusReceived(ContainerId containerId,
 *       ContainerStatus containerStatus) {
 *     [make use of the status of the container]
 *   }
 *
 *   public void onContainerStopped(ContainerId containerId) {
 *     [post process after the container is stopped]
 *   }
 *
 *   public void onStartContainerError(
 *       ContainerId containerId, Throwable t) {
 *     [handle the raised exception]
 *   }
 *
 *   public void onGetContainerStatusError(
 *       ContainerId containerId, Throwable t) {
 *     [handle the raised exception]
 *   }
 *
 *   public void onStopContainerError(
 *       ContainerId containerId, Throwable t) {
 *     [handle the raised exception]
 *   }
 * }
 * }
 * </pre>
 *
 * The client's life-cycle should be managed like the following:
 *
 * <pre>
 * {@code
 * NMClientAsync asyncClient = 
 *     NMClientAsync.createNMClientAsync(new MyCallbackhandler());
 * asyncClient.init(conf);
 * asyncClient.start();
 * asyncClient.startContainer(container, containerLaunchContext);
 * [... wait for container being started]
 * asyncClient.getContainerStatus(container.getId(), container.getNodeId(),
 *     container.getContainerToken());
 * [... handle the status in the callback instance]
 * asyncClient.stopContainer(container.getId(), container.getNodeId(),
 *     container.getContainerToken());
 * [... wait for container being stopped]
 * asyncClient.stop();
 * }
 * </pre>
 */
@Public
@Stable
public abstract class NMClientAsync extends AbstractService {

    protected NMClient client;
    protected CallbackHandler callbackHandler;

    public static NMClientAsync createNMClientAsync(AbstractCallbackHandler callbackHandler) {
        return new NMClientAsyncImpl(callbackHandler);
    }

    protected NMClientAsync(AbstractCallbackHandler callbackHandler) {
        this(NMClientAsync.class.getName(), callbackHandler);
    }

    protected NMClientAsync(String name, AbstractCallbackHandler callbackHandler) {
        this(name, new NMClientImpl(), callbackHandler);
    }

    protected NMClientAsync(String name, NMClient client, AbstractCallbackHandler callbackHandler) {
        super(name);
        this.setClient(client);
        this.setCallbackHandler(callbackHandler);
    }

    /**
     * @deprecated Use {@link #createNMClientAsync(AbstractCallbackHandler)}
     *             instead.
     */
    @Deprecated
    public static NMClientAsync createNMClientAsync(CallbackHandler callbackHandler) {
        return new NMClientAsyncImpl(callbackHandler);
    }

    /**
     * @deprecated Use {@link #NMClientAsync(AbstractCallbackHandler)}
     *             instead.
     */
    @Deprecated
    protected NMClientAsync(CallbackHandler callbackHandler) {
        this(NMClientAsync.class.getName(), callbackHandler);
    }

    /**
     * @deprecated Use {@link #NMClientAsync(String, AbstractCallbackHandler)}
     *             instead.
     */
    @Deprecated
    protected NMClientAsync(String name, CallbackHandler callbackHandler) {
        this(name, new NMClientImpl(), callbackHandler);
    }

    @Private
    @VisibleForTesting
    @Deprecated
    protected NMClientAsync(String name, NMClient client, CallbackHandler callbackHandler) {
        super(name);
        this.setClient(client);
        this.setCallbackHandler(callbackHandler);
    }

    public abstract void startContainerAsync(Container container, ContainerLaunchContext containerLaunchContext);

    @Deprecated
    public abstract void increaseContainerResourceAsync(Container container);

    /**
     * <p>Update the resources of a container.</p>
     *
     * <p>The <code>ApplicationMaster</code> or other applications that use the
     * client must provide the details of the container, including the Id and
     * the target resource encapsulated in the updated container token via
     * {@link Container}.
     * </p>
     *
     * @param container the container with updated token.
     */
    public abstract void updateContainerResourceAsync(Container container);

    /**
     * <p>Re-Initialize the Container.</p>
     *
     * @param containerId the Id of the container to Re-Initialize.
     * @param containerLaunchContex the updated ContainerLaunchContext.
     * @param autoCommit commit re-initialization automatically ?
     */
    public abstract void reInitializeContainerAsync(ContainerId containerId,
            ContainerLaunchContext containerLaunchContex, boolean autoCommit);

    /**
     * <p>Restart the specified container.</p>
     *
     * @param containerId the Id of the container to restart.
     */
    public abstract void restartContainerAsync(ContainerId containerId);

    /**
     * <p>Rollback last reInitialization of the specified container.</p>
     *
     * @param containerId the Id of the container to restart.
     */
    public abstract void rollbackLastReInitializationAsync(ContainerId containerId);

    /**
     * <p>Commit last reInitialization of the specified container.</p>
     *
     * @param containerId the Id of the container to commit reInitialize.
     */
    public abstract void commitLastReInitializationAsync(ContainerId containerId);

    public abstract void stopContainerAsync(ContainerId containerId, NodeId nodeId);

    public abstract void getContainerStatusAsync(ContainerId containerId, NodeId nodeId);

    public NMClient getClient() {
        return client;
    }

    public void setClient(NMClient client) {
        this.client = client;
    }

    public CallbackHandler getCallbackHandler() {
        return callbackHandler;
    }

    public void setCallbackHandler(CallbackHandler callbackHandler) {
        this.callbackHandler = callbackHandler;
    }

    /**
     * <p>
     * The callback abstract class. The callback functions need to be implemented
     * by {@link NMClientAsync} users. The APIs are called when responses from
     * <code>NodeManager</code> are available.
     * </p>
     *
     * <p>
     * Once a callback happens, the users can chose to act on it in blocking or
     * non-blocking manner. If the action on callback is done in a blocking
     * manner, some of the threads performing requests on NodeManagers may get
     * blocked depending on how many threads in the pool are busy.
     * </p>
     *
     * <p>
     * The implementation of the callback functions should not throw the
     * unexpected exception. Otherwise, {@link NMClientAsync} will just
     * catch, log and then ignore it.
     * </p>
     */
    public abstract static class AbstractCallbackHandler implements CallbackHandler {
        /**
         * The API is called when <code>NodeManager</code> responds to indicate its
         * acceptance of the starting container request.
         *
         * @param containerId the Id of the container
         * @param allServiceResponse a Map between the auxiliary service names and
         *                           their outputs
         */
        public abstract void onContainerStarted(ContainerId containerId,
                Map<String, ByteBuffer> allServiceResponse);

        /**
         * The API is called when <code>NodeManager</code> responds with the status
         * of the container.
         *
         * @param containerId the Id of the container
         * @param containerStatus the status of the container
         */
        public abstract void onContainerStatusReceived(ContainerId containerId, ContainerStatus containerStatus);

        /**
         * The API is called when <code>NodeManager</code> responds to indicate the
         * container is stopped.
         *
         * @param containerId the Id of the container
         */
        public abstract void onContainerStopped(ContainerId containerId);

        /**
         * The API is called when an exception is raised in the process of
         * starting a container.
         *
         * @param containerId the Id of the container
         * @param t the raised exception
         */
        public abstract void onStartContainerError(ContainerId containerId, Throwable t);

        /**
         * The API is called when <code>NodeManager</code> responds to indicate
         * the container resource has been successfully increased.
         *
         * @param containerId the Id of the container
         * @param resource the target resource of the container
         */
        @Deprecated
        public abstract void onContainerResourceIncreased(ContainerId containerId, Resource resource);

        /**
         * The API is called when <code>NodeManager</code> responds to indicate
         * the container resource has been successfully updated.
         *
         * @param containerId the Id of the container
         * @param resource the target resource of the container
         */
        public abstract void onContainerResourceUpdated(ContainerId containerId, Resource resource);

        /**
         * The API is called when an exception is raised in the process of
         * querying the status of a container.
         *
         * @param containerId the Id of the container
         * @param t the raised exception
         */
        public abstract void onGetContainerStatusError(ContainerId containerId, Throwable t);

        /**
         * The API is called when an exception is raised in the process of
         * increasing container resource.
         *
         * @param containerId the Id of the container
         * @param t the raised exception
         */
        @Deprecated
        public abstract void onIncreaseContainerResourceError(ContainerId containerId, Throwable t);

        /**
         * The API is called when an exception is raised in the process of
         * updating container resource.
         *
         * @param containerId the Id of the container
         * @param t the raised exception
         */
        public abstract void onUpdateContainerResourceError(ContainerId containerId, Throwable t);

        /**
         * The API is called when an exception is raised in the process of
         * stopping a container.
         *
         * @param containerId the Id of the container
         * @param t the raised exception
         */
        public abstract void onStopContainerError(ContainerId containerId, Throwable t);

        /**
         * Callback for container re-initialization request.
         *
         * @param containerId the Id of the container to be Re-Initialized.
         */
        public void onContainerReInitialize(ContainerId containerId) {
        }

        /**
         * Callback for container restart.
         *
         * @param containerId the Id of the container to restart.
         */
        public void onContainerRestart(ContainerId containerId) {
        }

        /**
         * Callback for rollback of last re-initialization.
         *
         * @param containerId the Id of the container to restart.
         */
        public void onRollbackLastReInitialization(ContainerId containerId) {
        }

        /**
         * Callback for commit of last re-initialization.
         *
         * @param containerId the Id of the container to commit reInitialize.
         */
        public void onCommitLastReInitialization(ContainerId containerId) {
        }

        /**
         * Error Callback for container re-initialization request.
         *
         * @param containerId the Id of the container to be Re-Initialized.
         * @param t a Throwable.
         */
        public void onContainerReInitializeError(ContainerId containerId, Throwable t) {
        }

        /**
         * Error Callback for container restart.
         *
         * @param containerId the Id of the container to restart.
         * @param t a Throwable.
         *
         */
        public void onContainerRestartError(ContainerId containerId, Throwable t) {
        }

        /**
         * Error Callback for rollback of last re-initialization.
         *
         * @param containerId the Id of the container to restart.
         * @param t a Throwable.
         */
        public void onRollbackLastReInitializationError(ContainerId containerId, Throwable t) {
        }

        /**
         * Error Callback for commit of last re-initialization.
         *
         * @param containerId the Id of the container to commit reInitialize.
         * @param t a Throwable.
         */
        public void onCommitLastReInitializationError(ContainerId containerId, Throwable t) {
        }
    }

    /**
     * @deprecated Use {@link NMClientAsync.AbstractCallbackHandler} instead.
     *
     * <p>
     * The callback interface needs to be implemented by {@link NMClientAsync}
     * users. The APIs are called when responses from <code>NodeManager</code> are
     * available.
     * </p>
     *
     * <p>
     * Once a callback happens, the users can chose to act on it in blocking or
     * non-blocking manner. If the action on callback is done in a blocking
     * manner, some of the threads performing requests on NodeManagers may get
     * blocked depending on how many threads in the pool are busy.
     * </p>
     *
     * <p>
     * The implementation of the callback function should not throw the
     * unexpected exception. Otherwise, {@link NMClientAsync} will just
     * catch, log and then ignore it.
     * </p>
     */
    @Deprecated
    public static interface CallbackHandler {
        /**
         * The API is called when <code>NodeManager</code> responds to indicate its
         * acceptance of the starting container request
         * @param containerId the Id of the container
         * @param allServiceResponse a Map between the auxiliary service names and
         *                           their outputs
         */
        void onContainerStarted(ContainerId containerId, Map<String, ByteBuffer> allServiceResponse);

        /**
         * The API is called when <code>NodeManager</code> responds with the status
         * of the container
         * @param containerId the Id of the container
         * @param containerStatus the status of the container
         */
        void onContainerStatusReceived(ContainerId containerId, ContainerStatus containerStatus);

        /**
         * The API is called when <code>NodeManager</code> responds to indicate the
         * container is stopped.
         * @param containerId the Id of the container
         */
        void onContainerStopped(ContainerId containerId);

        /**
         * The API is called when an exception is raised in the process of
         * starting a container
         *
         * @param containerId the Id of the container
         * @param t the raised exception
         */
        void onStartContainerError(ContainerId containerId, Throwable t);

        /**
         * The API is called when an exception is raised in the process of
         * querying the status of a container
         *
         * @param containerId the Id of the container
         * @param t the raised exception
         */
        void onGetContainerStatusError(ContainerId containerId, Throwable t);

        /**
         * The API is called when an exception is raised in the process of
         * stopping a container
         *
         * @param containerId the Id of the container
         * @param t the raised exception
         */
        void onStopContainerError(ContainerId containerId, Throwable t);

    }

}