001 /**
002 *
003 * Copyright 2004 Protique Ltd
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 *
017 **/
018
019 package org.activemq;
020
021 import java.util.Iterator;
022
023 import javax.jms.JMSException;
024
025 import org.activemq.io.util.MemoryBoundedQueue;
026 import org.activemq.message.ActiveMQMessage;
027
028 /**
029 * A utility class used by the Session for dispatching messages asynchronously to consumers
030 *
031 * @version $Revision: 1.1.1.1 $
032 * @see javax.jms.Session
033 */
034 public class ActiveMQSessionExecutor implements Runnable {
035 private ActiveMQSession session;
036 private MemoryBoundedQueue messageQueue;
037 private boolean closed;
038 private Thread runner;
039 private boolean dispatchedBySessionPool;
040 private boolean optimizedMessageDispatch;
041
042 ActiveMQSessionExecutor(ActiveMQSession session, MemoryBoundedQueue queue) {
043 this.session = session;
044 this.messageQueue = queue;
045 }
046
047 void setDispatchedBySessionPool(boolean value) {
048 dispatchedBySessionPool = value;
049 }
050
051 /**
052 * @return Returns the optimizedMessageDispatch.
053 */
054 boolean isOptimizedMessageDispatch() {
055 return optimizedMessageDispatch;
056 }
057 /**
058 * @param optimizedMessageDispatch The optimizedMessageDispatch to set.
059 */
060 void setOptimizedMessageDispatch(boolean optimizedMessageDispatch) {
061 this.optimizedMessageDispatch = optimizedMessageDispatch;
062 }
063
064 void execute(ActiveMQMessage message) {
065 if (optimizedMessageDispatch && !dispatchedBySessionPool){
066 dispatch(message);
067 }else {
068 messageQueue.enqueue(message);
069 }
070
071 }
072
073 void executeFirst(ActiveMQMessage message) {
074 messageQueue.enqueueFirstNoBlock(message);
075 }
076
077 boolean hasUncomsumedMessages() {
078 return !messageQueue.isEmpty();
079 }
080
081 /**
082 * implementation of Runnable
083 */
084 public void run() {
085 while (!closed && !dispatchedBySessionPool) {
086 ActiveMQMessage message = null;
087 try {
088 message = (ActiveMQMessage) messageQueue.dequeue(100);
089 }
090 catch (InterruptedException ie) {
091 }
092 if (!closed) {
093 if (message != null) {
094 if (!dispatchedBySessionPool) {
095 dispatch(message);
096 }
097 else {
098 messageQueue.enqueueFirstNoBlock(message);
099 }
100 }
101 }
102 }
103 }
104
105 void dispatch(ActiveMQMessage message){
106 for (Iterator i = this.session.consumers.iterator(); i.hasNext();) {
107 ActiveMQMessageConsumer consumer = (ActiveMQMessageConsumer) i.next();
108 if (message.isConsumerTarget(consumer.getConsumerNumber())) {
109 try {
110 consumer.processMessage(message.shallowCopy());
111 }
112 catch (JMSException e) {
113 this.session.connection.handleAsyncException(e);
114 }
115 }
116 }
117 }
118
119 synchronized void start() {
120 messageQueue.start();
121 if (runner == null && (!dispatchedBySessionPool || optimizedMessageDispatch)) {
122 runner = new Thread(this, "JmsSessionDispatcher: " + session.getSessionId());
123 runner.setPriority(Thread.MAX_PRIORITY);
124 //runner.setDaemon(true);
125 runner.start();
126 }
127 }
128
129 synchronized void stop() {
130 messageQueue.stop();
131 }
132
133 synchronized void close() {
134 closed = true;
135 messageQueue.close();
136 }
137
138 void clear() {
139 messageQueue.clear();
140 }
141
142 ActiveMQMessage dequeueNoWait() {
143 try {
144 return (ActiveMQMessage) messageQueue.dequeueNoWait();
145 }
146 catch (InterruptedException ie) {
147 return null;
148 }
149 }
150
151 protected void clearMessagesInProgress(){
152 messageQueue.clear();
153 }
154
155
156 }