Package com.taobao.metamorphosis.metaslave

Source Code of com.taobao.metamorphosis.metaslave.SlaveOffsetStorage

/*
* (C) 2007-2012 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.
* Authors:
*   wuhua <wq163@163.com>
*/
package com.taobao.metamorphosis.metaslave;

import java.util.Collection;

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

import com.taobao.gecko.core.util.OpaqueGenerator;
import com.taobao.gecko.service.exception.NotifyRemotingException;
import com.taobao.metamorphosis.client.RemotingClientWrapper;
import com.taobao.metamorphosis.client.consumer.TopicPartitionRegInfo;
import com.taobao.metamorphosis.client.consumer.storage.OffsetStorage;
import com.taobao.metamorphosis.cluster.Partition;
import com.taobao.metamorphosis.exception.NetworkException;
import com.taobao.metamorphosis.network.BooleanCommand;
import com.taobao.metamorphosis.network.HttpStatus;
import com.taobao.metamorphosis.network.OffsetCommand;
import com.taobao.metamorphosis.server.assembly.MetaMorphosisBroker;
import com.taobao.metamorphosis.server.store.MessageStore;
import com.taobao.metamorphosis.server.store.MessageStoreManager;


/**
* ��slave��Ϣ�ļ���load offset,ûload��ʱ��master��ѯ��Сoffset
*
* @author �޻�
* @since 2011-6-27 ����10:09:38
*/
public class SlaveOffsetStorage implements OffsetStorage {
    private final static Log log = LogFactory.getLog(SlaveOffsetStorage.class);
    private final MetaMorphosisBroker broker;
    private final RemotingClientWrapper remotingClient;
    private final SlaveZooKeeper slaveZooKeeper;


    public SlaveOffsetStorage(final MetaMorphosisBroker broker, final SlaveZooKeeper slaveZooKeeper,
            final RemotingClientWrapper remotingClient) {
        this.broker = broker;
        this.remotingClient = remotingClient;
        this.slaveZooKeeper = slaveZooKeeper;
    }


    @Override
    public void close() {
        final String masterServerUrl = this.slaveZooKeeper.getMasterServerUrl();
        try {
            if (!StringUtils.isBlank(masterServerUrl)) {
                this.remotingClient.closeWithRef(masterServerUrl, this, true);
            }
        }
        catch (NotifyRemotingException e) {
            // ignore;
        }
    }


    @Override
    public void commitOffset(final String group, final Collection<TopicPartitionRegInfo> infoList) {
        // do nothing
    }


    @Override
    public void initOffset(final String topic, final String group, final Partition partition, final long offset) {
        // do nothing
    }

    private static String offsetFormat = "topic=%s,group=%s,partition=%s,offset=%s";


    @Override
    public TopicPartitionRegInfo load(final String topic, final String group, final Partition partition) {
        // �ȴӱ��ز�ѯ
        final MessageStoreManager storeManager = this.broker.getStoreManager();
        final MessageStore messageStore = storeManager.getMessageStore(topic, partition.getPartition());
        if (messageStore != null) {
            log.info("load offset from local"
                    + String.format(offsetFormat, topic, group, partition.getPartition(), messageStore.getSizeInBytes()));
            return new TopicPartitionRegInfo(topic, partition, messageStore.getMinOffset()
                + messageStore.getSizeInBytes());
        }
        else {
            final String masterServerUrl = this.slaveZooKeeper.getMasterServerUrl();
            if (StringUtils.isBlank(masterServerUrl)) {
                throw new NullPointerException("masterServerUrl is empty");
            }

            try {
                final long offset = this.queryOffsetInMaster(masterServerUrl, partition, topic);
                log.info("load offset from master,"
                        + String.format(offsetFormat, topic, group, partition.getPartition(), offset));
                return new TopicPartitionRegInfo(topic, partition, offset);
            }
            catch (final Exception e) {
                if (e instanceof InterruptedException) {
                    Thread.currentThread().interrupt();
                }
                throw new RuntimeException("load offset fail,", e);
            }
        }
    }


    /** ��ȷ�鵽offsetʱ����,������׳��쳣 */
    long queryOffsetInMaster(final String masterServerUrl, final Partition partition, final String topic)
            throws NetworkException, InterruptedException {

        // �ڿͻ��˶�����Ϣǰ����û���ӵ�������
        if (!this.remotingClient.isConnected(masterServerUrl)) {
            log.info("try connect to " + masterServerUrl);
            this.connectServer(masterServerUrl);
        }
        try {
            final BooleanCommand resp =
                    (BooleanCommand) this.remotingClient.invokeToGroup(masterServerUrl, new OffsetCommand(topic,
                        this.broker.getMetaConfig().getSlaveConfig().getSlaveGroup(), partition.getPartition(), 0,
                        OpaqueGenerator.getNextOpaque()));

            final String resultStr = resp.getErrorMsg();

            switch (resp.getCode()) {
            case HttpStatus.Success: {
                return Long.parseLong(resultStr);
            }
            case HttpStatus.NotFound: {
                // ��master��û���յ�һ�����topic����Ϣʱ,Ŀ¼��û����.����Ĭ��offsetΪ0����
                return 0;
            }
            default:
                throw new RuntimeException("failed to query offset form " + masterServerUrl + ",topic=" + topic
                    + ",partition=" + partition.getPartition() + ",httpCode=" + resp.getCode() + ",errorMessage="
                    + resultStr);
            }

        }
        catch (final InterruptedException e) {
            throw e;
        }
        catch (final Exception e) {
            throw new NetworkException("failed to query offset form " + masterServerUrl + ",topic=" + topic
                + ",partition=" + partition.getPartition(), e);
        }
    }


    private void connectServer(final String serverUrl) throws NetworkException, InterruptedException {
        try {
            this.remotingClient.connectWithRef(serverUrl, this);
            this.remotingClient.awaitReadyInterrupt(serverUrl, 5000);
            // 5�������Ӳ�������Ϊ�����û����
            // ,��ϲ�ѯ
        }
        catch (final NotifyRemotingException e) {
            throw new NetworkException("Connect to " + serverUrl + " failed", e);
        }
        catch (final InterruptedException e) {
            throw e;
        }
    }

}
TOP

Related Classes of com.taobao.metamorphosis.metaslave.SlaveOffsetStorage

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.