com.alibaba.otter.shared.arbitrate.impl.setl.zookeeper.termin.NormalTerminProcess.java Source code

Java tutorial

Introduction

Here is the source code for com.alibaba.otter.shared.arbitrate.impl.setl.zookeeper.termin.NormalTerminProcess.java

Source

/*
 * Copyright (C) 2010-2101 Alibaba Group Holding Limited.
 *
 * 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 com.alibaba.otter.shared.arbitrate.impl.setl.zookeeper.termin;

import java.util.Collections;
import java.util.List;

import org.I0Itec.zkclient.exception.ZkException;
import org.I0Itec.zkclient.exception.ZkInterruptedException;
import org.I0Itec.zkclient.exception.ZkNoNodeException;
import org.I0Itec.zkclient.exception.ZkNodeExistsException;
import org.apache.commons.lang.math.RandomUtils;
import org.apache.zookeeper.CreateMode;
import org.springframework.util.CollectionUtils;

import com.alibaba.otter.shared.arbitrate.exception.ArbitrateException;
import com.alibaba.otter.shared.arbitrate.impl.ArbitrateConstants;
import com.alibaba.otter.shared.arbitrate.impl.config.ArbitrateConfigUtils;
import com.alibaba.otter.shared.arbitrate.impl.setl.helper.StageComparator;
import com.alibaba.otter.shared.arbitrate.impl.setl.helper.StagePathUtils;
import com.alibaba.otter.shared.arbitrate.impl.zookeeper.ZooKeeperClient;
import com.alibaba.otter.shared.arbitrate.model.ProcessNodeEventData;
import com.alibaba.otter.shared.arbitrate.model.TerminEventData;
import com.alibaba.otter.shared.common.utils.JsonUtils;
import com.alibaba.otter.shared.common.utils.zookeeper.ZkClientx;

/**
 * ???
 * 
 * <pre>
 *  ????.
 * 1. normalshutdown/rollback??shutdown/rollback??? (normal???)
 * 2. shutdown/rollback?channel?normal?stageprocessnormal?stage??
 * 3. ?termin?process (???processtermin?process?????termin??)
 * 4. normalshutdown/rollback????termin. (???termin?createtermin??create???) 
 * 
 * ?(canaltermin??/???retry??????) 
 * write at 2012-09-06 by jianghang.loujh
 * </pre>
 * 
 * @author jianghang 2011-9-26 ?01:52:53
 * @version 4.0.0
 */
public class NormalTerminProcess implements TerminProcess {

    private ZkClientx zookeeper = ZooKeeperClient.getInstance();

    public boolean process(TerminEventData data) {
        return doProcess(data, false);
    }

    private boolean doProcess(TerminEventData data, boolean retry) {
        Long pipelineId = data.getPipelineId();
        Long processId = data.getProcessId();

        List<String> currentStages = null;
        try {
            currentStages = zookeeper.getChildren(StagePathUtils.getProcess(pipelineId, processId));
            Collections.sort(currentStages, new StageComparator());
        } catch (ZkNoNodeException e) {
            // ignore?
            return false;
        } catch (ZkException e) {
            throw new ArbitrateException("Termin_process", e);
        }

        // ?S.E.T.L
        // s
        if (currentStages == null || currentStages.contains(ArbitrateConstants.NODE_SELECTED)) {
            try {
                boolean successed = zookeeper.delete(StagePathUtils.getSelectStage(pipelineId, processId));
                if (!successed) {
                    processDeleteFailed();
                }
            } catch (ZkException e) {
                throw new ArbitrateException("Termin_process", e);
            }
        }

        // e
        if (currentStages == null || currentStages.contains(ArbitrateConstants.NODE_EXTRACTED)) {
            try {
                boolean successed = zookeeper.delete(StagePathUtils.getExtractStage(pipelineId, processId));
                if (!successed) {
                    processDeleteFailed();
                }
            } catch (ZkException e) {
                throw new ArbitrateException("Termin_process", e);
            }
        }

        // t
        if (currentStages == null || currentStages.contains(ArbitrateConstants.NODE_TRANSFORMED)) {
            try {
                boolean successed = zookeeper.delete(StagePathUtils.getTransformStage(pipelineId, processId));
                if (!successed) {
                    processDeleteFailed();
                }
            } catch (ZkException e) {
                throw new ArbitrateException("Termin_process", e);
            }
        }
        // l
        // try {
        // zookeeper.delete(StagePathUtils.getLoadStage(pipelineId, processId), -1, new VoidCallback() {
        //
        // public void processResult(int rc, String path, Object ctx) {
        // logger.debug("delete {} successful. ", path);
        // }
        // }, null);
        // } catch (NoNodeException e) {
        // // ignore,?
        // } catch (KeeperException e) {
        // throw new ArbitrateException("Termin_process", e);
        // } catch (InterruptedException e) {
        // // ignore
        // }

        // transform?s/enormalrollback/shutdown?
        // ?????
        return processDelete(data, CollectionUtils.isEmpty(currentStages), retry);
    }

