ml.shifu.guagua.hadoop.ZooKeeperWorkerInterceptor.java Source code

Java tutorial

Introduction

Here is the source code for ml.shifu.guagua.hadoop.ZooKeeperWorkerInterceptor.java

Source

/*
 * Copyright [2013-2015] PayPal Software Foundation
 *
 * 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 ml.shifu.guagua.hadoop;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.TimeUnit;

import ml.shifu.guagua.BasicCoordinator.RetryCoordinatorCommand;
import ml.shifu.guagua.GuaguaConstants;
import ml.shifu.guagua.GuaguaRuntimeException;
import ml.shifu.guagua.coordinator.zk.ZooKeeperUtils;
import ml.shifu.guagua.io.Bytable;
import ml.shifu.guagua.util.NumberFormatUtils;
import ml.shifu.guagua.worker.BasicWorkerInterceptor;
import ml.shifu.guagua.worker.WorkerContext;

import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Follow with {@link ZooKeeperMasterInterceptor}, {@link ZooKeeperWorkerInterceptor} is used to read zookeeper server
 * info from hdfs file.
 */
public class ZooKeeperWorkerInterceptor<MASTER_RESULT extends Bytable, WORKER_RESULT extends Bytable>
        extends BasicWorkerInterceptor<MASTER_RESULT, WORKER_RESULT> {

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

    /**
     * Default waiting time to check master or worker progress from zookeeper servers.
     */
    private static final int WAIT_SLOT_MILLS = 300;

    /**
     * Waiting time to check master or worker progress from zookeeper servers.
     */
    private long sleepTime = WAIT_SLOT_MILLS;

    /**
     * Fixed-time waiting or each time increasing the waiting time.
     */
    private boolean isFixedTime = true;

    @Override
    public void preApplication(WorkerContext<MASTER_RESULT, WORKER_RESULT> context) {
        String zkServers = context.getProps().getProperty(GuaguaConstants.GUAGUA_ZK_SERVERS);
        if (zkServers == null || zkServers.length() == 0 || !ZooKeeperUtils.checkServers(zkServers)) {
            this.sleepTime = NumberFormatUtils.getLong(
                    context.getProps().getProperty(GuaguaConstants.GUAGUA_COORDINATOR_SLEEP_UNIT), WAIT_SLOT_MILLS);
            this.isFixedTime = Boolean.TRUE.toString().equalsIgnoreCase(
                    context.getProps().getProperty(GuaguaConstants.GUAGUA_COORDINATOR_FIXED_SLEEP_ENABLE,
                            GuaguaConstants.GUAGUA_COORDINATOR_FIXED_SLEEP));

            String hdfsZookeeperServerFolder = getZookeeperServerFolder(context);
            long start = System.nanoTime();
            while (true) {
                if (TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start) > 10 * 60 * 1000L) {
                    throw new GuaguaRuntimeException("Cannot get zookeeper server address in 10 minutes.");
                }
                BufferedReader br = null;
                try {
                    final FileSystem fileSystem = FileSystem.get(new Configuration());
                    final Path zookeeperServerPath = fileSystem.makeQualified(new Path(hdfsZookeeperServerFolder,
                            GuaguaConstants.GUAGUA_CLUSTER_ZOOKEEPER_SERVER_FILE));
                    LOG.info("Embeded zookeeper server address is {}", zookeeperServerPath);

                    new RetryCoordinatorCommand(this.isFixedTime, this.sleepTime) {
                        @Override
                        public boolean retryExecution() throws Exception, InterruptedException {
                            return fileSystem.exists(zookeeperServerPath);
                        }
                    }.execute();

                    FSDataInputStream fis = fileSystem.open(zookeeperServerPath);
                    br = new BufferedReader(new InputStreamReader(fis));
                    String zookeeperServer = br.readLine();
                    if (zookeeperServer == null || zookeeperServer.length() == 0) {
                        LOG.warn("Cannot get zookeeper server in {} ", zookeeperServerPath.toString());
                        // retry
                        continue;
                    }
                    // set server info to context for next intercepters.
                    LOG.info("Embeded zookeeper instance is {}", zookeeperServer);
                    context.getProps().setProperty(GuaguaConstants.GUAGUA_ZK_SERVERS, zookeeperServer);
                    break;
                } catch (Throwable t) {
                    LOG.warn(String.format("Error in get zookeeper address message: %s", t.getMessage()));
                    continue;
                } finally {
                    IOUtils.closeQuietly(br);
                }
            }
        }
    }

    // TODO merge this function together with the one in worker
    private String getZookeeperServerFolder(WorkerContext<MASTER_RESULT, WORKER_RESULT> context) {
        String defaultZooKeeperServePath = new StringBuilder(200).append("tmp").append(Path.SEPARATOR)
                .append("_guagua").append(Path.SEPARATOR).append(context.getAppId()).append(Path.SEPARATOR)
                .toString();
        String hdfsZookeeperServerPath = context.getProps()
                .getProperty(GuaguaConstants.GUAGUA_ZK_CLUSTER_SERVER_FOLDER, defaultZooKeeperServePath);
        return hdfsZookeeperServerPath;
    }

}