/** * $Id: PullAPIWrapper.java 1831 2013-05-16 01:39:51Z shijia.wxr $ */ package com.alibaba.rocketmq.client.impl.consumer; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import com.alibaba.rocketmq.client.consumer.PullCallback; import com.alibaba.rocketmq.client.consumer.ConsumeFromWhichNode; import com.alibaba.rocketmq.client.consumer.PullResult; import com.alibaba.rocketmq.client.exception.MQBrokerException; import com.alibaba.rocketmq.client.exception.MQClientException; import com.alibaba.rocketmq.client.impl.CommunicationMode; import com.alibaba.rocketmq.client.impl.FindBrokerResult; import com.alibaba.rocketmq.client.impl.factory.MQClientFactory; import com.alibaba.rocketmq.common.MessageQueue; import com.alibaba.rocketmq.common.protocol.header.PullMessageRequestHeader; import com.alibaba.rocketmq.common.sysflag.PullSysFlag; import com.alibaba.rocketmq.remoting.exception.RemotingException; /** * ��Pull�ӿڽ��н�һ���ķ�װ * * @author vintage.wang@gmail.com shijia.wxr@taobao.com * */ public class PullAPIWrapper { private ConcurrentHashMap<MessageQueue, AtomicBoolean/* suggestPullingFromSlave */> pullFromWhichNodeTable = new ConcurrentHashMap<MessageQueue, AtomicBoolean>(32); private final MQClientFactory mQClientFactory; private final String consumerGroup; private final ConsumeFromWhichNode consumeFromWhichNode; public PullAPIWrapper(MQClientFactory mQClientFactory, String consumerGroup, final ConsumeFromWhichNode pullFromWhere) { this.mQClientFactory = mQClientFactory; this.consumerGroup = consumerGroup; this.consumeFromWhichNode = pullFromWhere; } public void updatePullFromWhichNode(final MessageQueue mq, final boolean suggestPullingFromSlave) { AtomicBoolean suggest = this.pullFromWhichNodeTable.get(mq); if (null == suggest) { this.pullFromWhichNodeTable.put(mq, new AtomicBoolean(suggestPullingFromSlave)); } else { suggest.set(suggestPullingFromSlave); } } /** * ÿ�����ж�Ӧ������Ӧ�ı�����������ĸ��������� */ public ConsumeFromWhichNode recalculatePullFromWhichNode(final MessageQueue mq) { switch (this.consumeFromWhichNode) { case CONSUME_FROM_MASTER_FIRST: AtomicBoolean suggest = this.pullFromWhichNodeTable.get(mq); if (suggest != null) { if (suggest.get()) { return ConsumeFromWhichNode.CONSUME_FROM_SLAVE_FIRST; } } return ConsumeFromWhichNode.CONSUME_FROM_MASTER_FIRST; default: break; } return this.consumeFromWhichNode; } public PullResult pullKernelImpl(// final MessageQueue mq,// 1 final String subExpression,// 2 final long offset,// 3 final int maxNums,// 4 final int sysFlag,// 5 final long commitOffset,// 6 final long brokerSuspendMaxTimeMillis,// 7 final long timeoutMillis,// 8 final CommunicationMode communicationMode,// 9 final PullCallback pullCallback// 10 ) throws MQClientException, RemotingException, MQBrokerException, InterruptedException { FindBrokerResult findBrokerResult = this.mQClientFactory.findBrokerAddressInSubscribe(mq.getBrokerName(), this.recalculatePullFromWhichNode(mq)); if (null == findBrokerResult) { // TODO �˴����ܶ�Name Serverѹ��������Ҫ���� this.mQClientFactory.updateTopicRouteInfoFromNameServer(mq.getTopic()); findBrokerResult = this.mQClientFactory.findBrokerAddressInSubscribe(mq.getBrokerName(), this.recalculatePullFromWhichNode(mq)); } if (findBrokerResult != null) { int sysFlagInner = sysFlag; // Slave������ʵʱ�ύ���ѽ��ȣ����Զ�ʱ�ύ if (findBrokerResult.isSlave()) { sysFlagInner = PullSysFlag.clearCommitOffsetFlag(sysFlagInner); } PullMessageRequestHeader requestHeader = new PullMessageRequestHeader(); requestHeader.setConsumerGroup(this.consumerGroup); requestHeader.setTopic(mq.getTopic()); requestHeader.setQueueId(mq.getQueueId()); requestHeader.setQueueOffset(offset); requestHeader.setMaxMsgNums(maxNums); requestHeader.setSysFlag(sysFlagInner); requestHeader.setCommitOffset(commitOffset); requestHeader.setSuspendTimeoutMillis(brokerSuspendMaxTimeMillis); requestHeader.setSubscription(subExpression); PullResult pullResult = this.mQClientFactory.getMQClientAPIImpl().pullMessage(// findBrokerResult.getBrokerAddr(),// requestHeader,// timeoutMillis,// communicationMode,// pullCallback); return pullResult; } throw new MQClientException("The broker[" + mq.getBrokerName() + "] not exist", null); } }