mirror of https://github.com/apache/activemq.git
tidied up synchronization
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@637028 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
c57bad8711
commit
bbd2e47dbd
|
@ -16,9 +16,9 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.activemq.ra;
|
package org.apache.activemq.ra;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import javax.jms.JMSException;
|
import javax.jms.JMSException;
|
||||||
|
@ -45,8 +45,8 @@ public class ServerSessionPoolImpl implements ServerSessionPool {
|
||||||
private final ActiveMQEndpointWorker activeMQAsfEndpointWorker;
|
private final ActiveMQEndpointWorker activeMQAsfEndpointWorker;
|
||||||
private final int maxSessions;
|
private final int maxSessions;
|
||||||
|
|
||||||
private List<ServerSessionImpl> idleSessions = new CopyOnWriteArrayList<ServerSessionImpl>();
|
private List<ServerSessionImpl> idleSessions = new ArrayList<ServerSessionImpl>();
|
||||||
private List<ServerSessionImpl> activeSessions = new CopyOnWriteArrayList<ServerSessionImpl>();
|
private List<ServerSessionImpl> activeSessions = new ArrayList<ServerSessionImpl>();
|
||||||
private AtomicBoolean closing = new AtomicBoolean(false);
|
private AtomicBoolean closing = new AtomicBoolean(false);
|
||||||
|
|
||||||
public ServerSessionPoolImpl(ActiveMQEndpointWorker activeMQAsfEndpointWorker, int maxSessions) {
|
public ServerSessionPoolImpl(ActiveMQEndpointWorker activeMQAsfEndpointWorker, int maxSessions) {
|
||||||
|
@ -76,7 +76,9 @@ public class ServerSessionPoolImpl implements ServerSessionPool {
|
||||||
} catch (UnavailableException e) {
|
} catch (UnavailableException e) {
|
||||||
// The container could be limiting us on the number of endpoints
|
// The container could be limiting us on the number of endpoints
|
||||||
// that are being created.
|
// that are being created.
|
||||||
LOG.debug("Could not create an endpoint.", e);
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("Could not create an endpoint.", e);
|
||||||
|
}
|
||||||
session.close();
|
session.close();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -92,17 +94,30 @@ public class ServerSessionPoolImpl implements ServerSessionPool {
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
public ServerSession getServerSession() throws JMSException {
|
public ServerSession getServerSession() throws JMSException {
|
||||||
LOG.debug("ServerSession requested.");
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("ServerSession requested.");
|
||||||
|
}
|
||||||
if (closing.get()) {
|
if (closing.get()) {
|
||||||
throw new JMSException("Session Pool Shutting Down.");
|
throw new JMSException("Session Pool Shutting Down.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idleSessions.size() > 0) {
|
ServerSessionImpl ss = null;
|
||||||
ServerSessionImpl ss = idleSessions.remove(idleSessions.size() - 1);
|
synchronized (idleSessions) {
|
||||||
activeSessions.add(ss);
|
if (idleSessions.size() > 0) {
|
||||||
LOG.debug("Using idle session: " + ss);
|
ss = idleSessions.remove(idleSessions.size() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ss != null) {
|
||||||
|
synchronized (activeSessions) {
|
||||||
|
activeSessions.add(ss);
|
||||||
|
}
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("Using idle session: " + ss);
|
||||||
|
}
|
||||||
return ss;
|
return ss;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
synchronized (activeSessions) {
|
||||||
// Are we at the upper limit?
|
// Are we at the upper limit?
|
||||||
if (activeSessions.size() >= maxSessions) {
|
if (activeSessions.size() >= maxSessions) {
|
||||||
// then reuse the already created sessions..
|
// then reuse the already created sessions..
|
||||||
|
@ -110,66 +125,97 @@ public class ServerSessionPoolImpl implements ServerSessionPool {
|
||||||
// processing.
|
// processing.
|
||||||
return getExistingServerSession();
|
return getExistingServerSession();
|
||||||
}
|
}
|
||||||
ServerSessionImpl ss = createServerSessionImpl();
|
|
||||||
// We may not be able to create a session due to the container
|
|
||||||
// restricting us.
|
|
||||||
if (ss == null) {
|
|
||||||
if (activeSessions.size() == 0) {
|
|
||||||
//no idle sessions, no active sessions, and we can't create a new session....
|
|
||||||
throw new JMSException("Endpoint factory did not allow creation of any endpoints.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return getExistingServerSession();
|
|
||||||
}
|
|
||||||
activeSessions.add(ss);
|
|
||||||
LOG.debug("Created a new session: " + ss);
|
|
||||||
return ss;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ss = createServerSessionImpl();
|
||||||
|
// We may not be able to create a session due to the container
|
||||||
|
// restricting us.
|
||||||
|
if (ss == null) {
|
||||||
|
synchronized (activeSessions) {
|
||||||
|
if (activeSessions.isEmpty()) {
|
||||||
|
throw new JMSException(
|
||||||
|
"Endpoint factory did not allow creation any endpoints.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getExistingServerSession();
|
||||||
|
}
|
||||||
|
synchronized (activeSessions) {
|
||||||
|
activeSessions.add(ss);
|
||||||
|
}
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("Created a new session: " + ss);
|
||||||
|
}
|
||||||
|
return ss;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param messageDispatch the message to dispatch
|
* @param messageDispatch
|
||||||
|
* the message to dispatch
|
||||||
* @throws JMSException
|
* @throws JMSException
|
||||||
*/
|
*/
|
||||||
private void dispatchToSession(MessageDispatch messageDispatch) throws JMSException {
|
private void dispatchToSession(MessageDispatch messageDispatch)
|
||||||
|
throws JMSException {
|
||||||
|
|
||||||
ServerSession serverSession = getServerSession();
|
ServerSession serverSession = getServerSession();
|
||||||
Session s = serverSession.getSession();
|
Session s = serverSession.getSession();
|
||||||
ActiveMQSession session = null;
|
ActiveMQSession session = null;
|
||||||
if (s instanceof ActiveMQSession) {
|
if (s instanceof ActiveMQSession) {
|
||||||
session = (ActiveMQSession)s;
|
session = (ActiveMQSession) s;
|
||||||
} else if (s instanceof ActiveMQQueueSession) {
|
} else if (s instanceof ActiveMQQueueSession) {
|
||||||
session = (ActiveMQSession)s;
|
session = (ActiveMQSession) s;
|
||||||
} else if (s instanceof ActiveMQTopicSession) {
|
} else if (s instanceof ActiveMQTopicSession) {
|
||||||
session = (ActiveMQSession)s;
|
session = (ActiveMQSession) s;
|
||||||
} else {
|
} else {
|
||||||
activeMQAsfEndpointWorker.connection.onAsyncException(new JMSException("Session pool provided an invalid session type: " + s.getClass()));
|
activeMQAsfEndpointWorker.connection
|
||||||
|
.onAsyncException(new JMSException(
|
||||||
|
"Session pool provided an invalid session type: "
|
||||||
|
+ s.getClass()));
|
||||||
}
|
}
|
||||||
session.dispatch(messageDispatch);
|
session.dispatch(messageDispatch);
|
||||||
serverSession.start();
|
serverSession.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return
|
* @return session
|
||||||
*/
|
*/
|
||||||
private ServerSession getExistingServerSession() {
|
private ServerSession getExistingServerSession() {
|
||||||
ServerSessionImpl ss = activeSessions.remove(0);
|
ServerSessionImpl ss = null;
|
||||||
activeSessions.add(ss);
|
if (!activeSessions.isEmpty()) {
|
||||||
LOG.debug("Reusing an active session: " + ss);
|
if (activeSessions.size() > 1) {
|
||||||
|
// round robin
|
||||||
|
ss = activeSessions.remove(0);
|
||||||
|
activeSessions.add(ss);
|
||||||
|
} else {
|
||||||
|
ss = activeSessions.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("Reusing an active session: " + ss);
|
||||||
|
}
|
||||||
return ss;
|
return ss;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void returnToPool(ServerSessionImpl ss) {
|
public void returnToPool(ServerSessionImpl ss) {
|
||||||
LOG.debug("Session returned to pool: " + ss);
|
if (LOG.isDebugEnabled()) {
|
||||||
activeSessions.remove(ss);
|
LOG.debug("Session returned to pool: " + ss);
|
||||||
idleSessions.add(ss);
|
}
|
||||||
|
synchronized(activeSessions) {
|
||||||
|
activeSessions.remove(ss);
|
||||||
|
}
|
||||||
|
synchronized(idleSessions) {
|
||||||
|
idleSessions.add(ss);
|
||||||
|
}
|
||||||
synchronized (closing) {
|
synchronized (closing) {
|
||||||
closing.notify();
|
closing.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeFromPool(ServerSessionImpl ss) {
|
public void removeFromPool(ServerSessionImpl ss) {
|
||||||
activeSessions.remove(ss);
|
synchronized(activeSessions) {
|
||||||
|
activeSessions.remove(ss);
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
ActiveMQSession session = (ActiveMQSession)ss.getSession();
|
ActiveMQSession session = (ActiveMQSession)ss.getSession();
|
||||||
List l = session.getUnconsumedMessages();
|
List l = session.getUnconsumedMessages();
|
||||||
|
@ -186,26 +232,35 @@ public class ServerSessionPoolImpl implements ServerSessionPool {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
synchronized (closing) {
|
closing.set(true);
|
||||||
closing.set(true);
|
closeIdleSessions();
|
||||||
closeIdleSessions();
|
// we may have to wait erroneously 250ms if an
|
||||||
while (activeSessions.size() > 0) {
|
// active session is removed during our wait and we
|
||||||
LOG.debug("Active Sessions = " + activeSessions.size());
|
// are not notified
|
||||||
try {
|
while (getActiveSessionSize() > 0) {
|
||||||
closing.wait(1000);
|
if (LOG.isDebugEnabled()) {
|
||||||
} catch (InterruptedException e) {
|
LOG.debug("Active Sessions = " + getActiveSessionSize());
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
closeIdleSessions();
|
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
synchronized (closing) {
|
||||||
|
closing.wait(250);
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
closeIdleSessions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void closeIdleSessions() {
|
private void closeIdleSessions() {
|
||||||
for (Iterator<ServerSessionImpl> iter = idleSessions.iterator(); iter.hasNext();) {
|
synchronized(idleSessions) {
|
||||||
ServerSessionImpl ss = iter.next();
|
for (Iterator<ServerSessionImpl> iter = idleSessions.iterator(); iter.hasNext();) {
|
||||||
ss.close();
|
ServerSessionImpl ss = iter.next();
|
||||||
|
ss.close();
|
||||||
|
}
|
||||||
|
idleSessions.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,12 +270,18 @@ public class ServerSessionPoolImpl implements ServerSessionPool {
|
||||||
public boolean isClosing() {
|
public boolean isClosing() {
|
||||||
return closing.get();
|
return closing.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param closing The closing to set.
|
* @param closing The closing to set.
|
||||||
*/
|
*/
|
||||||
public void setClosing(boolean closing) {
|
public void setClosing(boolean closing) {
|
||||||
this.closing.set(closing);
|
this.closing.set(closing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getActiveSessionSize() {
|
||||||
|
synchronized(activeSessions) {
|
||||||
|
return activeSessions.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue