+ ",it closed,");
return new BooleanCommand(HttpStatus.Forbidden, "Partition[" + this.metaConfig.getBrokerId() + "-"
+ request.getPartition() + "] has been closed", request.getOpaque());
}
final MessageStore store = this.storeManager.getMessageStore(topic, request.getPartition());
if (store == null) {
this.statsManager.statsGetMiss(topic, group, 1);
return new BooleanCommand(HttpStatus.NotFound, "The topic `" + topic + "` in partition `"
+ request.getPartition() + "` is not exists", request.getOpaque());
}
if (request.getMaxSize() <= 0) {
return new BooleanCommand(HttpStatus.BadRequest, "Bad request,invalid max size:" + request.getMaxSize(),
request.getOpaque());
}
try {
final MessageSet set =
store.slice(request.getOffset(),
Math.min(this.metaConfig.getMaxTransferSize(), request.getMaxSize()));
ConsumerMessageFilter filter = this.consumerFilterManager.findFilter(topic, group);
if (set != null) {
if (zeroCopy && filter == null) {
set.write(request, ctx);
return null;
}
else {
// refer to the code of line 440 in MessageStore
// create two copies of byte array including the byteBuffer
// and new bytes
// this may not a good use case of Buffer
final ByteBuffer byteBuffer =
ByteBuffer.allocate(Math.min(this.metaConfig.getMaxTransferSize(), request.getMaxSize()));
set.read(byteBuffer);
byte[] bytes = this.getBytesFromBuffer(byteBuffer);
// If filter is not null,we filter the messages by it.
if (filter != null) {
MessageIterator it = new MessageIterator(topic, bytes);
// reuse the buffer.
byteBuffer.clear();
while (it.hasNext()) {
Message msg = it.next();
try {
if (filter.accept(group, msg)) {
ByteBuffer msgBuf = it.getCurrentMsgBuf();
// Append current message buffer to result
// buffer.
byteBuffer.put(msgBuf);
}
}
catch (Exception e) {
log.error("Filter message for consumer failed,topic=" + topic + ",group=" + group
+ ",filterClass=" + filter.getClass().getCanonicalName(), e);
}
}
// re-new the byte array.
bytes = this.getBytesFromBuffer(byteBuffer);
// All these messages are not acceptable,move forward
// offset.
if (bytes.length == 0) {
return new BooleanCommand(HttpStatus.Moved, String.valueOf(request.getOffset()
+ it.getOffset()), request.getOpaque());
}
}
return new DataCommand(bytes, request.getOpaque(), true);
}
}
else {
this.statsManager.statsGetMiss(topic, group, 1);
this.statsManager.statsGetFailed(topic, group, 1);
// �������ƫ��������ʵ�����ֵʱ,���ظ��ͻ���ʵ������ƫ����.
final long maxOffset = store.getMaxOffset();
final long requestOffset = request.getOffset();
if (requestOffset > maxOffset
&& (this.metaConfig.isUpdateConsumerOffsets() || requestOffset == Long.MAX_VALUE)) {
log.info("offset[" + requestOffset + "] is exceeded,tell the client real max offset: " + maxOffset
+ ",topic=" + topic + ",group=" + group);
this.statsManager.statsOffset(topic, group, 1);
return new BooleanCommand(HttpStatus.Moved, String.valueOf(maxOffset), request.getOpaque());
}
else {
return new BooleanCommand(HttpStatus.NotFound, "Could not find message at position "
+ requestOffset, request.getOpaque());
}
}
}
catch (final ArrayIndexOutOfBoundsException e) {
log.error("Could not get message from position " + request.getOffset() + ",it is out of bounds,topic="
+ topic);
// ��֪������õ�offset
this.statsManager.statsGetMiss(topic, group, 1);
this.statsManager.statsGetFailed(topic, group, 1);
final long validOffset = store.getNearestOffset(request.getOffset());
this.statsManager.statsOffset(topic, group, 1);
return new BooleanCommand(HttpStatus.Moved, String.valueOf(validOffset), request.getOpaque());
}
catch (final Throwable e) {