    private boolean processDelete(TerminEventData data, boolean noStage, boolean retry) {
        Long pipelineId = data.getPipelineId();
        Long processId = data.getProcessId();

        boolean result = false;
        // process
        // ?process
        String path = StagePathUtils.getProcess(pipelineId, processId);
        byte[] bytes = null;
        try {
            bytes = zookeeper.readData(path);
        } catch (ZkNoNodeException e) {
            return false;// ?
        }

        ProcessNodeEventData nodeData = JsonUtils.unmarshalFromByte(bytes, ProcessNodeEventData.class);
        if (nodeData.getStatus().isUsed()) {// true?termin
            // ??

            if (noStage && nodeData.getMode().isZookeeper()) {// rpc modestage??sleep
                // ??case:
                // ????s/e/t/l?delete????delete
                // createTermin???case?
                // ???s????rollback/shutdown????
                processDeleteFailed();
                return processDelete(data, false, retry);// ???process??
            }

            // at 2012-09-06
            // deleteFailed??process?s/e/t/lsleep+retry?
            // sleepprocess?s/e/tprocess??createTermin
            if (!retry) {
                // modify at 2012-08-14 , ??bug
                // 1. process abaprocessb????
                // 2. ?btermin?atermintermin????
                // termin?process?process??termin?
                // ????process?termin?

                // modify at 2012-09-06 , ??bug
                // process??s/e??shutdown??terminprocess delete?processt
                // process?retry?retry??termin?
                // ???retry??termin?
                result = createTermin(data, pipelineId, processId);// termin
            }
        }

        try {
            // false??
            result = zookeeper.deleteRecursive(StagePathUtils.getProcess(pipelineId, processId));
            if (!result) {
                doProcess(data, true);// ????managernodestage?
            }
        } catch (ZkInterruptedException e) {
            throw e;
        } catch (ZkException e) {
            doProcess(data, true);// ????managernodestage?
        }

        return result;
    }

    private boolean createTermin(TerminEventData data, Long pipelineId, Long processId) {
        // 1. end
        String path = StagePathUtils.getTermin(pipelineId, processId);
        data.setCurrNid(ArbitrateConfigUtils.getCurrentNid());
        // ?
        byte[] bytes = JsonUtils.marshalToByte(data);
        try {
            zookeeper.create(path, bytes, CreateMode.PERSISTENT);
        } catch (ZkNodeExistsException e) {
            // ignore
            return false;
        } catch (ZkException e) {
            throw new ArbitrateException("Termin_single", e);
        }

        return true;
    }

    private void processDeleteFailed() {
        try {
            // ?????
            Thread.sleep(500 + RandomUtils.nextInt(500));
        } catch (InterruptedException e) {
            // ignore
        }
    }
}