private void returnResponse( final String group, final String topic, ChannelHandlerContext ctx, final RemotingCommand response, final List<MessageExt> msgList) { if (null != msgList) { ByteBuffer[] msgBufferList = new ByteBuffer[msgList.size()]; int bodyTotalSize = 0; for (int i = 0; i < msgList.size(); i++) { try { msgBufferList[i] = messageToByteBuffer(msgList.get(i)); bodyTotalSize += msgBufferList[i].capacity(); } catch (Exception e) { log.error("messageToByteBuffer UnsupportedEncodingException", e); } } ByteBuffer body = ByteBuffer.allocate(bodyTotalSize); for (ByteBuffer bb : msgBufferList) { bb.flip(); body.put(bb); } response.setBody(body.array()); // 统计 this.filtersrvController .getFilterServerStatsManager() .incGroupGetNums(group, topic, msgList.size()); this.filtersrvController .getFilterServerStatsManager() .incGroupGetSize(group, topic, bodyTotalSize); } try { ctx.writeAndFlush(response) .addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { log.error( "FilterServer response to " + future.channel().remoteAddress() + " failed", future.cause()); log.error(response.toString()); } } }); } catch (Throwable e) { log.error("FilterServer process request over, but response failed", e); log.error(response.toString()); } }
public void processResponseCommand(ChannelHandlerContext ctx, RemotingCommand cmd) { final ResponseFuture responseFuture = responseTable.get(cmd.getOpaque()); if (responseFuture != null) { responseFuture.setResponseCommand(cmd); responseFuture.release(); // 异步调用 if (responseFuture.getInvokeCallback() != null) { boolean runInThisThread = false; ExecutorService executor = this.getCallbackExecutor(); if (executor != null) { try { executor.submit( new Runnable() { @Override public void run() { try { responseFuture.executeInvokeCallback(); } catch (Throwable e) { plog.warn("excute callback in executor exception, and callback throw", e); } } }); } catch (Exception e) { runInThisThread = true; plog.warn("excute callback in executor exception, maybe executor busy", e); } } else { runInThisThread = true; } if (runInThisThread) { try { responseFuture.executeInvokeCallback(); } catch (Throwable e) { plog.warn("executeInvokeCallback Exception", e); } } } // 同步调用 else { responseFuture.putResponse(cmd); } } else { plog.warn( "receive response, but not matched any request, " + RemotingHelper.parseChannelRemoteAddr(ctx.channel())); plog.warn(cmd.toString()); } responseTable.remove(cmd.getOpaque()); }
public void invokeOnewayImpl( final Channel channel, final RemotingCommand request, final long timeoutMillis) throws InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException { request.markOnewayRPC(); boolean acquired = this.semaphoreOneway.tryAcquire(timeoutMillis, TimeUnit.MILLISECONDS); if (acquired) { final SemaphoreReleaseOnlyOnce once = new SemaphoreReleaseOnlyOnce(this.semaphoreOneway); try { channel .writeAndFlush(request) .addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture f) throws Exception { once.release(); if (!f.isSuccess()) { plog.warn( "send a request command to channel <" + channel.remoteAddress() + "> failed."); plog.warn(request.toString()); } } }); } catch (Exception e) { once.release(); plog.warn( "write send a request command to channel <" + channel.remoteAddress() + "> failed."); throw new RemotingSendRequestException(RemotingHelper.parseChannelRemoteAddr(channel), e); } } else { if (timeoutMillis <= 0) { throw new RemotingTooMuchRequestException("invokeOnewayImpl invoke too fast"); } else { String info = String.format( "invokeOnewayImpl tryAcquire semaphore timeout, %dms, waiting thread nums: %d semaphoreAsyncValue: %d", // timeoutMillis, // this.semaphoreAsync.getQueueLength(), // this.semaphoreAsync.availablePermits() // ); plog.warn(info); plog.warn(request.toString()); throw new RemotingTimeoutException(info); } } }
public void invokeAsyncImpl( final Channel channel, final RemotingCommand request, final long timeoutMillis, final InvokeCallback invokeCallback) throws InterruptedException, RemotingTooMuchRequestException, RemotingTimeoutException, RemotingSendRequestException { boolean acquired = this.semaphoreAsync.tryAcquire(timeoutMillis, TimeUnit.MILLISECONDS); if (acquired) { final SemaphoreReleaseOnlyOnce once = new SemaphoreReleaseOnlyOnce(this.semaphoreAsync); final ResponseFuture responseFuture = new ResponseFuture(request.getOpaque(), timeoutMillis, invokeCallback, once); this.responseTable.put(request.getOpaque(), responseFuture); try { channel .writeAndFlush(request) .addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture f) throws Exception { if (f.isSuccess()) { responseFuture.setSendRequestOK(true); return; } else { responseFuture.setSendRequestOK(false); } responseFuture.putResponse(null); responseTable.remove(request.getOpaque()); try { responseFuture.executeInvokeCallback(); } catch (Throwable e) { plog.warn( "excute callback in writeAndFlush addListener, and callback throw", e); } finally { responseFuture.release(); } plog.warn( "send a request command to channel <{}> failed.", RemotingHelper.parseChannelRemoteAddr(channel)); plog.warn(request.toString()); } }); } catch (Exception e) { responseFuture.release(); plog.warn( "send a request command to channel <" + RemotingHelper.parseChannelRemoteAddr(channel) + "> Exception", e); throw new RemotingSendRequestException(RemotingHelper.parseChannelRemoteAddr(channel), e); } } else { if (timeoutMillis <= 0) { throw new RemotingTooMuchRequestException("invokeAsyncImpl invoke too fast"); } else { String info = String.format( "invokeAsyncImpl tryAcquire semaphore timeout, %dms, waiting thread nums: %d semaphoreAsyncValue: %d", // timeoutMillis, // this.semaphoreAsync.getQueueLength(), // this.semaphoreAsync.availablePermits() // ); plog.warn(info); plog.warn(request.toString()); throw new RemotingTimeoutException(info); } } }