/*
* (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> , boyan <killme2008@gmail.com>
*/
package com.taobao.metamorphosis.client.extension.producer;
import java.util.concurrent.TimeUnit;
import com.taobao.metamorphosis.Message;
import com.taobao.metamorphosis.client.producer.SendResult;
import com.taobao.metamorphosis.cluster.Partition;
import com.taobao.metamorphosis.exception.MetaClientException;
/**
*
* @author ��
* @since 2011-8-9 ����6:12:01
*/
class OrderedMessageSender {
private final OrderedMessageProducer producer;
OrderedMessageSender(OrderedMessageProducer producer) {
this.producer = producer;
}
SendResult sendMessage(Message message, long timeout, TimeUnit unit) throws MetaClientException,
InterruptedException {
int maxRecheck = 3;
int check = 1;
for (;;) {
SelectPartitionResult result = this.trySelectPartition(message);
// ���÷���������
if (!result.isPartitionWritable()) {
return this.producer.saveMessageToLocal(message, result.getSelectedPartition(), timeout, unit);
}
// ���÷�������
else {
int localMessageCount =
this.producer.getLocalMessageCount(message.getTopic(), result.getSelectedPartition());
if (localMessageCount > 0) {
this.producer.tryRecoverMessage(message.getTopic(), result.getSelectedPartition());
}
if (localMessageCount <= 0) {
// ���ش����Ϣ����Ϊ��,������Ϣ���͵������
return this.producer.sendMessageToServer(message, timeout, unit, true);
}
else if (localMessageCount > 0 && localMessageCount <= 20) {
// ���ش����Ϣֻ����������,ͣ��һ�µȴ�������Ϣ���ָ�,`�ټ������״̬,
// �����maxRecheck�� ������Ϣ��û���ָ���,�汾�ز��˳�.
if (check >= maxRecheck) {
return this.producer.saveMessageToLocal(message, result.getSelectedPartition(), timeout, unit);
}
Thread.sleep(100L);
}
else {
// ���ش����Ϣ���кܶ�,����д����
return this.producer.saveMessageToLocal(message, result.getSelectedPartition(), timeout, unit);
}
}
check++;
}// end for
}
private SelectPartitionResult trySelectPartition(Message message) throws MetaClientException {
SelectPartitionResult result = new SelectPartitionResult();
try {
Partition partition = this.producer.selectPartition(message);
if (partition == null) {
throw new MetaClientException("selected null partition");
}
result.setSelectedPartition(partition);
result.setPartitionWritable(true);
}
catch (AvailablePartitionNumException e) {
String msg = e.getMessage();
String partitionStr = msg.substring(msg.indexOf("[") + 1, msg.indexOf("]"));
result.setSelectedPartition(new Partition(partitionStr));
result.setPartitionWritable(false);
}
catch (MetaClientException e) {
throw e;
}
return result;
}
private static class SelectPartitionResult {
private boolean partitionWritable;
private Partition selectedPartition;
public boolean isPartitionWritable() {
return this.partitionWritable;
}
public void setPartitionWritable(boolean partitionWritable) {
this.partitionWritable = partitionWritable;
}
public Partition getSelectedPartition() {
return this.selectedPartition;
}
public void setSelectedPartition(Partition selectedPartition) {
this.selectedPartition = selectedPartition;
}
}
}