📄 messagedispatchinterceptor.java
字号:
/* * Copyright 1999,2004 The Apache Software Foundation. * * 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 */package org.apache.catalina.tribes.group.interceptors;import java.util.concurrent.atomic.AtomicLong;import org.apache.catalina.tribes.Channel;import org.apache.catalina.tribes.ChannelException;import org.apache.catalina.tribes.ChannelMessage;import org.apache.catalina.tribes.Member;import org.apache.catalina.tribes.group.ChannelInterceptorBase;import org.apache.catalina.tribes.group.InterceptorPayload;import org.apache.catalina.tribes.transport.bio.util.FastQueue;import org.apache.catalina.tribes.transport.bio.util.LinkObject;/** * * The message dispatcher is a way to enable asynchronous communication * through a channel. The dispatcher will look for the <code>Channel.SEND_OPTIONS_ASYNCHRONOUS</code> * flag to be set, if it is, it will queue the message for delivery and immediately return to the sender. * * * * @author Filip Hanik * @version 1.0 */public class MessageDispatchInterceptor extends ChannelInterceptorBase implements Runnable { private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(MessageDispatchInterceptor.class); private long maxQueueSize = 1024*1024*64; //64MB private FastQueue queue = new FastQueue(); private boolean run = false; private Thread msgDispatchThread = null; private AtomicLong currentSize = new AtomicLong(0); private boolean useDeepClone = false; public void sendMessage(Member[] destination, ChannelMessage msg, InterceptorPayload payload) throws ChannelException { boolean async = (msg.getOptions() & Channel.SEND_OPTIONS_ASYNCHRONOUS) == Channel.SEND_OPTIONS_ASYNCHRONOUS; if ( async && run ) { if ( (currentSize.get()+msg.getMessage().getLength()) > maxQueueSize ) throw new ChannelException("Asynchronous queue is full, reached its limit of "+maxQueueSize+" bytes, current:"+currentSize+" bytes."); //add to queue if ( useDeepClone ) msg = (ChannelMessage)msg.deepclone(); if (!queue.add(msg, destination, payload) ) { throw new ChannelException("Unable to add the message to the async queue, queue bug?"); } currentSize.addAndGet(msg.getMessage().getLength()); } else { super.sendMessage(destination, msg, payload); } } public void setMaxQueueSize(long maxQueueSize) { this.maxQueueSize = maxQueueSize; } public void setUseDeepClone(boolean useDeepClone) { this.useDeepClone = useDeepClone; } public long getMaxQueueSize() { return maxQueueSize; } public boolean getUseDeepClone() { return useDeepClone; } public void start(int svc) throws ChannelException { //start the thread if (!run ) { synchronized (this) { if ( !run ) { msgDispatchThread = new Thread(this); msgDispatchThread.setName("MessageDispatchThread"); msgDispatchThread.setDaemon(true); msgDispatchThread.setPriority(Thread.MAX_PRIORITY); queue.setEnabled(true); run = true; msgDispatchThread.start(); }//end if }//sync }//end if super.start(svc); } public void stop(int svc) throws ChannelException { //stop the thread if ( run ) { synchronized (this) { if ( run ) { run = false; queue.setEnabled(false); msgDispatchThread.interrupt(); currentSize = new AtomicLong(0); }//end if }//sync }//end if super.stop(svc); } public void run() { while ( run ) { LinkObject link = queue.remove(); if ( link == null ) continue; //should not happen unless we exceed wait time while ( link != null && run ) { ChannelMessage msg = link.data(); Member[] destination = link.getDestination(); try { super.sendMessage(destination,msg,null); try { if ( link.getHandler() != null ) link.getHandler().handleCompletion(destination,msg); } catch ( Exception ex ) { log.error("Unable to report back completed message.",ex); } } catch ( Exception x ) { if ( log.isDebugEnabled() ) log.debug("Error while processing async message.",x); try { if (link.getHandler() != null) link.getHandler().handleError(x, destination, msg); } catch ( Exception ex ) { log.error("Unable to report back error message.",ex); } } finally { currentSize.addAndGet(-msg.getMessage().getLength()); link = link.next(); }//try }//while }//while }//run}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -