[jboss-cvs] JBoss Messaging SVN: r7478 - in branches/Branch_MultiThreaded_Replication: src/main/org/jboss/messaging/core/client/impl and 27 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Fri Jun 26 05:46:36 EDT 2009
Author: timfox
Date: 2009-06-26 05:46:34 -0400 (Fri, 26 Jun 2009)
New Revision: 7478
Added:
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/replication/ReplicateLockSequenceMessage.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/replication/ReplicationResponseMessage.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/ReplicableAction.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/Replicator.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/JBMThread.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/PriorityLock.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/ReplicatorImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/StatefulObjectReadWriteLock.java
branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/unit/core/server/replication/
branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/unit/core/server/replication/impl/
branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/unit/core/server/replication/impl/NewSequencedLockTest.java
Removed:
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/ReplicateCreateSessionMessage.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/replication/SessionReplicateDeliveryMessage.java
Modified:
branches/Branch_MultiThreaded_Replication/src/config/trunk/non-clustered/logging.properties
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/client/impl/ClientSessionImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/exception/MessagingException.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/ManagementService.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/impl/ManagementServiceImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/impl/MessagingServerControlImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/impl/QueueControlImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/paging/impl/PagingStoreImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/persistence/impl/journal/JournalStorageManager.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/persistence/impl/nullpm/NullStorageManager.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/AddressManager.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/PostOffice.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/impl/PostOfficeImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/impl/SimpleAddressManager.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/impl/WildcardAddressManager.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/Channel.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/RemotingConnection.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/ChannelImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/PacketDecoder.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/RemotingConnectionImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/invm/InVMConnection.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/PacketImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/server/impl/RemotingServiceImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/MessagingServer.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/Queue.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/ServerConsumer.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/ServerSession.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/BridgeImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/ClusterConnectionImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/ClusterManagerImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/Redistributor.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/LastValueQueue.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/MessagingServerImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/MessagingServerPacketHandler.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/QueueFactoryImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/QueueImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/ServerConsumerImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/ServerSessionImpl.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/ServerSessionPacketHandler.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/integration/logging/JBMLoggerFormatter.java
branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/utils/JBMThreadFactory.java
branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/integration/cluster/failover/SimpleAutomaticFailoverTest.java
branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/BindingImplTest.java
branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/unit/core/server/impl/QueueImplTest.java
Log:
mt replication commit 1
Modified: branches/Branch_MultiThreaded_Replication/src/config/trunk/non-clustered/logging.properties
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/config/trunk/non-clustered/logging.properties 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/config/trunk/non-clustered/logging.properties 2009-06-26 09:46:34 UTC (rev 7478)
@@ -20,7 +20,7 @@
java.util.logging.FileHandler.level=INFO
java.util.logging.FileHandler.formatter=org.jboss.messaging.integration.logging.JBMLoggerFormatter
java.util.logging.FileHandler.pattern=logs/messaging.log
-java.util.logging.FileHandler.limit=10000
+java.util.logging.FileHandler.limit=0
# Default global logging level.
# This specifies which kinds of events are logged across
# all loggers. For any given facility this global level
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/client/impl/ClientSessionImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/client/impl/ClientSessionImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/client/impl/ClientSessionImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -721,7 +721,7 @@
try
{
- channel.transferConnection(backupConnection, channel.getID(), null);
+ channel.transferConnection(backupConnection);
backupConnection.syncIDGeneratorSequence(remotingConnection.getIDGeneratorSequence());
@@ -735,7 +735,7 @@
if (!response.isRemoved())
{
- channel.replayCommands(response.getLastReceivedCommandID(), channel.getID());
+ channel.replayCommands(response.getLastReceivedCommandID());
ok = true;
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/exception/MessagingException.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/exception/MessagingException.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/exception/MessagingException.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -22,6 +22,8 @@
package org.jboss.messaging.core.exception;
+import org.jboss.messaging.core.logging.Logger;
+
/**
*
* A MessagingException
@@ -32,7 +34,10 @@
public class MessagingException extends Exception
{
private static final long serialVersionUID = -4802014152804997417L;
+
+ private static final Logger log = Logger.getLogger(MessagingException.class);
+
// Error codes -------------------------------------------------
public static final int INTERNAL_ERROR = 000;
@@ -110,6 +115,8 @@
public MessagingException(int code, String msg)
{
super(msg);
+
+ // log.info("Creating new messagingexception", new Exception());
this.code = code;
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/ManagementService.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/ManagementService.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/ManagementService.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -37,6 +37,7 @@
import org.jboss.messaging.core.management.impl.MessagingServerControlImpl;
import org.jboss.messaging.core.messagecounter.MessageCounterManager;
import org.jboss.messaging.core.persistence.StorageManager;
+import org.jboss.messaging.core.postoffice.ClusterQueueStateManager;
import org.jboss.messaging.core.postoffice.PostOffice;
import org.jboss.messaging.core.remoting.server.RemotingService;
import org.jboss.messaging.core.remoting.spi.Acceptor;
@@ -80,15 +81,16 @@
// Resource Registration
MessagingServerControlImpl registerServer(PostOffice postOffice,
- StorageManager storageManager,
- Configuration configuration,
- HierarchicalRepository<AddressSettings> addressSettingsRepository,
- HierarchicalRepository<Set<Role>> securityRepository,
- ResourceManager resourceManager,
- RemotingService remotingService,
- MessagingServer messagingServer,
- QueueFactory queueFactory,
- boolean backup) throws Exception;
+ StorageManager storageManager,
+ Configuration configuration,
+ HierarchicalRepository<AddressSettings> addressSettingsRepository,
+ HierarchicalRepository<Set<Role>> securityRepository,
+ ResourceManager resourceManager,
+ RemotingService remotingService,
+ MessagingServer messagingServer,
+ QueueFactory queueFactory,
+ ClusterQueueStateManager clusterQueueStateManager,
+ boolean backup) throws Exception;
void unregisterServer() throws Exception;
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/impl/ManagementServiceImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/impl/ManagementServiceImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/impl/ManagementServiceImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -67,6 +67,7 @@
import org.jboss.messaging.core.messagecounter.MessageCounterManager;
import org.jboss.messaging.core.messagecounter.impl.MessageCounterManagerImpl;
import org.jboss.messaging.core.persistence.StorageManager;
+import org.jboss.messaging.core.postoffice.ClusterQueueStateManager;
import org.jboss.messaging.core.postoffice.PostOffice;
import org.jboss.messaging.core.remoting.server.RemotingService;
import org.jboss.messaging.core.remoting.spi.Acceptor;
@@ -111,13 +112,13 @@
private StorageManager storageManager;
- private MessagingServer messagingServer;
-
private HierarchicalRepository<Set<Role>> securityRepository;
private HierarchicalRepository<AddressSettings> addressSettingsRepository;
private MessagingServerControlImpl messagingServerControl;
+
+ private MessagingServer messagingServer;
private final MessageCounterManager messageCounterManager;
@@ -140,6 +141,8 @@
private final Set<NotificationListener> listeners = new org.jboss.messaging.utils.ConcurrentHashSet<NotificationListener>();
private ReplicationOperationInvoker replicationInvoker;
+
+ private ClusterQueueStateManager clusterQueueStateManager;
// Static --------------------------------------------------------
@@ -199,12 +202,14 @@
final RemotingService remotingService,
final MessagingServer messagingServer,
final QueueFactory queueFactory,
+ final ClusterQueueStateManager clusterQueueStateManager,
final boolean backup) throws Exception
{
this.postOffice = postOffice;
this.addressSettingsRepository = addressSettingsRepository;
this.securityRepository = securityRepository;
this.storageManager = storageManager;
+ this.clusterQueueStateManager = clusterQueueStateManager;
this.messagingServer = messagingServer;
JBMSecurityManager sm = messagingServer.getSecurityManager();
@@ -213,7 +218,7 @@
sm.addUser(managementClusterUser, managementClusterPassword);
}
- messagingServerControl = new MessagingServerControlImpl(postOffice,
+ messagingServerControl = new MessagingServerControlImpl(clusterQueueStateManager,
configuration,
resourceManager,
remotingService,
@@ -608,6 +613,8 @@
public void sendNotification(final Notification notification) throws Exception
{
+ log.info("messagingservercontrol " + this.messagingServerControl + " ne " + this.notificationsEnabled);
+
if (messagingServerControl != null && notificationsEnabled)
{
// This needs to be synchronized since we need to ensure notifications are processed in strict sequence
@@ -616,7 +623,7 @@
// We also need to synchronize on the post office notification lock
// otherwise we can get notifications arriving in wrong order / missing
// if a notification occurs at same time as sendQueueInfoToQueue is processed
- synchronized (postOffice.getNotificationLock())
+ synchronized (clusterQueueStateManager.getNotificationLock())
{
// First send to any local listeners
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/impl/MessagingServerControlImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/impl/MessagingServerControlImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/impl/MessagingServerControlImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -49,7 +49,7 @@
import org.jboss.messaging.core.management.NotificationType;
import org.jboss.messaging.core.messagecounter.MessageCounterManager;
import org.jboss.messaging.core.messagecounter.impl.MessageCounterManagerImpl;
-import org.jboss.messaging.core.postoffice.PostOffice;
+import org.jboss.messaging.core.postoffice.ClusterQueueStateManager;
import org.jboss.messaging.core.remoting.RemotingConnection;
import org.jboss.messaging.core.remoting.server.RemotingService;
import org.jboss.messaging.core.server.MessagingServer;
@@ -77,7 +77,7 @@
// Attributes ----------------------------------------------------
- private final PostOffice postOffice;
+ private final ClusterQueueStateManager clusterQueueStateManager;
private final Configuration configuration;
@@ -97,15 +97,15 @@
// Constructors --------------------------------------------------
- public MessagingServerControlImpl(final PostOffice postOffice,
- final Configuration configuration,
- final ResourceManager resourceManager,
- final RemotingService remotingService,
- final MessagingServer messagingServer,
- final MessageCounterManager messageCounterManager,
- final NotificationBroadcasterSupport broadcaster) throws Exception
+ public MessagingServerControlImpl(final ClusterQueueStateManager clusterQueueStateManager,
+ final Configuration configuration,
+ final ResourceManager resourceManager,
+ final RemotingService remotingService,
+ final MessagingServer messagingServer,
+ final MessageCounterManager messageCounterManager,
+ final NotificationBroadcasterSupport broadcaster) throws Exception
{
- this.postOffice = postOffice;
+ this.clusterQueueStateManager = clusterQueueStateManager;
this.configuration = configuration;
this.resourceManager = resourceManager;
this.remotingService = remotingService;
@@ -151,19 +151,20 @@
public String[] getInterceptorClassNames()
{
- return configuration.getInterceptorClassNames().toArray(new String[configuration.getInterceptorClassNames().size()]);
+ return configuration.getInterceptorClassNames().toArray(new String[configuration.getInterceptorClassNames()
+ .size()]);
}
public int getAIOBufferSize()
{
return configuration.getAIOBufferSize();
}
-
+
public int getAIOBufferTimeout()
{
return configuration.getAIOBufferTimeout();
}
-
+
public String getJournalDirectory()
{
return configuration.getJournalDirectory();
@@ -203,7 +204,7 @@
{
return configuration.getScheduledThreadPoolMaxSize();
}
-
+
public int getThreadPoolMaxSize()
{
return configuration.getThreadPoolMaxSize();
@@ -467,39 +468,39 @@
public Object[] getConnectors() throws Exception
{
Collection<TransportConfiguration> connectorConfigurations = configuration.getConnectorConfigurations().values();
-
+
Object[] ret = new Object[connectorConfigurations.size()];
-
+
int i = 0;
- for (TransportConfiguration config: connectorConfigurations)
+ for (TransportConfiguration config : connectorConfigurations)
{
Object[] tc = new Object[3];
-
+
tc[0] = config.getName();
tc[1] = config.getFactoryClassName();
tc[2] = config.getParams();
-
+
ret[i++] = tc;
}
-
+
return ret;
}
-
+
public String getConnectorsAsJSON() throws Exception
{
JSONArray array = new JSONArray();
-
- for (TransportConfiguration config: configuration.getConnectorConfigurations().values())
+
+ for (TransportConfiguration config : configuration.getConnectorConfigurations().values())
{
array.put(new JSONObject(config));
}
-
+
return array.toString();
}
public void sendQueueInfoToQueue(final String queueName, final String address) throws Exception
{
- postOffice.sendQueueInfoToQueue(new SimpleString(queueName), new SimpleString(address));
+ clusterQueueStateManager.sendQueueInfoToQueue(new SimpleString(queueName), new SimpleString(address));
}
// NotificationEmitter implementation ----------------------------
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/impl/QueueControlImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/impl/QueueControlImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/management/impl/QueueControlImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -155,7 +155,7 @@
public long getPersistenceID()
{
- return queue.getPersistenceID();
+ return queue.getID();
}
public long getScheduledCount()
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/paging/impl/PagingStoreImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/paging/impl/PagingStoreImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/paging/impl/PagingStoreImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -30,6 +30,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -47,6 +48,7 @@
import org.jboss.messaging.core.persistence.StorageManager;
import org.jboss.messaging.core.postoffice.PostOffice;
import org.jboss.messaging.core.server.ServerMessage;
+import org.jboss.messaging.core.server.replication.impl.StatefulObjectReadWriteLock;
import org.jboss.messaging.core.settings.impl.AddressSettings;
import org.jboss.messaging.core.transaction.Transaction;
import org.jboss.messaging.core.transaction.TransactionPropertyIndexes;
@@ -114,6 +116,8 @@
* We need to perform checks on currentPage with minimal locking
* */
private final ReadWriteLock currentPageLock = new ReentrantReadWriteLock();
+
+ //private final Lock lock = StatefulObjectReadWriteLock.createLock().writeLock();
private volatile boolean running = false;
@@ -299,7 +303,6 @@
}
}
- // TODO all of this can be simplified
public boolean page(final PagedMessage message, final boolean sync, final boolean duplicateDetection) throws Exception
{
if (!running)
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/persistence/impl/journal/JournalStorageManager.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/persistence/impl/journal/JournalStorageManager.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/persistence/impl/journal/JournalStorageManager.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -144,9 +144,13 @@
private final int perfBlastPages;
+ private boolean backup;
+
public JournalStorageManager(final Configuration config, final Executor executor)
{
this.executor = executor;
+
+ backup = config.isBackup();
if (config.getJournalType() != JournalType.NIO && config.getJournalType() != JournalType.ASYNCIO)
{
@@ -245,6 +249,8 @@
public long generateUniqueID()
{
long id = idGenerator.generateID();
+
+ log.info("Generating unique id on backup " + backup + " id " + id, new Exception());
return id;
}
@@ -306,7 +312,7 @@
public void updateScheduledDeliveryTime(final MessageReference ref) throws Exception
{
ScheduledDeliveryEncoding encoding = new ScheduledDeliveryEncoding(ref.getScheduledDeliveryTime(),
- ref.getQueue().getPersistenceID());
+ ref.getQueue().getID());
messageJournal.appendUpdateRecord(ref.getMessage().getMessageID(),
SET_SCHEDULED_DELIVERY_TIME,
@@ -405,7 +411,7 @@
public void updateScheduledDeliveryTimeTransactional(final long txID, final MessageReference ref) throws Exception
{
ScheduledDeliveryEncoding encoding = new ScheduledDeliveryEncoding(ref.getScheduledDeliveryTime(),
- ref.getQueue().getPersistenceID());
+ ref.getQueue().getID());
messageJournal.appendUpdateRecordTransactional(txID,
ref.getMessage().getMessageID(),
@@ -463,7 +469,7 @@
public void updateDeliveryCount(final MessageReference ref) throws Exception
{
- DeliveryCountUpdateEncoding updateInfo = new DeliveryCountUpdateEncoding(ref.getQueue().getPersistenceID(),
+ DeliveryCountUpdateEncoding updateInfo = new DeliveryCountUpdateEncoding(ref.getQueue().getID(),
ref.getDeliveryCount());
messageJournal.appendUpdateRecord(ref.getMessage().getMessageID(),
@@ -912,11 +918,7 @@
binding.getAddress(),
filterString);
- long id = this.generateUniqueID();
-
- queue.setPersistenceID(id);
-
- bindingsJournal.appendAddRecord(id, QUEUE_BINDING_RECORD, bindingEncoding, true);
+ bindingsJournal.appendAddRecord(queue.getID(), QUEUE_BINDING_RECORD, bindingEncoding, true);
}
public void deleteQueueBinding(final long queueBindingID) throws Exception
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/persistence/impl/nullpm/NullStorageManager.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/persistence/impl/nullpm/NullStorageManager.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/persistence/impl/nullpm/NullStorageManager.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -61,6 +61,13 @@
private volatile boolean started;
+ private boolean backup;
+
+ public NullStorageManager(final boolean backup)
+ {
+ this.backup = backup;
+ }
+
public UUID getPersistentID()
{
return id;
@@ -186,6 +193,8 @@
{
long id = idSequence.getAndIncrement();
+ // log.info("Generating unique id on backup " + backup + " id " + id, new Exception());
+
return id;
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/AddressManager.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/AddressManager.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/AddressManager.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -34,7 +34,7 @@
*/
public interface AddressManager
{
- boolean addBinding(Binding binding);
+ void addBinding(Binding binding);
Binding removeBinding(SimpleString uniqueName);
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/PostOffice.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/PostOffice.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/PostOffice.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -73,7 +73,7 @@
DuplicateIDCache getDuplicateIDCache(SimpleString address);
- void sendQueueInfoToQueue(SimpleString queueName, SimpleString address) throws Exception;
+ //void sendQueueInfoToQueue(SimpleString queueName, SimpleString address) throws Exception;
- Object getNotificationLock();
+ // Object getNotificationLock();
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/impl/PostOfficeImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/impl/PostOfficeImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/impl/PostOfficeImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -32,6 +32,7 @@
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.locks.ReadWriteLock;
import org.jboss.messaging.core.buffers.ChannelBuffers;
import org.jboss.messaging.core.client.management.impl.ManagementHelper;
@@ -54,11 +55,11 @@
import org.jboss.messaging.core.postoffice.DuplicateIDCache;
import org.jboss.messaging.core.postoffice.PostOffice;
import org.jboss.messaging.core.postoffice.QueueInfo;
-import org.jboss.messaging.core.server.MessagingServer;
import org.jboss.messaging.core.server.Queue;
import org.jboss.messaging.core.server.QueueFactory;
import org.jboss.messaging.core.server.ServerMessage;
import org.jboss.messaging.core.server.impl.ServerMessageImpl;
+import org.jboss.messaging.core.server.replication.impl.StatefulObjectReadWriteLock;
import org.jboss.messaging.core.settings.HierarchicalRepository;
import org.jboss.messaging.core.settings.impl.AddressSettings;
import org.jboss.messaging.core.transaction.Transaction;
@@ -78,14 +79,12 @@
* @author <a href="jmesnil at redhat.com">Jeff Mesnil</a>
* @author <a href="csuconic at redhat.com">Clebert Suconic</a>
*/
-public class PostOfficeImpl implements PostOffice, NotificationListener
+public class PostOfficeImpl implements PostOffice // , NotificationListener
{
private static final Logger log = Logger.getLogger(PostOfficeImpl.class);
- public static final SimpleString HDR_RESET_QUEUE_DATA = new SimpleString("_JBM_RESET_QUEUE_DATA");
+ // public static final SimpleString HDR_RESET_QUEUE_DATA = new SimpleString("_JBM_RESET_QUEUE_DATA");
- private MessagingServer server;
-
private final AddressManager addressManager;
private final QueueFactory queueFactory;
@@ -105,7 +104,7 @@
private final long reaperPeriod;
private final int reaperPriority;
-
+
private Reaper reaper;
private final ConcurrentMap<SimpleString, DuplicateIDCache> duplicateIDCaches = new ConcurrentHashMap<SimpleString, DuplicateIDCache>();
@@ -124,16 +123,17 @@
private Set<Integer> transientIDs = new HashSet<Integer>();
- private Map<SimpleString, QueueInfo> queueInfos = new HashMap<SimpleString, QueueInfo>();
+ // private Map<SimpleString, QueueInfo> queueInfos = new HashMap<SimpleString, QueueInfo>();
- private final Object notificationLock = new Object();
+ // private final Object notificationLock = new Object();
- private final org.jboss.messaging.utils.ExecutorFactory redistributorExecutorFactory;
+ // private final org.jboss.messaging.utils.ExecutorFactory redistributorExecutorFactory;
+ //
+ // private final HierarchicalRepository<AddressSettings> addressSettingsRepository;
- private final HierarchicalRepository<AddressSettings> addressSettingsRepository;
+ private final ReadWriteLock lock;
- public PostOfficeImpl(final MessagingServer server,
- final StorageManager storageManager,
+ public PostOfficeImpl(final StorageManager storageManager,
final PagingManager pagingManager,
final QueueFactory bindableFactory,
final ManagementService managementService,
@@ -142,13 +142,11 @@
final boolean enableWildCardRouting,
final boolean backup,
final int idCacheSize,
- final boolean persistIDCache,
- final ExecutorFactory orderedExecutorFactory,
- HierarchicalRepository<AddressSettings> addressSettingsRepository)
+ final boolean persistIDCache)
+ // final ExecutorFactory orderedExecutorFactory,
+ // HierarchicalRepository<AddressSettings> addressSettingsRepository)
{
- this.server = server;
-
this.storageManager = storageManager;
this.queueFactory = bindableFactory;
@@ -176,16 +174,18 @@
this.persistIDCache = persistIDCache;
- this.redistributorExecutorFactory = orderedExecutorFactory;
+ // this.redistributorExecutorFactory = orderedExecutorFactory;
- this.addressSettingsRepository = addressSettingsRepository;
+ // this.addressSettingsRepository = addressSettingsRepository;
+
+ lock = new StatefulObjectReadWriteLock("postoffice", storageManager.generateUniqueID(), 0);
}
// MessagingComponent implementation ---------------------------------------
public synchronized void start() throws Exception
{
- managementService.addNotificationListener(this);
+ // managementService.addNotificationListener(this);
if (pagingManager != null)
{
@@ -202,21 +202,21 @@
started = true;
}
-
+
public synchronized void stop() throws Exception
- {
- managementService.removeNotificationListener(this);
+ {
+ // managementService.removeNotificationListener(this);
if (reaper != null)
{
reaper.stop();
-
+
expiryReaper.join();
}
addressManager.clear();
- queueInfos.clear();
+ // queueInfos.clear();
transientIDs.clear();
@@ -230,256 +230,264 @@
// NotificationListener implementation -------------------------------------
- public void onNotification(final Notification notification)
- {
- synchronized (notificationLock)
- {
- NotificationType type = notification.getType();
+ // public void onNotification(final Notification notification)
+ // {
+ // synchronized (notificationLock)
+ // {
+ // NotificationType type = notification.getType();
+ //
+ // switch (type)
+ // {
+ // case BINDING_ADDED:
+ // {
+ // TypedProperties props = notification.getProperties();
+ //
+ // Integer bindingType = (Integer)props.getProperty(ManagementHelper.HDR_BINDING_TYPE);
+ //
+ // if (bindingType == null)
+ // {
+ // throw new IllegalArgumentException("Binding type not specified");
+ // }
+ //
+ // if (bindingType == BindingType.DIVERT_INDEX)
+ // {
+ // // We don't propagate diverts
+ // return;
+ // }
+ //
+ // SimpleString routingName = (SimpleString)props.getProperty(ManagementHelper.HDR_ROUTING_NAME);
+ //
+ // SimpleString clusterName = (SimpleString)props.getProperty(ManagementHelper.HDR_CLUSTER_NAME);
+ //
+ // SimpleString address = (SimpleString)props.getProperty(ManagementHelper.HDR_ADDRESS);
+ //
+ // Integer transientID = (Integer)props.getProperty(ManagementHelper.HDR_BINDING_ID);
+ //
+ // SimpleString filterString = (SimpleString)props.getProperty(ManagementHelper.HDR_FILTERSTRING);
+ //
+ // Integer distance = (Integer)props.getProperty(ManagementHelper.HDR_DISTANCE);
+ //
+ // QueueInfo info = new QueueInfo(routingName, clusterName, address, filterString, transientID, distance);
+ //
+ // queueInfos.put(clusterName, info);
+ //
+ // break;
+ // }
+ // case BINDING_REMOVED:
+ // {
+ // TypedProperties props = notification.getProperties();
+ //
+ // SimpleString clusterName = (SimpleString)props.getProperty(ManagementHelper.HDR_CLUSTER_NAME);
+ //
+ // if (clusterName == null)
+ // {
+ // throw new IllegalStateException("No cluster name");
+ // }
+ //
+ // QueueInfo info = queueInfos.remove(clusterName);
+ //
+ // if (info == null)
+ // {
+ // throw new IllegalStateException("Cannot find queue info for queue " + clusterName);
+ // }
+ //
+ // break;
+ // }
+ // case CONSUMER_CREATED:
+ // {
+ // TypedProperties props = notification.getProperties();
+ //
+ // SimpleString clusterName = (SimpleString)props.getProperty(ManagementHelper.HDR_CLUSTER_NAME);
+ //
+ // if (clusterName == null)
+ // {
+ // throw new IllegalStateException("No cluster name");
+ // }
+ //
+ // SimpleString filterString = (SimpleString)props.getProperty(ManagementHelper.HDR_FILTERSTRING);
+ //
+ // QueueInfo info = queueInfos.get(clusterName);
+ //
+ // if (info == null)
+ // {
+ // throw new IllegalStateException("Cannot find queue info for queue " + clusterName);
+ // }
+ //
+ // info.incrementConsumers();
+ //
+ // if (filterString != null)
+ // {
+ // List<SimpleString> filterStrings = info.getFilterStrings();
+ //
+ // if (filterStrings == null)
+ // {
+ // filterStrings = new ArrayList<SimpleString>();
+ //
+ // info.setFilterStrings(filterStrings);
+ // }
+ //
+ // filterStrings.add(filterString);
+ // }
+ //
+ // Integer distance = (Integer)props.getProperty(ManagementHelper.HDR_DISTANCE);
+ //
+ // if (distance == null)
+ // {
+ // throw new IllegalStateException("No distance");
+ // }
+ //
+ // if (distance > 0)
+ // {
+ // SimpleString queueName = (SimpleString)props.getProperty(ManagementHelper.HDR_ROUTING_NAME);
+ //
+ // if (queueName == null)
+ // {
+ // throw new IllegalStateException("No queue name");
+ // }
+ //
+ // Binding binding = getBinding(queueName);
+ //
+ // if (binding != null)
+ // {
+ // // We have a local queue
+ // Queue queue = (Queue)binding.getBindable();
+ //
+ // AddressSettings addressSettings = addressSettingsRepository.getMatch(binding.getAddress()
+ // .toString());
+ //
+ // long redistributionDelay = addressSettings.getRedistributionDelay();
+ //
+ // if (redistributionDelay != -1)
+ // {
+ // queue.addRedistributor(redistributionDelay, redistributorExecutorFactory.getExecutor());
+ // }
+ // }
+ // }
+ //
+ // break;
+ // }
+ // case CONSUMER_CLOSED:
+ // {
+ // TypedProperties props = notification.getProperties();
+ //
+ // SimpleString clusterName = (SimpleString)props.getProperty(ManagementHelper.HDR_CLUSTER_NAME);
+ //
+ // if (clusterName == null)
+ // {
+ // throw new IllegalStateException("No distance");
+ // }
+ //
+ // SimpleString filterString = (SimpleString)props.getProperty(ManagementHelper.HDR_FILTERSTRING);
+ //
+ // QueueInfo info = queueInfos.get(clusterName);
+ //
+ // if (info == null)
+ // {
+ // throw new IllegalStateException("Cannot find queue info for queue " + clusterName);
+ // }
+ //
+ // info.decrementConsumers();
+ //
+ // if (filterString != null)
+ // {
+ // List<SimpleString> filterStrings = info.getFilterStrings();
+ //
+ // filterStrings.remove(filterString);
+ // }
+ //
+ // if (info.getNumberOfConsumers() == 0)
+ // {
+ // Integer distance = (Integer)props.getProperty(ManagementHelper.HDR_DISTANCE);
+ //
+ // if (distance == null)
+ // {
+ // throw new IllegalStateException("No cluster name");
+ // }
+ //
+ // if (distance == 0)
+ // {
+ // SimpleString queueName = (SimpleString)props.getProperty(ManagementHelper.HDR_ROUTING_NAME);
+ //
+ // if (queueName == null)
+ // {
+ // throw new IllegalStateException("No queue name");
+ // }
+ //
+ // Binding binding = getBinding(queueName);
+ //
+ // if (binding == null)
+ // {
+ // throw new IllegalStateException("No queue " + queueName);
+ // }
+ //
+ // Queue queue = (Queue)binding.getBindable();
+ //
+ // AddressSettings addressSettings = addressSettingsRepository.getMatch(binding.getAddress()
+ // .toString());
+ //
+ // long redistributionDelay = addressSettings.getRedistributionDelay();
+ //
+ // if (redistributionDelay != -1)
+ // {
+ // queue.addRedistributor(redistributionDelay, redistributorExecutorFactory.getExecutor());
+ // }
+ // }
+ // }
+ //
+ // break;
+ // }
+ // case SECURITY_AUTHENTICATION_VIOLATION:
+ // case SECURITY_PERMISSION_VIOLATION:
+ // break;
+ // default:
+ // {
+ // throw new IllegalArgumentException("Invalid type " + type);
+ // }
+ //
+ // }
+ // }
+ // }
- switch (type)
- {
- case BINDING_ADDED:
- {
- TypedProperties props = notification.getProperties();
-
- Integer bindingType = (Integer)props.getProperty(ManagementHelper.HDR_BINDING_TYPE);
-
- if (bindingType == null)
- {
- throw new IllegalArgumentException("Binding type not specified");
- }
-
- if (bindingType == BindingType.DIVERT_INDEX)
- {
- // We don't propagate diverts
- return;
- }
-
- SimpleString routingName = (SimpleString)props.getProperty(ManagementHelper.HDR_ROUTING_NAME);
-
- SimpleString clusterName = (SimpleString)props.getProperty(ManagementHelper.HDR_CLUSTER_NAME);
-
- SimpleString address = (SimpleString)props.getProperty(ManagementHelper.HDR_ADDRESS);
-
- Integer transientID = (Integer)props.getProperty(ManagementHelper.HDR_BINDING_ID);
-
- SimpleString filterString = (SimpleString)props.getProperty(ManagementHelper.HDR_FILTERSTRING);
-
- Integer distance = (Integer)props.getProperty(ManagementHelper.HDR_DISTANCE);
-
- QueueInfo info = new QueueInfo(routingName, clusterName, address, filterString, transientID, distance);
-
- queueInfos.put(clusterName, info);
-
- break;
- }
- case BINDING_REMOVED:
- {
- TypedProperties props = notification.getProperties();
-
- SimpleString clusterName = (SimpleString)props.getProperty(ManagementHelper.HDR_CLUSTER_NAME);
-
- if (clusterName == null)
- {
- throw new IllegalStateException("No cluster name");
- }
-
- QueueInfo info = queueInfos.remove(clusterName);
-
- if (info == null)
- {
- throw new IllegalStateException("Cannot find queue info for queue " + clusterName);
- }
-
- break;
- }
- case CONSUMER_CREATED:
- {
- TypedProperties props = notification.getProperties();
-
- SimpleString clusterName = (SimpleString)props.getProperty(ManagementHelper.HDR_CLUSTER_NAME);
-
- if (clusterName == null)
- {
- throw new IllegalStateException("No cluster name");
- }
-
- SimpleString filterString = (SimpleString)props.getProperty(ManagementHelper.HDR_FILTERSTRING);
-
- QueueInfo info = queueInfos.get(clusterName);
-
- if (info == null)
- {
- throw new IllegalStateException("Cannot find queue info for queue " + clusterName);
- }
-
- info.incrementConsumers();
-
- if (filterString != null)
- {
- List<SimpleString> filterStrings = info.getFilterStrings();
-
- if (filterStrings == null)
- {
- filterStrings = new ArrayList<SimpleString>();
-
- info.setFilterStrings(filterStrings);
- }
-
- filterStrings.add(filterString);
- }
-
- Integer distance = (Integer)props.getProperty(ManagementHelper.HDR_DISTANCE);
-
- if (distance == null)
- {
- throw new IllegalStateException("No distance");
- }
-
- if (distance > 0)
- {
- SimpleString queueName = (SimpleString)props.getProperty(ManagementHelper.HDR_ROUTING_NAME);
-
- if (queueName == null)
- {
- throw new IllegalStateException("No queue name");
- }
-
- Binding binding = getBinding(queueName);
-
- if (binding != null)
- {
- // We have a local queue
- Queue queue = (Queue)binding.getBindable();
-
- AddressSettings addressSettings = addressSettingsRepository.getMatch(binding.getAddress()
- .toString());
-
- long redistributionDelay = addressSettings.getRedistributionDelay();
-
- if (redistributionDelay != -1)
- {
- queue.addRedistributor(redistributionDelay, redistributorExecutorFactory.getExecutor(),
- server.getReplicatingChannel());
- }
- }
- }
-
- break;
- }
- case CONSUMER_CLOSED:
- {
- TypedProperties props = notification.getProperties();
-
- SimpleString clusterName = (SimpleString)props.getProperty(ManagementHelper.HDR_CLUSTER_NAME);
-
- if (clusterName == null)
- {
- throw new IllegalStateException("No distance");
- }
-
- SimpleString filterString = (SimpleString)props.getProperty(ManagementHelper.HDR_FILTERSTRING);
-
- QueueInfo info = queueInfos.get(clusterName);
-
- if (info == null)
- {
- throw new IllegalStateException("Cannot find queue info for queue " + clusterName);
- }
-
- info.decrementConsumers();
-
- if (filterString != null)
- {
- List<SimpleString> filterStrings = info.getFilterStrings();
-
- filterStrings.remove(filterString);
- }
-
- if (info.getNumberOfConsumers() == 0)
- {
- Integer distance = (Integer)props.getProperty(ManagementHelper.HDR_DISTANCE);
-
- if (distance == null)
- {
- throw new IllegalStateException("No cluster name");
- }
-
- if (distance == 0)
- {
- SimpleString queueName = (SimpleString)props.getProperty(ManagementHelper.HDR_ROUTING_NAME);
-
- if (queueName == null)
- {
- throw new IllegalStateException("No queue name");
- }
-
- Binding binding = getBinding(queueName);
-
- if (binding == null)
- {
- throw new IllegalStateException("No queue " + queueName);
- }
-
- Queue queue = (Queue)binding.getBindable();
-
- AddressSettings addressSettings = addressSettingsRepository.getMatch(binding.getAddress()
- .toString());
-
- long redistributionDelay = addressSettings.getRedistributionDelay();
-
- if (redistributionDelay != -1)
- {
- queue.addRedistributor(redistributionDelay, redistributorExecutorFactory.getExecutor(),
- server.getReplicatingChannel());
- }
- }
- }
-
- break;
- }
- case SECURITY_AUTHENTICATION_VIOLATION:
- case SECURITY_PERMISSION_VIOLATION:
- break;
- default:
- {
- throw new IllegalArgumentException("Invalid type " + type);
- }
-
- }
- }
- }
-
// PostOffice implementation -----------------------------------------------
- // TODO - needs to be synchronized to prevent happening concurrently with activate().
+ // TODO - needs to be locked to prevent happening concurrently with activate().
// (and possible removeBinding and other methods)
// Otherwise can have situation where createQueue comes in before failover, then failover occurs
// and post office is activated but queue remains unactivated after failover so delivery never occurs
// even though failover is complete
- public synchronized void addBinding(final Binding binding) throws Exception
+ public void addBinding(final Binding binding) throws Exception
{
- binding.setID(generateTransientID());
+ lock.writeLock().lock();
+ try
+ {
+ binding.setID(generateTransientID());
- boolean existed = addressManager.addBinding(binding);
+ boolean addressExists = addressManager.getBindingsForRoutingAddress(binding.getAddress()) != null;
- if (binding.getType() == BindingType.LOCAL_QUEUE)
- {
- Queue queue = (Queue)binding.getBindable();
+ addressManager.addBinding(binding);
- if (backup)
+ if (binding.getType() == BindingType.LOCAL_QUEUE)
{
- queue.setBackup();
- }
+ Queue queue = (Queue)binding.getBindable();
- managementService.registerQueue(queue, binding.getAddress(), storageManager);
+ if (backup)
+ {
+ queue.setBackup();
+ }
- if (!existed)
- {
- managementService.registerAddress(binding.getAddress());
+ managementService.registerQueue(queue, binding.getAddress(), storageManager);
+
+ if (!addressExists)
+ {
+ managementService.registerAddress(binding.getAddress());
+ }
}
}
-
+ finally
+ {
+ lock.writeLock().unlock();
+ }
+
TypedProperties props = new TypedProperties();
props.putIntProperty(ManagementHelper.HDR_BINDING_TYPE, binding.getType().toInt());
@@ -499,40 +507,54 @@
if (filter != null)
{
props.putStringProperty(ManagementHelper.HDR_FILTERSTRING, filter.getFilterString());
- }
-
+ }
+
String uid = UUIDGenerator.getInstance().generateStringUUID();
+ log.info("*** sending notification");
managementService.sendNotification(new Notification(uid, NotificationType.BINDING_ADDED, props));
}
- public synchronized Binding removeBinding(final SimpleString uniqueName) throws Exception
+ public Binding removeBinding(final SimpleString uniqueName) throws Exception
{
- Binding binding = addressManager.removeBinding(uniqueName);
- if (binding == null)
+ lock.writeLock().lock();
+ Binding binding;
+ try
{
- throw new MessagingException(MessagingException.QUEUE_DOES_NOT_EXIST);
- }
+ binding = addressManager.removeBinding(uniqueName);
+ if (binding == null)
+ {
+ throw new MessagingException(MessagingException.QUEUE_DOES_NOT_EXIST);
+ }
- if (binding.getType() == BindingType.LOCAL_QUEUE)
- {
- managementService.unregisterQueue(uniqueName, binding.getAddress());
+ if (binding.getType() == BindingType.LOCAL_QUEUE)
+ {
+ managementService.unregisterQueue(uniqueName, binding.getAddress());
- if (addressManager.getBindingsForRoutingAddress(binding.getAddress()) == null)
+ if (addressManager.getBindingsForRoutingAddress(binding.getAddress()) == null)
+ {
+ managementService.unregisterAddress(binding.getAddress());
+ }
+ }
+ else if (binding.getType() == BindingType.DIVERT)
{
- managementService.unregisterAddress(binding.getAddress());
+ managementService.unregisterDivert(uniqueName);
+
+ if (addressManager.getBindingsForRoutingAddress(binding.getAddress()) == null)
+ {
+ managementService.unregisterAddress(binding.getAddress());
+ }
}
+
+ releaseTransientID(binding.getID());
+
+
}
- else if (binding.getType() == BindingType.DIVERT)
+ finally
{
- managementService.unregisterDivert(uniqueName);
-
- if (addressManager.getBindingsForRoutingAddress(binding.getAddress()) == null)
- {
- managementService.unregisterAddress(binding.getAddress());
- }
+ lock.writeLock().unlock();
}
-
+
TypedProperties props = new TypedProperties();
props.putStringProperty(ManagementHelper.HDR_ADDRESS, binding.getAddress());
@@ -544,32 +566,54 @@
props.putIntProperty(ManagementHelper.HDR_DISTANCE, binding.getDistance());
managementService.sendNotification(new Notification(null, NotificationType.BINDING_REMOVED, props));
-
- releaseTransientID(binding.getID());
-
+
return binding;
}
public Bindings getBindingsForAddress(final SimpleString address)
{
- Bindings bindings = addressManager.getBindingsForRoutingAddress(address);
+ lock.readLock().lock();
+ try
+ {
+ Bindings bindings = addressManager.getBindingsForRoutingAddress(address);
- if (bindings == null)
+ if (bindings == null)
+ {
+ bindings = new BindingsImpl();
+ }
+
+ return bindings;
+ }
+ finally
{
- bindings = new BindingsImpl();
+ lock.readLock().unlock();
}
-
- return bindings;
}
public Binding getBinding(final SimpleString name)
{
- return addressManager.getBinding(name);
+ lock.readLock().lock();
+ try
+ {
+ return addressManager.getBinding(name);
+ }
+ finally
+ {
+ lock.readLock().unlock();
+ }
}
-
+
public Bindings getMatchingBindings(final SimpleString address)
{
- return addressManager.getMatchingBindings(address);
+ lock.readLock().lock();
+ try
+ {
+ return addressManager.getMatchingBindings(address);
+ }
+ finally
+ {
+ lock.readLock().unlock();
+ }
}
public void route(final ServerMessage message, Transaction tx) throws Exception
@@ -577,7 +621,7 @@
SimpleString address = message.getDestination();
byte[] duplicateIDBytes = null;
-
+
Object duplicateID = message.getProperty(MessageImpl.HDR_DUPLICATE_DETECTION_ID);
DuplicateIDCache cache = null;
@@ -594,7 +638,7 @@
{
duplicateIDBytes = (byte[])duplicateID;
}
-
+
if (cache.contains(duplicateIDBytes))
{
if (tx == null)
@@ -624,41 +668,49 @@
startedTx = true;
}
-
+
cache.addToCache(duplicateIDBytes, tx);
}
- if (tx == null)
+ lock.readLock().lock();
+ try
{
- if (pagingManager.page(message, true))
+ if (tx == null)
{
- return;
+ if (pagingManager.page(message, true))
+ {
+ return;
+ }
}
- }
- else
- {
- SimpleString destination = message.getDestination();
+ else
+ {
+ SimpleString destination = message.getDestination();
- boolean depage = tx.getProperty(TransactionPropertyIndexes.IS_DEPAGE) != null;
+ boolean depage = tx.getProperty(TransactionPropertyIndexes.IS_DEPAGE) != null;
- if (!depage && pagingManager.isPaging(destination))
- {
- getPageOperation(tx).addMessageToPage(message);
+ if (!depage && pagingManager.isPaging(destination))
+ {
+ getPageOperation(tx).addMessageToPage(message);
- return;
+ return;
+ }
}
- }
- Bindings bindings = addressManager.getBindingsForRoutingAddress(address);
+ Bindings bindings = addressManager.getBindingsForRoutingAddress(address);
- if (bindings != null)
- {
- bindings.route(message, tx);
+ if (bindings != null)
+ {
+ bindings.route(message, tx);
+ }
+
+ if (startedTx)
+ {
+ tx.commit();
+ }
}
-
- if (startedTx)
+ finally
{
- tx.commit();
+ lock.readLock().unlock();
}
}
@@ -669,15 +721,23 @@
public boolean redistribute(final ServerMessage message, final Queue originatingQueue, final Transaction tx) throws Exception
{
- Bindings bindings = addressManager.getBindingsForRoutingAddress(message.getDestination());
+ lock.readLock().lock();
+ try
+ {
+ Bindings bindings = addressManager.getBindingsForRoutingAddress(message.getDestination());
- if (bindings != null)
- {
- return bindings.redistribute(message, originatingQueue, tx);
+ if (bindings != null)
+ {
+ return bindings.redistribute(message, originatingQueue, tx);
+ }
+ else
+ {
+ return false;
+ }
}
- else
+ finally
{
- return false;
+ lock.readLock().unlock();
}
}
@@ -734,88 +794,88 @@
return cache;
}
-
- public Object getNotificationLock()
- {
- return notificationLock;
- }
- public void sendQueueInfoToQueue(final SimpleString queueName, final SimpleString address) throws Exception
- {
- // We send direct to the queue so we can send it to the same queue that is bound to the notifications adress -
- // this is crucial for ensuring
- // that queue infos and notifications are received in a contiguous consistent stream
- Binding binding = addressManager.getBinding(queueName);
+ // public Object getNotificationLock()
+ // {
+ // return notificationLock;
+ // }
- if (binding == null)
- {
- throw new IllegalStateException("Cannot find queue " + queueName);
- }
+ // public void sendQueueInfoToQueue(final SimpleString queueName, final SimpleString address) throws Exception
+ // {
+ // // We send direct to the queue so we can send it to the same queue that is bound to the notifications adress -
+ // // this is crucial for ensuring
+ // // that queue infos and notifications are received in a contiguous consistent stream
+ // Binding binding = addressManager.getBinding(queueName);
+ //
+ // if (binding == null)
+ // {
+ // throw new IllegalStateException("Cannot find queue " + queueName);
+ // }
+ //
+ // Queue queue = (Queue)binding.getBindable();
+ //
+ // // Need to lock to make sure all queue info and notifications are in the correct order with no gaps
+ // synchronized (notificationLock)
+ // {
+ // // First send a reset message
+ //
+ // ServerMessage message = new ServerMessageImpl(storageManager.generateUniqueID());
+ // message.setBody(ChannelBuffers.EMPTY_BUFFER);
+ // message.setDestination(queueName);
+ // message.putBooleanProperty(HDR_RESET_QUEUE_DATA, true);
+ // queue.preroute(message, null);
+ // queue.route(message, null);
+ //
+ // for (QueueInfo info : queueInfos.values())
+ // {
+ // if (info.getAddress().startsWith(address))
+ // {
+ // message = createQueueInfoMessage(NotificationType.BINDING_ADDED, queueName);
+ //
+ // message.putStringProperty(ManagementHelper.HDR_ADDRESS, info.getAddress());
+ // message.putStringProperty(ManagementHelper.HDR_CLUSTER_NAME, info.getClusterName());
+ // message.putStringProperty(ManagementHelper.HDR_ROUTING_NAME, info.getRoutingName());
+ // message.putIntProperty(ManagementHelper.HDR_BINDING_ID, info.getID());
+ // message.putStringProperty(ManagementHelper.HDR_FILTERSTRING, info.getFilterString());
+ // message.putIntProperty(ManagementHelper.HDR_DISTANCE, info.getDistance());
+ //
+ // routeDirect(queue, message);
+ //
+ // int consumersWithFilters = info.getFilterStrings() != null ? info.getFilterStrings().size() : 0;
+ //
+ // for (int i = 0; i < info.getNumberOfConsumers() - consumersWithFilters; i++)
+ // {
+ // message = createQueueInfoMessage(NotificationType.CONSUMER_CREATED, queueName);
+ //
+ // message.putStringProperty(ManagementHelper.HDR_ADDRESS, info.getAddress());
+ // message.putStringProperty(ManagementHelper.HDR_CLUSTER_NAME, info.getClusterName());
+ // message.putStringProperty(ManagementHelper.HDR_ROUTING_NAME, info.getRoutingName());
+ // message.putIntProperty(ManagementHelper.HDR_DISTANCE, info.getDistance());
+ //
+ // routeDirect(queue, message);
+ // }
+ //
+ // if (info.getFilterStrings() != null)
+ // {
+ // for (SimpleString filterString : info.getFilterStrings())
+ // {
+ // message = createQueueInfoMessage(NotificationType.CONSUMER_CREATED, queueName);
+ //
+ // message.putStringProperty(ManagementHelper.HDR_ADDRESS, info.getAddress());
+ // message.putStringProperty(ManagementHelper.HDR_CLUSTER_NAME, info.getClusterName());
+ // message.putStringProperty(ManagementHelper.HDR_ROUTING_NAME, info.getRoutingName());
+ // message.putStringProperty(ManagementHelper.HDR_FILTERSTRING, filterString);
+ // message.putIntProperty(ManagementHelper.HDR_DISTANCE, info.getDistance());
+ //
+ // routeDirect(queue, message);
+ // }
+ // }
+ // }
+ // }
+ // }
+ //
+ // }
- Queue queue = (Queue)binding.getBindable();
-
- // Need to lock to make sure all queue info and notifications are in the correct order with no gaps
- synchronized (notificationLock)
- {
- // First send a reset message
-
- ServerMessage message = new ServerMessageImpl(storageManager.generateUniqueID());
- message.setBody(ChannelBuffers.EMPTY_BUFFER);
- message.setDestination(queueName);
- message.putBooleanProperty(HDR_RESET_QUEUE_DATA, true);
- queue.preroute(message, null);
- queue.route(message, null);
-
- for (QueueInfo info : queueInfos.values())
- {
- if (info.getAddress().startsWith(address))
- {
- message = createQueueInfoMessage(NotificationType.BINDING_ADDED, queueName);
-
- message.putStringProperty(ManagementHelper.HDR_ADDRESS, info.getAddress());
- message.putStringProperty(ManagementHelper.HDR_CLUSTER_NAME, info.getClusterName());
- message.putStringProperty(ManagementHelper.HDR_ROUTING_NAME, info.getRoutingName());
- message.putIntProperty(ManagementHelper.HDR_BINDING_ID, info.getID());
- message.putStringProperty(ManagementHelper.HDR_FILTERSTRING, info.getFilterString());
- message.putIntProperty(ManagementHelper.HDR_DISTANCE, info.getDistance());
-
- routeDirect(queue, message);
-
- int consumersWithFilters = info.getFilterStrings() != null ? info.getFilterStrings().size() : 0;
-
- for (int i = 0; i < info.getNumberOfConsumers() - consumersWithFilters; i++)
- {
- message = createQueueInfoMessage(NotificationType.CONSUMER_CREATED, queueName);
-
- message.putStringProperty(ManagementHelper.HDR_ADDRESS, info.getAddress());
- message.putStringProperty(ManagementHelper.HDR_CLUSTER_NAME, info.getClusterName());
- message.putStringProperty(ManagementHelper.HDR_ROUTING_NAME, info.getRoutingName());
- message.putIntProperty(ManagementHelper.HDR_DISTANCE, info.getDistance());
-
- routeDirect(queue, message);
- }
-
- if (info.getFilterStrings() != null)
- {
- for (SimpleString filterString : info.getFilterStrings())
- {
- message = createQueueInfoMessage(NotificationType.CONSUMER_CREATED, queueName);
-
- message.putStringProperty(ManagementHelper.HDR_ADDRESS, info.getAddress());
- message.putStringProperty(ManagementHelper.HDR_CLUSTER_NAME, info.getClusterName());
- message.putStringProperty(ManagementHelper.HDR_ROUTING_NAME, info.getRoutingName());
- message.putStringProperty(ManagementHelper.HDR_FILTERSTRING, filterString);
- message.putIntProperty(ManagementHelper.HDR_DISTANCE, info.getDistance());
-
- routeDirect(queue, message);
- }
- }
- }
- }
- }
-
- }
-
// Private -----------------------------------------------------------------
private synchronized void startExpiryScanner()
@@ -823,41 +883,41 @@
if (reaperPeriod > 0)
{
reaper = new Reaper();
-
+
expiryReaper = new Thread(reaper, "JBM-expiry-reaper");
-
+
expiryReaper.setPriority(reaperPriority);
-
+
expiryReaper.start();
}
}
-
- private void routeDirect(final Queue queue, final ServerMessage message) throws Exception
- {
- if (queue.getFilter() == null || queue.getFilter().match(message))
- {
- queue.preroute(message, null);
- queue.route(message, null);
- }
- }
- private ServerMessage createQueueInfoMessage(final NotificationType type, final SimpleString queueName)
- {
- ServerMessage message = new ServerMessageImpl(storageManager.generateUniqueID());
- message.setBody(ChannelBuffers.EMPTY_BUFFER);
+ // private void routeDirect(final Queue queue, final ServerMessage message) throws Exception
+ // {
+ // if (queue.getFilter() == null || queue.getFilter().match(message))
+ // {
+ // queue.preroute(message, null);
+ // queue.route(message, null);
+ // }
+ // }
+ //
+ // private ServerMessage createQueueInfoMessage(final NotificationType type, final SimpleString queueName)
+ // {
+ // ServerMessage message = new ServerMessageImpl(storageManager.generateUniqueID());
+ // message.setBody(ChannelBuffers.EMPTY_BUFFER);
+ //
+ // message.setDestination(queueName);
+ //
+ // String uid = UUIDGenerator.getInstance().generateStringUUID();
+ //
+ // message.putStringProperty(ManagementHelper.HDR_NOTIFICATION_TYPE, new SimpleString(type.toString()));
+ // message.putLongProperty(ManagementHelper.HDR_NOTIFICATION_TIMESTAMP, System.currentTimeMillis());
+ //
+ // message.putStringProperty(new SimpleString("foobar"), new SimpleString(uid));
+ //
+ // return message;
+ // }
- message.setDestination(queueName);
-
- String uid = UUIDGenerator.getInstance().generateStringUUID();
-
- message.putStringProperty(ManagementHelper.HDR_NOTIFICATION_TYPE, new SimpleString(type.toString()));
- message.putLongProperty(ManagementHelper.HDR_NOTIFICATION_TIMESTAMP, System.currentTimeMillis());
-
- message.putStringProperty(new SimpleString("foobar"), new SimpleString(uid));
-
- return message;
- }
-
private int generateTransientID()
{
int start = transientIDSequence;
@@ -902,26 +962,26 @@
return oper;
}
}
-
+
private class Reaper implements Runnable
{
private boolean closed;
-
+
public synchronized void stop()
{
closed = true;
-
+
notify();
}
-
+
public synchronized void run()
{
while (true)
{
long toWait = reaperPeriod;
-
+
long start = System.currentTimeMillis();
-
+
while (!closed && toWait > 0)
{
try
@@ -931,33 +991,33 @@
catch (InterruptedException e)
{
}
-
+
long now = System.currentTimeMillis();
-
+
toWait -= now - start;
-
+
start = now;
}
-
+
if (closed)
{
return;
}
-
+
Map<SimpleString, Binding> nameMap = addressManager.getBindings();
-
+
List<Queue> queues = new ArrayList<Queue>();
-
+
for (Binding binding : nameMap.values())
{
if (binding.getType() == BindingType.LOCAL_QUEUE)
{
Queue queue = (Queue)binding.getBindable();
-
+
queues.add(queue);
}
}
-
+
for (Queue queue : queues)
{
try
@@ -982,8 +1042,6 @@
messagesToPage.add(message);
}
-
-
/* (non-Javadoc)
* @see org.jboss.messaging.core.transaction.TransactionOperation#getDistinctQueues()
*/
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/impl/SimpleAddressManager.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/impl/SimpleAddressManager.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/impl/SimpleAddressManager.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -21,9 +21,8 @@
*/
package org.jboss.messaging.core.postoffice.impl;
+import java.util.HashMap;
import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
import org.jboss.messaging.core.logging.Logger;
import org.jboss.messaging.core.postoffice.Address;
@@ -43,18 +42,22 @@
{
private static final Logger log = Logger.getLogger(SimpleAddressManager.class);
- private final ConcurrentMap<SimpleString, Bindings> mappings = new ConcurrentHashMap<SimpleString, Bindings>();
+ private final Map<SimpleString, Bindings> mappings = new HashMap<SimpleString, Bindings>();
- private final ConcurrentMap<SimpleString, Binding> nameMap = new ConcurrentHashMap<SimpleString, Binding>();
+ private final Map<SimpleString, Binding> nameMap = new HashMap<SimpleString, Binding>();
- public boolean addBinding(final Binding binding)
+ public void addBinding(final Binding binding)
{
- if (nameMap.putIfAbsent(binding.getUniqueName(), binding) != null)
+ if (nameMap.containsKey(binding.getUniqueName()))
{
throw new IllegalStateException("Binding already exists " + binding);
}
- return addMappingInternal(binding.getAddress(), binding);
+ nameMap.put(binding.getUniqueName(), binding);
+
+ addMappingInternal(binding.getAddress(), binding);
+
+ log.info(System.identityHashCode(this) + " adding binding " + binding.getUniqueName());
}
public Binding removeBinding(final SimpleString uniqueName)
@@ -77,7 +80,19 @@
}
public Binding getBinding(final SimpleString bindableName)
- {
+ {
+ log.info(System.identityHashCode(this) + " dumping bindings");
+
+ for (SimpleString name: nameMap.keySet())
+ {
+ log.info("binding name: " + name);
+ }
+
+ for (SimpleString address: mappings.keySet())
+ {
+ log.info("address name: " + address);
+ }
+
return nameMap.get(bindableName);
}
@@ -151,26 +166,17 @@
return theBinding;
}
- protected boolean addMappingInternal(final SimpleString address, final Binding binding)
+ protected void addMappingInternal(final SimpleString address, final Binding binding)
{
Bindings bindings = mappings.get(address);
- Bindings prevBindings = null;
-
if (bindings == null)
{
bindings = new BindingsImpl();
- prevBindings = mappings.putIfAbsent(address, bindings);
-
- if (prevBindings != null)
- {
- bindings = prevBindings;
- }
+ mappings.put(address, bindings);
}
bindings.addBinding(binding);
-
- return prevBindings != null;
}
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/impl/WildcardAddressManager.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/impl/WildcardAddressManager.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/postoffice/impl/WildcardAddressManager.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -23,10 +23,8 @@
import java.util.Collection;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import org.jboss.messaging.core.logging.Logger;
import org.jboss.messaging.core.postoffice.Address;
@@ -64,8 +62,8 @@
public Bindings getBindingsForRoutingAddress(final SimpleString address)
{
Bindings bindings = super.getBindingsForRoutingAddress(address);
-
- //this should only happen if we're routing to an address that has no mappings when we're running checkAllowable
+
+ // this should only happen if we're routing to an address that has no mappings when we're running checkAllowable
if (bindings == null && !wildCardAddresses.isEmpty())
{
Address add = addAndUpdateAddressMap(address);
@@ -88,43 +86,38 @@
}
return bindings;
}
-
+
/**
* If the address to add the binding to contains a wildcard then a copy of the binding (with the same underlying queue)
* will be added to the actual mappings. Otherwise the binding is added as normal.
*
* @param binding the binding to add
- * @return true if the address was a new mapping
*/
- public boolean addBinding(final Binding binding)
+ public void addBinding(final Binding binding)
{
- boolean exists = super.addBinding(binding);
- if (!exists)
+ log.info("Adding binding " + binding.getAddress() + " name " + binding.getUniqueName());
+ super.addBinding(binding);
+ Address add = addAndUpdateAddressMap(binding.getAddress());
+ if (add.containsWildCard())
{
- Address add = addAndUpdateAddressMap(binding.getAddress());
- if (add.containsWildCard())
+ for (Address destAdd : add.getLinkedAddresses())
{
- for (Address destAdd : add.getLinkedAddresses())
- {
- super.addMappingInternal(destAdd.getAddress(), binding);
- }
+ super.addMappingInternal(destAdd.getAddress(), binding);
}
- else
+ }
+ else
+ {
+ for (Address destAdd : add.getLinkedAddresses())
{
- for (Address destAdd : add.getLinkedAddresses())
+ Bindings bindings = super.getBindingsForRoutingAddress(destAdd.getAddress());
+ for (Binding b : bindings.getBindings())
{
- Bindings bindings = super.getBindingsForRoutingAddress(destAdd.getAddress());
- for (Binding b : bindings.getBindings())
- {
- super.addMappingInternal(binding.getAddress(), b);
- }
+ super.addMappingInternal(binding.getAddress(), b);
}
}
}
- return exists;
}
-
/**
* If the address is a wild card then the binding will be removed from the actual mappings for any linked address.
* otherwise it will be removed as normal.
@@ -243,7 +236,7 @@
private synchronized void removeAndUpdateAddressMap(final Address address)
{
- //we only remove if there are no bindings left
+ // we only remove if there are no bindings left
Bindings bindings = super.getBindingsForRoutingAddress(address.getAddress());
if (bindings == null || bindings.getBindings().size() == 0)
{
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/Channel.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/Channel.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/Channel.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -14,6 +14,7 @@
import java.util.concurrent.locks.Lock;
import org.jboss.messaging.core.exception.MessagingException;
+import org.jboss.messaging.core.server.replication.Replicator;
/**
* A Channel A Channel *does not* support concurrent access by more than one thread!
@@ -30,7 +31,7 @@
Packet sendBlocking(Packet packet) throws MessagingException;
- void replicatePacket(Packet packet, long replicatedChannelID, Runnable action);
+ //void replicatePacket(Packet packet, long replicatedChannelID, Runnable action);
void setHandler(ChannelHandler handler);
@@ -38,9 +39,9 @@
void close();
- void transferConnection(RemotingConnection newConnection, final long newID, final Channel replicatingChannel);
+ void transferConnection(RemotingConnection newConnection);
- void replayCommands(int lastReceivedCommandID, final long newID);
+ void replayCommands(int lastReceivedCommandID);
int getLastReceivedCommandID();
@@ -54,7 +55,7 @@
RemotingConnection getConnection();
- void executeOutstandingDelayedResults();
+ //void executeOutstandingDelayedResults();
void confirm(Packet packet);
@@ -64,5 +65,7 @@
void handlePacket(Packet packet);
- void waitForAllReplicationResponse();
+ //void waitForAllReplicationResponse();
+
+ void replicationResponseReceived(Replicator replicator);
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/RemotingConnection.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/RemotingConnection.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/RemotingConnection.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -75,5 +75,7 @@
long getBlockingCallTimeout();
- Object getTransferLock();
+ Object getTransferLock();
+
+ RemotingConnection getReplicatingConnection();
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/ChannelImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/ChannelImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/ChannelImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -48,6 +48,9 @@
import org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl;
import org.jboss.messaging.core.remoting.impl.wireformat.PacketsConfirmedMessage;
import org.jboss.messaging.core.remoting.spi.MessagingBuffer;
+import org.jboss.messaging.core.server.replication.Replicator;
+import org.jboss.messaging.core.server.replication.impl.JBMThread;
+import org.jboss.messaging.utils.Pair;
/**
* A ChannelImpl
@@ -86,11 +89,11 @@
private final Object sendBlockingLock = new Object();
- private final Object replicationLock = new Object();
+ // private final Object replicationLock = new Object();
private boolean failingOver;
- private final Queue<Runnable> responseActions = new ConcurrentLinkedQueue<Runnable>();
+ // private final Queue<Runnable> responseActions = new ConcurrentLinkedQueue<Runnable>();
private final int windowSize;
@@ -102,9 +105,9 @@
private CommandConfirmationHandler commandConfirmationHandler;
- private int responseActionCount;
+ // private int responseActionCount;
- private boolean playedResponsesOnFailure;
+ // private boolean playedResponsesOnFailure;
public ChannelImpl(final RemotingConnection connection, final long id, final int windowSize, final boolean block)
{
@@ -177,10 +180,30 @@
{
send(packet, false);
}
-
+
// This must never called by more than one thread concurrently
public void send(final Packet packet, final boolean flush)
{
+ //FIXME - this is a bit hacky
+
+ Thread t = Thread.currentThread();
+
+ if (t instanceof JBMThread)
+ {
+ JBMThread thread = (JBMThread)t;
+
+ if (thread.isRecording())
+ {
+ thread.getReplicator().registerWaitingChannel(this);
+
+ log.info("Queueing write");
+
+ queuedWrites.add(new Pair<Replicator, Packet>(thread.getReplicator(), packet));
+
+ return;
+ }
+ }
+
synchronized (sendLock)
{
packet.setChannelID(id);
@@ -226,6 +249,7 @@
if (connection.isActive() || packet.isWriteAlways())
{
+ log.info("actually writing packet " + packet.getType());
connection.getTransportConnection().write(buffer, flush);
}
}
@@ -294,7 +318,7 @@
{
resendCache.add(packet);
}
-
+
connection.getTransportConnection().write(buffer);
long toWait = connection.getBlockingCallTimeout();
@@ -349,98 +373,98 @@
// Must be synchronized since can be called by incoming session commands but also by deliveries
// Also needs to be synchronized with respect to replicatingChannelDead
- public void replicatePacket(final Packet packet, final long replicatedChannelID, final Runnable action)
- {
- packet.setChannelID(replicatedChannelID);
+ // public void replicatePacket(final Packet packet, final long replicatedChannelID, final Runnable action)
+ // {
+ // packet.setChannelID(replicatedChannelID);
+ //
+ // boolean runItNow = false;
+ //
+ // synchronized (replicationLock)
+ // {
+ // if (playedResponsesOnFailure && action != null)
+ // {
+ // // Already replicating channel failed, so just play the action now
+ //
+ // runItNow = true;
+ // }
+ // else
+ // {
+ // if (action != null)
+ // {
+ // responseActions.add(action);
+ //
+ // responseActionCount++;
+ // }
+ //
+ // final MessagingBuffer buffer = connection.getTransportConnection()
+ // .createBuffer(packet.getRequiredBufferSize());
+ //
+ // packet.encode(buffer);
+ //
+ // connection.getTransportConnection().write(buffer);
+ // }
+ // }
+ //
+ // // Execute outside lock
+ //
+ // if (runItNow)
+ // {
+ // action.run();
+ // }
+ // }
- boolean runItNow = false;
-
- synchronized (replicationLock)
- {
- if (playedResponsesOnFailure && action != null)
- {
- // Already replicating channel failed, so just play the action now
-
- runItNow = true;
- }
- else
- {
- if (action != null)
- {
- responseActions.add(action);
-
- responseActionCount++;
- }
-
- final MessagingBuffer buffer = connection.getTransportConnection()
- .createBuffer(packet.getRequiredBufferSize());
-
- packet.encode(buffer);
-
- connection.getTransportConnection().write(buffer);
- }
- }
-
- // Execute outside lock
-
- if (runItNow)
- {
- action.run();
- }
- }
-
public void setCommandConfirmationHandler(final CommandConfirmationHandler handler)
{
this.commandConfirmationHandler = handler;
}
- public void executeOutstandingDelayedResults()
- {
- // Execute on different thread to avoid deadlock
+ // public void executeOutstandingDelayedResults()
+ // {
+ // // Execute on different thread to avoid deadlock
+ //
+ // new Thread()
+ // {
+ // public void run()
+ // {
+ // doExecuteOutstandingDelayedResults();
+ // }
+ // }.start();
+ // }
+ //
+ // private void doExecuteOutstandingDelayedResults()
+ // {
+ // List<Runnable> toRun = new ArrayList<Runnable>();
+ //
+ // synchronized (replicationLock)
+ // {
+ // // Execute all the response actions now
+ //
+ // while (true)
+ // {
+ // Runnable action = responseActions.poll();
+ //
+ // if (action != null)
+ // {
+ // toRun.add(action);
+ // }
+ // else
+ // {
+ // break;
+ // }
+ // }
+ //
+ // responseActionCount = 0;
+ //
+ // playedResponsesOnFailure = true;
+ //
+ // for (Runnable action : toRun)
+ // {
+ // action.run();
+ // }
+ // }
+ //
+ // }
- new Thread()
- {
- public void run()
- {
- doExecuteOutstandingDelayedResults();
- }
- }.start();
- }
-
- private void doExecuteOutstandingDelayedResults()
- {
- List<Runnable> toRun = new ArrayList<Runnable>();
-
- synchronized (replicationLock)
- {
- // Execute all the response actions now
-
- while (true)
- {
- Runnable action = responseActions.poll();
-
- if (action != null)
- {
- toRun.add(action);
- }
- else
- {
- break;
- }
- }
-
- responseActionCount = 0;
-
- playedResponsesOnFailure = true;
-
- for (Runnable action : toRun)
- {
- action.run();
- }
- }
-
- }
-
public void setHandler(final ChannelHandler handler)
{
this.handler = handler;
@@ -466,9 +490,7 @@
closed = true;
}
- public void transferConnection(final RemotingConnection newConnection,
- final long newChannelID,
- final Channel replicatingChannel)
+ public void transferConnection(final RemotingConnection newConnection)
{
// Needs to synchronize on the connection to make sure no packets from
// the old connection get processed after transfer has occurred
@@ -476,36 +498,32 @@
{
connection.removeChannel(id);
- if (replicatingChannel != null)
- {
- // If we're reconnecting to a live node which is replicated then there will be a replicating channel
- // too. We need to then make sure that all replication responses come back since packets aren't
- // considered confirmed until response comes back and is processed. Otherwise responses to previous
- // message sends could come back after reconnection resulting in clients resending same message
- // since it wasn't confirmed yet.
- replicatingChannel.waitForAllReplicationResponse();
- }
+// if (replicatingChannel != null)
+// {
+// // If we're reconnecting to a live node which is replicated then there will be a replicating channel
+// // too. We need to then make sure that all replication responses come back since packets aren't
+// // considered confirmed until response comes back and is processed. Otherwise responses to previous
+// // message sends could come back after reconnection resulting in clients resending same message
+// // since it wasn't confirmed yet.
+// replicatingChannel.waitForAllReplicationResponse();
+// }
// And switch it
final RemotingConnectionImpl rnewConnection = (RemotingConnectionImpl)newConnection;
- rnewConnection.putChannel(newChannelID, this);
+ rnewConnection.putChannel(id, this);
connection = rnewConnection;
-
- this.id = newChannelID;
}
}
- public void replayCommands(final int otherLastReceivedCommandID, final long newChannelID)
+ public void replayCommands(final int otherLastReceivedCommandID)
{
clearUpTo(otherLastReceivedCommandID);
for (final Packet packet : resendCache)
{
- packet.setChannelID(newChannelID);
-
doWrite(packet);
}
}
@@ -591,16 +609,10 @@
return;
}
- else if (packet.getType() == REPLICATION_RESPONSE)
- {
- replicateResponseReceived();
-
- return;
- }
else
{
if (packet.isResponse())
- {
+ {
response = packet;
confirm(packet);
@@ -622,96 +634,96 @@
}
}
- replicateComplete();
+ // replicateComplete();
}
-
- public void waitForAllReplicationResponse()
- {
- synchronized (replicationLock)
- {
- long toWait = 10000; // TODO don't hardcode timeout
- long start = System.currentTimeMillis();
+ // public void waitForAllReplicationResponse()
+ // {
+ // synchronized (replicationLock)
+ // {
+ // long toWait = 10000; // TODO don't hardcode timeout
+ //
+ // long start = System.currentTimeMillis();
+ //
+ // while (responseActionCount > 0 && toWait > 0)
+ // {
+ // try
+ // {
+ // replicationLock.wait();
+ // }
+ // catch (InterruptedException e)
+ // {
+ // }
+ //
+ // long now = System.currentTimeMillis();
+ //
+ // toWait -= now - start;
+ //
+ // start = now;
+ // }
+ //
+ // if (toWait <= 0)
+ // {
+ // log.warn("Timed out waiting for replication responses to return");
+ // }
+ // }
+ // }
- while (responseActionCount > 0 && toWait > 0)
- {
- try
- {
- replicationLock.wait();
- }
- catch (InterruptedException e)
- {
- }
+ // private void replicateComplete()
+ // {
+ // if (!connection.isActive() && id != 0)
+ // {
+ // // We're on backup and not ping channel so send back a replication response
+ //
+ // Packet packet = new PacketImpl(REPLICATION_RESPONSE);
+ //
+ // packet.setChannelID(2);
+ //
+ // doWrite(packet);
+ // }
+ // }
- long now = System.currentTimeMillis();
-
- toWait -= now - start;
-
- start = now;
- }
-
- if (toWait <= 0)
- {
- log.warn("Timed out waiting for replication responses to return");
- }
- }
- }
-
- private void replicateComplete()
- {
- if (!connection.isActive() && id != 0)
- {
- // We're on backup and not ping channel so send back a replication response
-
- Packet packet = new PacketImpl(REPLICATION_RESPONSE);
-
- packet.setChannelID(2);
-
- doWrite(packet);
- }
- }
-
// This will never get called concurrently by more than one thread
// TODO it's not ideal synchronizing this since it forms a contention point with replication
// but we need to do this to protect it w.r.t. the check on replicatingChannel
- private void replicateResponseReceived()
- {
- Runnable result = null;
+ // private void replicateResponseReceived()
+ // {
+ // Runnable result = null;
+ //
+ // synchronized (replicationLock)
+ // {
+ // if (playedResponsesOnFailure)
+ // {
+ // return;
+ // }
+ //
+ // result = responseActions.poll();
+ //
+ // if (result == null)
+ // {
+ // throw new IllegalStateException("Cannot find response action");
+ // }
+ // }
+ //
+ // // Must execute outside of lock
+ // if (result != null)
+ // {
+ // result.run();
+ //
+ // // TODO - we can optimise this not to lock every time - only if waiting for all replications to return
+ // synchronized (replicationLock)
+ // {
+ // responseActionCount--;
+ //
+ // if (responseActionCount == 0)
+ // {
+ // replicationLock.notify();
+ // }
+ // }
+ // }
+ // }
- synchronized (replicationLock)
- {
- if (playedResponsesOnFailure)
- {
- return;
- }
-
- result = responseActions.poll();
-
- if (result == null)
- {
- throw new IllegalStateException("Cannot find response action");
- }
- }
-
- // Must execute outside of lock
- if (result != null)
- {
- result.run();
-
- // TODO - we can optimise this not to lock every time - only if waiting for all replications to return
- synchronized (replicationLock)
- {
- responseActionCount--;
-
- if (responseActionCount == 0)
- {
- replicationLock.notify();
- }
- }
- }
- }
-
private void doWrite(final Packet packet)
{
final MessagingBuffer buffer = connection.getTransportConnection().createBuffer(packet.getRequiredBufferSize());
@@ -763,4 +775,28 @@
sendSemaphore.release(sizeToFree);
}
}
+
+
+ private java.util.Queue<Pair<Replicator, Packet>> queuedWrites = new ConcurrentLinkedQueue<Pair<Replicator, Packet>>();
+
+ public void replicationResponseReceived(final Replicator replicator)
+ {
+ Pair<Replicator, Packet> pair = queuedWrites.peek();
+
+ if (pair != null && pair.a == replicator)
+ {
+ do
+ {
+ queuedWrites.remove();
+
+ log.info("replication response received, sending packet " + pair.b);
+ send(pair.b);
+
+ pair = queuedWrites.peek();
+ }
+ while (pair != null && pair.a.isResponseReceived());
+ }
+ }
+
+
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/PacketDecoder.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/PacketDecoder.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/PacketDecoder.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -36,7 +36,7 @@
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.REPLICATE_ACKNOWLEDGE;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.REPLICATE_ADD_REMOTE_CONSUMER;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.REPLICATE_ADD_REMOTE_QUEUE_BINDING;
-import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.REPLICATE_CREATESESSION;
+import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.REPLICATE_LOCK_SEQUENCES;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.REPLICATE_REDISTRIBUTION;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.REPLICATE_REMOVE_REMOTE_CONSUMER;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.REPLICATE_REMOVE_REMOTE_QUEUE_BINDING;
@@ -56,7 +56,6 @@
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_QUEUEQUERY_RESP;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_RECEIVE_CONTINUATION;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_RECEIVE_MSG;
-import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_REPLICATE_DELIVERY;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_ROLLBACK;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_SEND;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_SEND_CONTINUATION;
@@ -80,6 +79,7 @@
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_XA_START;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_XA_SUSPEND;
+import org.jboss.messaging.core.logging.Logger;
import org.jboss.messaging.core.remoting.Packet;
import org.jboss.messaging.core.remoting.impl.wireformat.CreateQueueMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.CreateSessionMessage;
@@ -91,7 +91,6 @@
import org.jboss.messaging.core.remoting.impl.wireformat.Ping;
import org.jboss.messaging.core.remoting.impl.wireformat.ReattachSessionMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.ReattachSessionResponseMessage;
-import org.jboss.messaging.core.remoting.impl.wireformat.ReplicateCreateSessionMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.RollbackMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionAcknowledgeMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionBindingQueryMessage;
@@ -124,13 +123,14 @@
import org.jboss.messaging.core.remoting.impl.wireformat.SessionXASetTimeoutResponseMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionXAStartMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateAcknowledgeMessage;
+import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateLockSequenceMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRedistributionMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRemoteBindingAddedMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRemoteBindingRemovedMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRemoteConsumerAddedMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRemoteConsumerRemovedMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateStartupInfoMessage;
-import org.jboss.messaging.core.remoting.impl.wireformat.replication.SessionReplicateDeliveryMessage;
+import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicationResponseMessage;
import org.jboss.messaging.core.remoting.spi.MessagingBuffer;
/**
@@ -142,9 +142,13 @@
*/
public class PacketDecoder
{
+ private static final Logger log = Logger.getLogger(PacketDecoder.class);
+
public Packet decode(final MessagingBuffer in)
{
final byte packetType = in.readByte();
+
+ log.info("decoding packet " + packetType);
Packet packet;
@@ -172,7 +176,7 @@
}
case REPLICATION_RESPONSE:
{
- packet = new PacketImpl(REPLICATION_RESPONSE);
+ packet = new ReplicationResponseMessage();
break;
}
case CREATESESSION:
@@ -180,11 +184,6 @@
packet = new CreateSessionMessage();
break;
}
- case REPLICATE_CREATESESSION:
- {
- packet = new ReplicateCreateSessionMessage();
- break;
- }
case CREATESESSION_RESP:
{
packet = new CreateSessionResponseMessage();
@@ -415,11 +414,6 @@
packet = new ReplicateRemoteConsumerRemovedMessage();
break;
}
- case SESS_REPLICATE_DELIVERY:
- {
- packet = new SessionReplicateDeliveryMessage();
- break;
- }
case REPLICATE_STARTUP_INFO:
{
packet = new ReplicateStartupInfoMessage();
@@ -435,6 +429,11 @@
packet = new ReplicateRedistributionMessage();
break;
}
+ case REPLICATE_LOCK_SEQUENCES:
+ {
+ packet = new ReplicateLockSequenceMessage();
+ break;
+ }
default:
{
throw new IllegalArgumentException("Invalid type: " + packetType);
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/RemotingConnectionImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/RemotingConnectionImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/RemotingConnectionImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -84,6 +84,8 @@
// -----------------------------------------------------------------------------------
private final Connection transportConnection;
+
+ private final RemotingConnection replicatingConnection;
private final Map<Long, Channel> channels = new ConcurrentHashMap<Long, Channel>();
@@ -127,21 +129,23 @@
final long blockingCallTimeout,
final List<Interceptor> interceptors)
{
- this(transportConnection, blockingCallTimeout, interceptors, true, true);
+ this(transportConnection, null, blockingCallTimeout, interceptors, true, true);
}
/*
* Create a server side connection
*/
public RemotingConnectionImpl(final Connection transportConnection,
+ final RemotingConnection replicatingConnection,
final List<Interceptor> interceptors,
final boolean active)
{
- this(transportConnection, -1, interceptors, active, false);
+ this(transportConnection, replicatingConnection, -1, interceptors, active, false);
}
private RemotingConnectionImpl(final Connection transportConnection,
+ final RemotingConnection replicatingConnection,
final long blockingCallTimeout,
final List<Interceptor> interceptors,
final boolean active,
@@ -149,6 +153,8 @@
{
this.transportConnection = transportConnection;
+
+ this.replicatingConnection = replicatingConnection;
this.blockingCallTimeout = blockingCallTimeout;
@@ -284,15 +290,6 @@
for (Channel channel : channels.values())
{
- // channel.lock.lock();
- // try
- // {
- // channel.sendCondition.signalAll();
- // }
- // finally
- // {
- // channel.lock.unlock();
- // }
channel.returnBlocking();
}
}
@@ -358,6 +355,11 @@
{
return blockingCallTimeout;
}
+
+ public RemotingConnection getReplicatingConnection()
+ {
+ return replicatingConnection;
+ }
// Buffer Handler implementation
// ----------------------------------------------------
@@ -365,6 +367,8 @@
public void bufferReceived(final Object connectionID, final MessagingBuffer buffer)
{
final Packet packet = decoder.decode(buffer);
+
+ log.info("packet received " + packet.getType());
synchronized (transferLock)
{
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/invm/InVMConnection.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/invm/InVMConnection.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/invm/InVMConnection.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -50,6 +50,8 @@
private final String id;
private boolean closed;
+
+ private volatile boolean closing;
private final int serverID;
@@ -82,8 +84,6 @@
listener.connectionCreated(this);
}
- private volatile boolean closing;
-
public void close()
{
if (closing)
@@ -123,18 +123,24 @@
{
try
{
+ log.info("writing on invm connection");
executor.execute(new Runnable()
{
public void run()
{
try
{
+ log.info("runnable running");
if (!closed)
{
buffer.readInt(); // read and discard
handler.bufferReceived(id, buffer);
}
+ else
+ {
+ log.info("it's closed");
+ }
}
catch (Exception e)
{
@@ -148,6 +154,7 @@
catch (RejectedExecutionException e)
{
// Ignore - this can happen if server/client is shutdown and another request comes in
+ log.error("shutdown", e);
}
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/PacketImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/PacketImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/PacketImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -64,11 +64,9 @@
public static final byte REATTACH_SESSION_RESP = 33;
- public static final byte REPLICATE_CREATESESSION = 34;
-
- public static final byte CREATE_QUEUE = 35;
+ public static final byte CREATE_QUEUE = 34;
- public static final byte DELETE_QUEUE = 36;
+ public static final byte DELETE_QUEUE = 35;
// Session
@@ -146,8 +144,6 @@
//Replication
- public static final byte SESS_REPLICATE_DELIVERY = 90;
-
public static final byte REPLICATE_ADD_REMOTE_QUEUE_BINDING = 91;
public static final byte REPLICATE_REMOVE_REMOTE_QUEUE_BINDING = 92;
@@ -162,6 +158,8 @@
public static final byte REPLICATE_REDISTRIBUTION = 97;
+ public static final byte REPLICATE_LOCK_SEQUENCES = 98;
+
// Static --------------------------------------------------------
public PacketImpl(final byte type)
@@ -189,6 +187,11 @@
public int encode(final MessagingBuffer buffer)
{
+// if (this.type == PacketImpl.EXCEPTION)
+// {
+// log.info("encoding exception", new Exception());
+// }
+
// The standard header fields
buffer.writeInt(0); // The length gets filled in at the end
buffer.writeByte(type);
Deleted: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/ReplicateCreateSessionMessage.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/ReplicateCreateSessionMessage.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/ReplicateCreateSessionMessage.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -1,264 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.messaging.core.remoting.impl.wireformat;
-
-import org.jboss.messaging.core.remoting.spi.MessagingBuffer;
-import org.jboss.messaging.utils.DataConstants;
-
-/**
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>.
- *
- * @version <tt>$Revision$</tt>
- */
-public class ReplicateCreateSessionMessage extends PacketImpl
-{
- // Constants -----------------------------------------------------
-
- // Attributes ----------------------------------------------------
-
- private String name;
-
- private long replicatedSessionChannelID;
-
- private long originalSessionChannelID;
-
- private int version;
-
- private String username;
-
- private String password;
-
- private int minLargeMessageSize;
-
- private boolean xa;
-
- private boolean autoCommitSends;
-
- private boolean autoCommitAcks;
-
- private boolean preAcknowledge;
-
- private int windowSize;
-
- // Static --------------------------------------------------------
-
- // Constructors --------------------------------------------------
-
- public ReplicateCreateSessionMessage(final String name,
- final long replicatedSessionChannelID,
- final long originalSessionChannelID,
- final int version,
- final String username,
- final String password,
- final int minLargeMessageSize,
- final boolean xa,
- final boolean autoCommitSends,
- final boolean autoCommitAcks,
- final boolean preAcknowledge,
- final int windowSize)
- {
- super(REPLICATE_CREATESESSION);
-
- this.name = name;
-
- this.replicatedSessionChannelID = replicatedSessionChannelID;
-
- this.originalSessionChannelID = originalSessionChannelID;
-
- this.version = version;
-
- this.username = username;
-
- this.password = password;
-
- this.minLargeMessageSize = minLargeMessageSize;
-
- this.xa = xa;
-
- this.autoCommitSends = autoCommitSends;
-
- this.autoCommitAcks = autoCommitAcks;
-
- this.preAcknowledge = preAcknowledge;
-
- this.windowSize = windowSize;
- }
-
- public ReplicateCreateSessionMessage()
- {
- super(REPLICATE_CREATESESSION);
- }
-
- // Public --------------------------------------------------------
-
- public String getName()
- {
- return name;
- }
-
- public long getReplicatedSessionChannelID()
- {
- return replicatedSessionChannelID;
- }
-
- public long getOriginalSessionChannelID()
- {
- return originalSessionChannelID;
- }
-
- public int getVersion()
- {
- return version;
- }
-
- public String getUsername()
- {
- return username;
- }
-
- public String getPassword()
- {
- return password;
- }
-
- public int getMinLargeMessageSize()
- {
- return minLargeMessageSize;
- }
-
- public boolean isXA()
- {
- return xa;
- }
-
- public boolean isAutoCommitSends()
- {
- return autoCommitSends;
- }
-
- public boolean isAutoCommitAcks()
- {
- return autoCommitAcks;
- }
-
- public boolean isPreAcknowledge()
- {
- return preAcknowledge;
- }
-
- public int getWindowSize()
- {
- return windowSize;
- }
-
- public int getRequiredBufferSize()
- {
- return BASIC_PACKET_SIZE +
- stringEncodeSize(name) + // buffer.writeString(name);
- DataConstants.SIZE_LONG + // buffer.writeLong(originalSessionChannelID);
- DataConstants.SIZE_LONG + // buffer.writeLong(replicatedSessionChannelID);
- DataConstants.SIZE_INT + // buffer.writeInt(version);
- nullableStringEncodeSize(username) + // buffer.writeNullableString(username);
- nullableStringEncodeSize(password) + // buffer.writeNullableString(password);
- DataConstants.SIZE_INT + // buffer.writeInt(minLargeMessageSize);
- DataConstants.SIZE_BOOLEAN + // buffer.writeBoolean(xa);
- DataConstants.SIZE_BOOLEAN + // buffer.writeBoolean(autoCommitSends);
- DataConstants.SIZE_BOOLEAN + // buffer.writeBoolean(autoCommitAcks);
- DataConstants.SIZE_INT + // buffer.writeInt(windowSize);
- DataConstants.SIZE_BOOLEAN; // buffer.writeBoolean(preAcknowledge);
- }
-
- @Override
- public void encodeBody(final MessagingBuffer buffer)
- {
- buffer.writeString(name);
- buffer.writeLong(originalSessionChannelID);
- buffer.writeLong(replicatedSessionChannelID);
- buffer.writeInt(version);
- buffer.writeNullableString(username);
- buffer.writeNullableString(password);
- buffer.writeInt(minLargeMessageSize);
- buffer.writeBoolean(xa);
- buffer.writeBoolean(autoCommitSends);
- buffer.writeBoolean(autoCommitAcks);
- buffer.writeInt(windowSize);
- buffer.writeBoolean(preAcknowledge);
- }
-
- @Override
- public void decodeBody(final MessagingBuffer buffer)
- {
- name = buffer.readString();
- originalSessionChannelID = buffer.readLong();
- replicatedSessionChannelID = buffer.readLong();
- version = buffer.readInt();
- username = buffer.readNullableString();
- password = buffer.readNullableString();
- minLargeMessageSize = buffer.readInt();
- xa = buffer.readBoolean();
- autoCommitSends = buffer.readBoolean();
- autoCommitAcks = buffer.readBoolean();
- windowSize = buffer.readInt();
- preAcknowledge = buffer.readBoolean();
- }
-
- @Override
- public boolean equals(final Object other)
- {
- if (other instanceof ReplicateCreateSessionMessage == false)
- {
- return false;
- }
-
- ReplicateCreateSessionMessage r = (ReplicateCreateSessionMessage)other;
-
- boolean matches = super.equals(other) && name.equals(r.name) &&
- originalSessionChannelID == r.originalSessionChannelID &&
- replicatedSessionChannelID == r.replicatedSessionChannelID &&
- version == r.version &&
- xa == r.xa &&
- autoCommitSends == r.autoCommitSends &&
- autoCommitAcks == r.autoCommitAcks &&
- (username == null ? r.username == null : username.equals(r.username)) &&
- (password == null ? r.password == null : password.equals(r.password)) &&
- minLargeMessageSize == r.minLargeMessageSize &&
- windowSize == r.windowSize;
-
- return matches;
- }
-
- @Override
- public final boolean isRequiresConfirmations()
- {
- return false;
- }
-
- // Package protected ---------------------------------------------
-
- // Protected -----------------------------------------------------
-
- // Private -------------------------------------------------------
-
- // Inner classes -------------------------------------------------
-}
Added: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/replication/ReplicateLockSequenceMessage.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/replication/ReplicateLockSequenceMessage.java (rev 0)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/replication/ReplicateLockSequenceMessage.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -0,0 +1,96 @@
+/*
+ * JBoss, Home of Professional Open Source Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors by
+ * the @authors tag. See the copyright.txt in the distribution for a full listing of individual contributors. This is
+ * free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
+ * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details. You should have received a copy of the GNU Lesser General Public License along with this software; if not,
+ * write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
+ * site: http://www.fsf.org.
+ */
+
+package org.jboss.messaging.core.remoting.impl.wireformat.replication;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl;
+import org.jboss.messaging.core.remoting.spi.MessagingBuffer;
+import org.jboss.messaging.utils.DataConstants;
+import org.jboss.messaging.utils.Pair;
+
+/**
+ *
+ * A ReplicateLockSequenceMessage
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ *
+ */
+public class ReplicateLockSequenceMessage extends PacketImpl
+{
+ // Constants -----------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ private List<Pair<Long, Integer>> sequences;
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ public ReplicateLockSequenceMessage(final List<Pair<Long, Integer>> sequences)
+ {
+ super(REPLICATE_LOCK_SEQUENCES);
+
+ this.sequences = sequences;
+ }
+
+ // Public --------------------------------------------------------
+
+ public ReplicateLockSequenceMessage()
+ {
+ super(REPLICATE_LOCK_SEQUENCES);
+ }
+
+ public int getRequiredBufferSize()
+ {
+ return BASIC_PACKET_SIZE + DataConstants.SIZE_INT + sequences.size() * (DataConstants.SIZE_LONG + DataConstants.SIZE_INT);
+ }
+
+ @Override
+ public void encodeBody(final MessagingBuffer buffer)
+ {
+ buffer.writeInt(sequences.size());
+ for (Pair<Long, Integer> sequence : sequences)
+ {
+ buffer.writeLong(sequence.a);
+ buffer.writeInt(sequence.b);
+ }
+ }
+
+ @Override
+ public void decodeBody(final MessagingBuffer buffer)
+ {
+ int len = buffer.readInt();
+ sequences = new ArrayList<Pair<Long, Integer>>(len);
+ for (int i = 0; i < len; i++)
+ {
+ sequences.add(new Pair<Long, Integer>(buffer.readLong(), buffer.readInt()));
+ }
+ }
+
+ public List<Pair<Long, Integer>> getSequences()
+ {
+ return sequences;
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ // Inner classes -------------------------------------------------
+}
Added: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/replication/ReplicationResponseMessage.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/replication/ReplicationResponseMessage.java (rev 0)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/replication/ReplicationResponseMessage.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.messaging.core.remoting.impl.wireformat.replication;
+
+import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.REPLICATION_RESPONSE;
+
+import org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl;
+
+/**
+ * A ReplicationResponseMessage
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ *
+ */
+public class ReplicationResponseMessage extends PacketImpl
+{
+ // Constants -----------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ public ReplicationResponseMessage()
+ {
+ super(REPLICATION_RESPONSE);
+ }
+
+ // Public --------------------------------------------------------
+
+ @Override
+ public boolean isWriteAlways()
+ {
+ return true;
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ // Inner classes -------------------------------------------------
+}
+
Deleted: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/replication/SessionReplicateDeliveryMessage.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/replication/SessionReplicateDeliveryMessage.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/impl/wireformat/replication/SessionReplicateDeliveryMessage.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -1,110 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source Copyright 2005-2008, Red Hat Middleware LLC, and individual contributors by
- * the @authors tag. See the copyright.txt in the distribution for a full listing of individual contributors. This is
- * free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
- * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
- * details. You should have received a copy of the GNU Lesser General Public License along with this software; if not,
- * write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
- * site: http://www.fsf.org.
- */
-
-package org.jboss.messaging.core.remoting.impl.wireformat.replication;
-
-import org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl;
-import org.jboss.messaging.core.remoting.spi.MessagingBuffer;
-import org.jboss.messaging.utils.DataConstants;
-
-/**
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- */
-public class SessionReplicateDeliveryMessage extends PacketImpl
-{
- // Constants -----------------------------------------------------
-
- // Attributes ----------------------------------------------------
-
- private long consumerID;
-
- private long messageID;
-
- // Static --------------------------------------------------------
-
- // Constructors --------------------------------------------------
-
- public SessionReplicateDeliveryMessage(final long consumerID, final long messageID)
- {
- super(SESS_REPLICATE_DELIVERY);
-
- this.consumerID = consumerID;
-
- this.messageID = messageID;
- }
-
- public SessionReplicateDeliveryMessage()
- {
- super(SESS_REPLICATE_DELIVERY);
- }
-
- // Public --------------------------------------------------------
-
- public long getConsumerID()
- {
- return consumerID;
- }
-
- public long getMessageID()
- {
- return messageID;
- }
-
- public int getRequiredBufferSize()
- {
- return BASIC_PACKET_SIZE + DataConstants.SIZE_LONG + DataConstants.SIZE_LONG;
- }
-
- @Override
- public void encodeBody(final MessagingBuffer buffer)
- {
- buffer.writeLong(consumerID);
-
- buffer.writeLong(messageID);
- }
-
- @Override
- public void decodeBody(final MessagingBuffer buffer)
- {
- consumerID = buffer.readLong();
-
- messageID = buffer.readLong();
- }
-
- @Override
- public boolean isRequiresConfirmations()
- {
- return false;
- }
-
- @Override
- public boolean equals(final Object other)
- {
- if (other instanceof SessionReplicateDeliveryMessage == false)
- {
- return false;
- }
-
- SessionReplicateDeliveryMessage r = (SessionReplicateDeliveryMessage)other;
-
- return super.equals(other) && consumerID == r.consumerID && messageID == r.messageID;
- }
-
- // Package protected ---------------------------------------------
-
- // Protected -----------------------------------------------------
-
- // Private -------------------------------------------------------
-
- // Inner classes -------------------------------------------------
-}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/server/impl/RemotingServiceImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/server/impl/RemotingServiceImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/remoting/server/impl/RemotingServiceImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -53,6 +53,8 @@
import org.jboss.messaging.core.remoting.spi.MessagingBuffer;
import org.jboss.messaging.core.server.MessagingServer;
import org.jboss.messaging.core.server.impl.MessagingServerPacketHandler;
+import org.jboss.messaging.core.server.replication.Replicator;
+import org.jboss.messaging.core.server.replication.impl.ReplicatorImpl;
/**
* @author <a href="mailto:jmesnil at redhat.com">Jeff Mesnil</a>
@@ -280,12 +282,46 @@
throw new IllegalStateException("Unable to create connection, server hasn't finished starting up");
}
- RemotingConnection rc = new RemotingConnectionImpl(connection, interceptors, !config.isBackup());
+ RemotingConnection replicatingConnection = server.getReplicatingConnection();
+
+ RemotingConnection rc = new RemotingConnectionImpl(connection, replicatingConnection, interceptors, !config.isBackup());
+ log.info("** creating connection " + System.identityHashCode(rc) + " replicating connection is " + replicatingConnection +
+ " backup is " + config.isBackup());
+
Channel channel1 = rc.getChannel(1, -1, false);
+
+ final Replicator replicator;
+
+ if (replicatingConnection != null)
+ {
+ Channel replicatingChannel = replicatingConnection.getChannel(1, -1, false);
+
+ replicator = new ReplicatorImpl(replicatingChannel);
+
+ replicatingChannel.setHandler(new ChannelHandler()
+ {
+ public void handlePacket(final Packet packet)
+ {
+ if (packet.getType() == PacketImpl.REPLICATION_RESPONSE)
+ {
+ log.info("*** got replication response from create session");
+ replicator.replicationResponseReceived();
+ }
+ else
+ {
+ throw new IllegalArgumentException("Invalid packet " + packet.getType());
+ }
+ }
+ });
+ }
+ else
+ {
+ replicator = null;
+ }
+
+ ChannelHandler handler = new MessagingServerPacketHandler(server, channel1, rc, replicator);
- ChannelHandler handler = new MessagingServerPacketHandler(server, channel1, rc);
-
channel1.setHandler(handler);
connections.put(connection.getID(), rc);
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/MessagingServer.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/MessagingServer.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/MessagingServer.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -18,7 +18,6 @@
import javax.management.MBeanServer;
import org.jboss.messaging.core.config.Configuration;
-import org.jboss.messaging.core.deployers.DeploymentManager;
import org.jboss.messaging.core.management.ManagementService;
import org.jboss.messaging.core.management.impl.MessagingServerControlImpl;
import org.jboss.messaging.core.persistence.StorageManager;
@@ -71,8 +70,7 @@
ReattachSessionResponseMessage reattachSession(RemotingConnection connection, String name, int lastReceivedCommandID) throws Exception;
CreateSessionResponseMessage createSession(String name,
- long channelID,
- long replicatedSessionID,
+ long channelID,
String username,
String password,
int minLargeMessageSize,
@@ -82,22 +80,9 @@
boolean autoCommitAcks,
boolean preAcknowledge,
boolean xa,
- int producerWindowSize) throws Exception;
+ int producerWindowSize,
+ boolean direct) throws Exception;
- void replicateCreateSession(String name,
- long channelID,
- long originalSessionID,
- String username,
- String password,
- int minLargeMessageSize,
- int incrementingVersion,
- RemotingConnection remotingConnection,
- boolean autoCommitSends,
- boolean autoCommitAcks,
- boolean preAcknowledge,
- boolean xa,
- int sendWindowSize) throws Exception;
-
void removeSession(String name) throws Exception;
ServerSession getSession(String name);
@@ -124,7 +109,9 @@
SimpleString getNodeID();
- Channel getReplicatingChannel();
+ //Channel getReplicatingChannel();
+
+ RemotingConnection getReplicatingConnection();
void initialiseBackup(UUID nodeID, long currentMessageID) throws Exception;
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/Queue.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/Queue.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/Queue.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -27,7 +27,6 @@
import java.util.concurrent.Executor;
import org.jboss.messaging.core.filter.Filter;
-import org.jboss.messaging.core.remoting.Channel;
import org.jboss.messaging.core.transaction.Transaction;
import org.jboss.messaging.utils.SimpleString;
@@ -46,10 +45,8 @@
SimpleString getName();
- long getPersistenceID();
+ long getID();
- void setPersistenceID(long id);
-
Filter getFilter();
boolean isDurable();
@@ -139,16 +136,14 @@
boolean consumerFailedOver();
- void addRedistributor(long delay, Executor executor, final Channel replicatingChannel);
+ void addRedistributor(long delay, Executor executor);
- void cancelRedistributor() throws Exception;
-
// Only used in testing
void deliverNow();
boolean checkDLQ(MessageReference ref) throws Exception;
- void lockDelivery();
+ void lock();
- void unlockDelivery();
+ void unlock();
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/ServerConsumer.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/ServerConsumer.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/ServerConsumer.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -55,9 +55,9 @@
void failedOver();
- void deliverReplicated(long messageID) throws Exception;
+ //void deliverReplicated(long messageID) throws Exception;
- void lock();
-
- void unlock();
+// void lock();
+//
+// void unlock();
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/ServerSession.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/ServerSession.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/ServerSession.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -26,7 +26,6 @@
import org.jboss.messaging.core.remoting.Packet;
import org.jboss.messaging.core.remoting.RemotingConnection;
import org.jboss.messaging.core.remoting.impl.wireformat.CreateQueueMessage;
-import org.jboss.messaging.core.remoting.impl.wireformat.PacketsConfirmedMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.RollbackMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionAcknowledgeMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionBindingQueryMessage;
@@ -48,7 +47,6 @@
import org.jboss.messaging.core.remoting.impl.wireformat.SessionXARollbackMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionXASetTimeoutMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionXAStartMessage;
-import org.jboss.messaging.core.remoting.impl.wireformat.replication.SessionReplicateDeliveryMessage;
import org.jboss.messaging.core.server.impl.ServerSessionPacketHandler;
/**
@@ -78,7 +76,12 @@
void close() throws Exception;
void promptDelivery(Queue queue);
+
+
+ void handleCreateConsumer(SessionCreateConsumerMessage packet);
+
+
void handleAcknowledge(final SessionAcknowledgeMessage packet);
void handleExpired(final SessionExpiredMessage packet);
@@ -119,8 +122,6 @@
void handleDeleteQueue(SessionDeleteQueueMessage packet);
- void handleCreateConsumer(SessionCreateConsumerMessage packet);
-
void handleExecuteQueueQuery(SessionQueueQueryMessage packet);
void handleExecuteBindingQuery(SessionBindingQueryMessage packet);
@@ -139,10 +140,6 @@
void handleClose(Packet packet);
- void handleReplicatedDelivery(SessionReplicateDeliveryMessage packet);
-
- void handlePacketsConfirmed(PacketsConfirmedMessage packet);
-
int transferConnection(RemotingConnection newConnection, int lastReceivedCommandID);
Channel getChannel();
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/BridgeImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/BridgeImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/BridgeImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -136,8 +136,6 @@
private final String clusterPassword;
- private Channel replicatingChannel;
-
private boolean activated;
// Static --------------------------------------------------------
@@ -163,8 +161,7 @@
final SimpleString managementAddress,
final SimpleString managementNotificationAddress,
final String clusterUser,
- final String clusterPassword,
- final Channel replicatingChannel,
+ final String clusterPassword,
final boolean activated,
final StorageManager storageManager) throws Exception
{
@@ -187,7 +184,6 @@
clusterUser,
clusterPassword,
null,
- replicatingChannel,
activated,
storageManager, null);
}
@@ -211,7 +207,6 @@
final String clusterUser,
final String clusterPassword,
final MessageFlowRecord flowRecord,
- final Channel replicatingChannel,
final boolean activated,
final StorageManager storageManager,
MessagingServer server) throws Exception
@@ -263,8 +258,6 @@
this.flowRecord = flowRecord;
- this.replicatingChannel = replicatingChannel;
-
this.activated = activated;
}
@@ -325,8 +318,6 @@
public synchronized void activate()
{
- replicatingChannel = null;
-
activated = true;
executor.execute(new CreateObjectsRunnable());
@@ -390,30 +381,7 @@
if (ref != null)
{
- if (replicatingChannel == null)
- {
- // Acknowledge when we know send has been processed on the server
- ref.getQueue().acknowledge(ref);
- }
- else
- {
- Packet packet = new ReplicateAcknowledgeMessage(name, ref.getMessage().getMessageID());
-
- replicatingChannel.replicatePacket(packet, 1, new Runnable()
- {
- public void run()
- {
- try
- {
- ref.getQueue().acknowledge(ref);
- }
- catch (Exception e)
- {
- log.error("Failed to ack", e);
- }
- }
- });
- }
+ ref.getQueue().acknowledge(ref);
}
}
catch (Exception e)
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/ClusterConnectionImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/ClusterConnectionImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/ClusterConnectionImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -24,7 +24,7 @@
import static org.jboss.messaging.core.management.NotificationType.CONSUMER_CLOSED;
import static org.jboss.messaging.core.management.NotificationType.CONSUMER_CREATED;
-import static org.jboss.messaging.core.postoffice.impl.PostOfficeImpl.HDR_RESET_QUEUE_DATA;
+import static org.jboss.messaging.core.postoffice.impl.ClusterQueueStateManagerImpl.HDR_RESET_QUEUE_DATA;
import java.util.HashMap;
import java.util.HashSet;
@@ -46,13 +46,7 @@
import org.jboss.messaging.core.postoffice.Binding;
import org.jboss.messaging.core.postoffice.Bindings;
import org.jboss.messaging.core.postoffice.PostOffice;
-import org.jboss.messaging.core.remoting.Channel;
-import org.jboss.messaging.core.remoting.Packet;
-import org.jboss.messaging.core.remoting.impl.wireformat.CreateQueueMessage;
-import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRemoteBindingAddedMessage;
-import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRemoteBindingRemovedMessage;
-import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRemoteConsumerAddedMessage;
-import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRemoteConsumerRemovedMessage;
+import org.jboss.messaging.core.postoffice.impl.ClusterQueueStateManagerImpl;
import org.jboss.messaging.core.server.MessagingServer;
import org.jboss.messaging.core.server.Queue;
import org.jboss.messaging.core.server.cluster.Bridge;
@@ -106,8 +100,6 @@
private final UUID nodeUUID;
- private final Channel replicatingChannel;
-
private final List<Pair<TransportConfiguration, TransportConfiguration>> staticConnectors;
private boolean backup;
@@ -131,8 +123,7 @@
final ScheduledExecutorService scheduledExecutor,
final List<Pair<TransportConfiguration, TransportConfiguration>> connectors,
final int maxHops,
- final UUID nodeUUID,
- final Channel replicatingChannel,
+ final UUID nodeUUID,
final boolean backup) throws Exception
{
this.name = name;
@@ -166,8 +157,6 @@
this.nodeUUID = nodeUUID;
- this.replicatingChannel = replicatingChannel;
-
this.backup = backup;
this.staticConnectors = connectors;
@@ -193,8 +182,7 @@
final ScheduledExecutorService scheduledExecutor,
final DiscoveryGroup discoveryGroup,
final int maxHops,
- final UUID nodeUUID,
- final Channel replicatingChannel,
+ final UUID nodeUUID,
final boolean backup) throws Exception
{
this.name = name;
@@ -223,8 +211,6 @@
this.nodeUUID = nodeUUID;
- this.replicatingChannel = replicatingChannel;
-
this.backup = backup;
this.staticConnectors = null;
@@ -384,47 +370,9 @@
// Add binding in storage so the queue will get reloaded on startup and we can find it - it's never
// actually routed to at that address though
- if (replicatingChannel == null)
- {
- queue = server.createQueue(queueName, queueName, null, true, false);
+ queue = server.createQueue(queueName, queueName, null, true, false);
- createNewRecord(entry.getKey(), connectorPair, queueName, queue, true);
- }
- else
- {
- // We need to create the record before we replicate, since otherwise, two updates can come in for
- // the same entry before the first replication comes back, and it won't find the record, so it
- // will try and create the queue twice
- createNewRecord(entry.getKey(), connectorPair, queueName, null, false);
-
- // Replicate the createQueue first
- Packet packet = new CreateQueueMessage(queueName, queueName, null, true, false);
-
- replicatingChannel.replicatePacket(packet, 1, new Runnable()
- {
- public void run()
- {
- try
- {
- Queue queue = server.createQueue(queueName, queueName, null, true, false);
-
- synchronized (ClusterConnectionImpl.this)
- {
- MessageFlowRecord record = records.get(entry.getKey());
-
- if (record != null)
- {
- record.activate(queue);
- }
- }
- }
- catch (Exception e)
- {
- log.error("Failed create record", e);
- }
- }
- });
- }
+ createNewRecord(entry.getKey(), connectorPair, queueName, queue, true);
}
}
}
@@ -456,8 +404,7 @@
managementService.getManagementNotificationAddress(),
managementService.getClusterUser(),
managementService.getClusterPassword(),
- record,
- replicatingChannel,
+ record,
!backup,
server.getStorageManager(),
server);
@@ -600,7 +547,7 @@
{
case BINDING_ADDED:
{
- doBindingAdded(message, replicatingChannel);
+ doBindingAdded(message);
break;
}
@@ -612,13 +559,13 @@
}
case CONSUMER_CREATED:
{
- doConsumerCreated(message, replicatingChannel);
+ doConsumerCreated(message);
break;
}
case CONSUMER_CLOSED:
{
- doConsumerClosed(message, replicatingChannel);
+ doConsumerClosed(message);
break;
}
@@ -641,11 +588,11 @@
{
for (RemoteQueueBinding binding : new HashSet<RemoteQueueBinding>(bindings.values()))
{
- removeBinding(binding.getClusterName(), replicatingChannel);
+ removeBinding(binding.getClusterName());
}
}
- private synchronized void doBindingAdded(final ClientMessage message, final Channel replChannel) throws Exception
+ private synchronized void doBindingAdded(final ClientMessage message) throws Exception
{
Integer distance = (Integer)message.getProperty(ManagementHelper.HDR_DISTANCE);
@@ -684,38 +631,7 @@
throw new IllegalStateException("queueID is null");
}
- if (replChannel != null)
- {
- Packet packet = new ReplicateRemoteBindingAddedMessage(name,
- queueAddress,
- clusterName,
- routingName,
- queueID,
- filterString,
- queue.getName(),
- distance + 1);
-
- beforeReplicate();
- replChannel.replicatePacket(packet, 1, new Runnable()
- {
- public void run()
- {
- try
- {
- doBindingAdded(message, null);
- }
- catch (Exception e)
- {
- log.error("Failed to add remote queue binding", e);
- }
-
- replicationComplete();
- }
- });
- }
- else
- {
- RemoteQueueBinding binding = new RemoteQueueBindingImpl(queueAddress,
+ RemoteQueueBinding binding = new RemoteQueueBindingImpl(queueAddress,
clusterName,
routingName,
queueID,
@@ -724,33 +640,33 @@
bridge.getName(),
distance + 1);
- bindings.put(clusterName, binding);
+ bindings.put(clusterName, binding);
- if (postOffice.getBinding(clusterName) != null)
- {
- // Sanity check - this means the binding has already been added via another bridge, probably max
- // hops is too high
- // or there are multiple cluster connections for the same address
+ if (postOffice.getBinding(clusterName) != null)
+ {
+ // Sanity check - this means the binding has already been added via another bridge, probably max
+ // hops is too high
+ // or there are multiple cluster connections for the same address
- log.warn("Remote queue binding " + clusterName +
- " has already been bound in the post office. Most likely cause for this is you have a loop " +
- "in your cluster due to cluster max-hops being too large or you have multiple cluster connections to the same nodes using overlapping addresses");
+ log.warn("Remote queue binding " + clusterName +
+ " has already been bound in the post office. Most likely cause for this is you have a loop " +
+ "in your cluster due to cluster max-hops being too large or you have multiple cluster connections to the same nodes using overlapping addresses");
- return;
- }
+ return;
+ }
- try
- {
- postOffice.addBinding(binding);
- }
- catch (Exception ignore)
- {
- }
+ try
+ {
+ postOffice.addBinding(binding);
+ }
+ catch (Exception ignore)
+ {
+ }
- Bindings theBindings = postOffice.getBindingsForAddress(queueAddress);
+ Bindings theBindings = postOffice.getBindingsForAddress(queueAddress);
- theBindings.setRouteWhenNoConsumers(routeWhenNoConsumers);
- }
+ theBindings.setRouteWhenNoConsumers(routeWhenNoConsumers);
+
}
private void doBindingRemoved(final ClientMessage message) throws Exception
@@ -762,47 +678,22 @@
throw new IllegalStateException("clusterName is null");
}
- removeBinding(clusterName, replicatingChannel);
+ removeBinding(clusterName);
}
- private synchronized void removeBinding(final SimpleString clusterName, final Channel replChannel) throws Exception
+ private synchronized void removeBinding(final SimpleString clusterName) throws Exception
{
- if (replChannel != null)
- {
- Packet packet = new ReplicateRemoteBindingRemovedMessage(clusterName);
+ RemoteQueueBinding binding = bindings.remove(clusterName);
- beforeReplicate();
- replChannel.replicatePacket(packet, 1, new Runnable()
- {
- public void run()
- {
- try
- {
- removeBinding(clusterName, null);
- }
- catch (Exception e)
- {
- log.error("Failed to remove remote queue binding", e);
- }
-
- replicationComplete();
- }
- });
- }
- else
+ if (binding == null)
{
- RemoteQueueBinding binding = bindings.remove(clusterName);
-
- if (binding == null)
- {
- throw new IllegalStateException("Cannot find binding for queue " + clusterName);
- }
-
- postOffice.removeBinding(binding.getUniqueName());
+ throw new IllegalStateException("Cannot find binding for queue " + clusterName);
}
+
+ postOffice.removeBinding(binding.getUniqueName());
}
- private synchronized void doConsumerCreated(final ClientMessage message, final Channel replChannel) throws Exception
+ private synchronized void doConsumerCreated(final ClientMessage message) throws Exception
{
Integer distance = (Integer)message.getProperty(ManagementHelper.HDR_DISTANCE);
@@ -822,47 +713,22 @@
SimpleString filterString = (SimpleString)message.getProperty(ManagementHelper.HDR_FILTERSTRING);
- if (replChannel != null)
- {
- Packet packet = new ReplicateRemoteConsumerAddedMessage(clusterName, filterString, message.getProperties());
+ RemoteQueueBinding binding = bindings.get(clusterName);
- beforeReplicate();
- replChannel.replicatePacket(packet, 1, new Runnable()
- {
- public void run()
- {
- try
- {
- doConsumerCreated(message, null);
- }
- catch (Exception e)
- {
- log.error("Failed to add remote consumer", e);
- }
-
- replicationComplete();
- }
- });
- }
- else
+ if (binding == null)
{
- RemoteQueueBinding binding = bindings.get(clusterName);
+ throw new IllegalStateException("Cannot find binding for " + clusterName);
+ }
- if (binding == null)
- {
- throw new IllegalStateException("Cannot find binding for " + clusterName);
- }
+ binding.addConsumer(filterString);
- binding.addConsumer(filterString);
+ // Need to propagate the consumer add
+ Notification notification = new Notification(null, CONSUMER_CREATED, message.getProperties());
- // Need to propagate the consumer add
- Notification notification = new Notification(null, CONSUMER_CREATED, message.getProperties());
-
- managementService.sendNotification(notification);
- }
+ managementService.sendNotification(notification);
}
- private synchronized void doConsumerClosed(final ClientMessage message, final Channel replChannel) throws Exception
+ private synchronized void doConsumerClosed(final ClientMessage message) throws Exception
{
Integer distance = (Integer)message.getProperty(ManagementHelper.HDR_DISTANCE);
@@ -882,46 +748,19 @@
SimpleString filterString = (SimpleString)message.getProperty(ManagementHelper.HDR_FILTERSTRING);
- if (replChannel != null)
- {
- Packet packet = new ReplicateRemoteConsumerRemovedMessage(clusterName,
- filterString,
- message.getProperties());
+ RemoteQueueBinding binding = bindings.get(clusterName);
- beforeReplicate();
- replChannel.replicatePacket(packet, 1, new Runnable()
- {
- public void run()
- {
- try
- {
- doConsumerClosed(message, null);
- }
- catch (Exception e)
- {
- log.error("Failed to remove remote consumer", e);
- }
-
- replicationComplete();
- }
- });
- }
- else
+ if (binding == null)
{
- RemoteQueueBinding binding = bindings.get(clusterName);
+ throw new IllegalStateException("Cannot find binding for " + clusterName);
+ }
- if (binding == null)
- {
- throw new IllegalStateException("Cannot find binding for " + clusterName);
- }
+ binding.removeConsumer(filterString);
- binding.removeConsumer(filterString);
+ // Need to propagate the consumer close
+ Notification notification = new Notification(null, CONSUMER_CLOSED, message.getProperties());
- // Need to propagate the consumer close
- Notification notification = new Notification(null, CONSUMER_CLOSED, message.getProperties());
-
- managementService.sendNotification(notification);
- }
+ managementService.sendNotification(notification);
}
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/ClusterManagerImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/ClusterManagerImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/ClusterManagerImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -46,7 +46,6 @@
import org.jboss.messaging.core.management.ManagementService;
import org.jboss.messaging.core.postoffice.Binding;
import org.jboss.messaging.core.postoffice.PostOffice;
-import org.jboss.messaging.core.remoting.Channel;
import org.jboss.messaging.core.server.MessagingServer;
import org.jboss.messaging.core.server.Queue;
import org.jboss.messaging.core.server.cluster.Bridge;
@@ -93,8 +92,6 @@
private final UUID nodeUUID;
- private Channel replicatingChannel;
-
private volatile boolean started;
private boolean backup;
@@ -105,8 +102,7 @@
final ScheduledExecutorService scheduledExecutor,
final ManagementService managementService,
final Configuration configuration,
- final UUID nodeUUID,
- final Channel replicatingChannel,
+ final UUID nodeUUID,
final boolean backup)
{
if (nodeUUID == null)
@@ -128,8 +124,6 @@
this.nodeUUID = nodeUUID;
- this.replicatingChannel = replicatingChannel;
-
this.backup = backup;
}
@@ -244,9 +238,7 @@
{
cc.activate();
}
-
- replicatingChannel = null;
-
+
backup = false;
}
@@ -444,8 +436,7 @@
managementService.getManagementAddress(),
managementService.getManagementNotificationAddress(),
managementService.getClusterUser(),
- managementService.getClusterPassword(),
- replicatingChannel,
+ managementService.getClusterPassword(),
!backup,
server.getStorageManager());
@@ -524,8 +515,7 @@
scheduledExecutor,
connectors,
config.getMaxHops(),
- nodeUUID,
- replicatingChannel,
+ nodeUUID,
backup);
}
else
@@ -550,8 +540,7 @@
scheduledExecutor,
dg,
config.getMaxHops(),
- nodeUUID,
- replicatingChannel,
+ nodeUUID,
backup);
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/Redistributor.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/Redistributor.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/cluster/impl/Redistributor.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -29,8 +29,6 @@
import org.jboss.messaging.core.persistence.StorageManager;
import org.jboss.messaging.core.postoffice.PostOffice;
import org.jboss.messaging.core.remoting.Channel;
-import org.jboss.messaging.core.remoting.Packet;
-import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRedistributionMessage;
import org.jboss.messaging.core.server.Consumer;
import org.jboss.messaging.core.server.HandleStatus;
import org.jboss.messaging.core.server.MessageReference;
@@ -66,14 +64,11 @@
private int count;
- private final Channel replicatingChannel;
-
public Redistributor(final Queue queue,
final StorageManager storageManager,
final PostOffice postOffice,
final Executor executor,
- final int batchSize,
- final Channel replicatingChannel)
+ final int batchSize)
{
this.queue = queue;
@@ -84,8 +79,6 @@
this.executor = executor;
this.batchSize = batchSize;
-
- this.replicatingChannel = replicatingChannel;
}
public Filter getFilter()
@@ -143,30 +136,8 @@
if (routed)
{
- if (replicatingChannel == null)
- {
- doRedistribute(reference, tx);
- }
- else
- {
- Packet packet = new ReplicateRedistributionMessage(queue.getName(), reference.getMessage().getMessageID());
-
- replicatingChannel.replicatePacket(packet, 1, new Runnable()
- {
- public void run()
- {
- try
- {
- doRedistribute(reference, tx);
- }
- catch (Exception e)
- {
- log.error("Failed to handle redistribution", e);
- }
- }
- });
- }
-
+ doRedistribute(reference, tx);
+
return HandleStatus.HANDLED;
}
else
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/LastValueQueue.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/LastValueQueue.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/LastValueQueue.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -60,18 +60,18 @@
private final StorageManager storageManager;
- public LastValueQueue(final long persistenceID,
- final SimpleString address,
- final SimpleString name,
- final Filter filter,
- final boolean durable,
- final boolean temporary,
- final ScheduledExecutorService scheduledExecutor,
- final PostOffice postOffice,
- final StorageManager storageManager,
- final HierarchicalRepository<AddressSettings> addressSettingsRepository)
+ public LastValueQueue(final long id,
+ final SimpleString address,
+ final SimpleString name,
+ final Filter filter,
+ final boolean durable,
+ final boolean temporary,
+ final ScheduledExecutorService scheduledExecutor,
+ final PostOffice postOffice,
+ final StorageManager storageManager,
+ final HierarchicalRepository<AddressSettings> addressSettingsRepository)
{
- super(persistenceID,
+ super(id,
address,
name,
filter,
@@ -182,7 +182,7 @@
}
}
- void postRollback(final LinkedList<MessageReference> refs) throws Exception
+ protected void postRollback(final LinkedList<MessageReference> refs) throws Exception
{
List<MessageReference> refsToDiscard = new ArrayList<MessageReference>();
List<SimpleString> refsToClear = new ArrayList<SimpleString>();
@@ -220,7 +220,7 @@
super.postRollback(refs);
}
- final void discardMessage(MessageReference ref, Transaction tx) throws Exception
+ private final void discardMessage(MessageReference ref, Transaction tx) throws Exception
{
deliveringCount.decrementAndGet();
PagingStore store = pagingManager.getPageStore(ref.getMessage().getDestination());
@@ -241,13 +241,13 @@
}
else
{
- storageManager.deleteMessageTransactional(tx.getID(), getPersistenceID(), msg.getMessageID());
+ storageManager.deleteMessageTransactional(tx.getID(), getID(), msg.getMessageID());
}
}
}
}
- final void discardMessage(Long id, Transaction tx) throws Exception
+ private final void discardMessage(long id, Transaction tx) throws Exception
{
RefsOperation oper = getRefsOperation(tx);
Iterator<MessageReference> iterator = oper.refsToAdd.iterator();
@@ -266,7 +266,7 @@
}
- final void rediscardMessage(long id, Transaction tx) throws Exception
+ private final void rediscardMessage(long id, Transaction tx) throws Exception
{
RefsOperation oper = getRefsOperation(tx);
Iterator<MessageReference> iterator = oper.refsToAdd.iterator();
@@ -284,7 +284,7 @@
}
}
- final void rediscardMessage(MessageReference ref) throws Exception
+ private final void rediscardMessage(final MessageReference ref) throws Exception
{
deliveringCount.decrementAndGet();
PagingStore store = pagingManager.getPageStore(ref.getMessage().getDestination());
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/MessagingServerImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/MessagingServerImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/MessagingServerImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -32,8 +32,6 @@
import javax.management.MBeanServer;
import org.jboss.messaging.core.client.impl.ClientSessionFactoryImpl;
-import org.jboss.messaging.core.client.impl.ConnectionManager;
-import org.jboss.messaging.core.client.impl.ConnectionManagerImpl;
import org.jboss.messaging.core.config.Configuration;
import org.jboss.messaging.core.config.TransportConfiguration;
import org.jboss.messaging.core.config.cluster.DivertConfiguration;
@@ -61,20 +59,27 @@
import org.jboss.messaging.core.persistence.impl.journal.JournalStorageManager;
import org.jboss.messaging.core.persistence.impl.nullpm.NullStorageManager;
import org.jboss.messaging.core.postoffice.Binding;
+import org.jboss.messaging.core.postoffice.ClusterQueueStateManager;
import org.jboss.messaging.core.postoffice.DuplicateIDCache;
import org.jboss.messaging.core.postoffice.PostOffice;
+import org.jboss.messaging.core.postoffice.impl.ClusterQueueStateManagerImpl;
import org.jboss.messaging.core.postoffice.impl.DivertBinding;
import org.jboss.messaging.core.postoffice.impl.LocalQueueBinding;
import org.jboss.messaging.core.postoffice.impl.PostOfficeImpl;
import org.jboss.messaging.core.remoting.Channel;
-import org.jboss.messaging.core.remoting.FailureListener;
+import org.jboss.messaging.core.remoting.ChannelHandler;
import org.jboss.messaging.core.remoting.Packet;
import org.jboss.messaging.core.remoting.RemotingConnection;
+import org.jboss.messaging.core.remoting.impl.RemotingConnectionImpl;
import org.jboss.messaging.core.remoting.impl.wireformat.CreateSessionResponseMessage;
+import org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl;
import org.jboss.messaging.core.remoting.impl.wireformat.ReattachSessionResponseMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateStartupInfoMessage;
import org.jboss.messaging.core.remoting.server.RemotingService;
import org.jboss.messaging.core.remoting.server.impl.RemotingServiceImpl;
+import org.jboss.messaging.core.remoting.spi.Connection;
+import org.jboss.messaging.core.remoting.spi.ConnectionLifeCycleListener;
+import org.jboss.messaging.core.remoting.spi.ConnectorFactory;
import org.jboss.messaging.core.security.CheckType;
import org.jboss.messaging.core.security.JBMSecurityManager;
import org.jboss.messaging.core.security.Role;
@@ -90,6 +95,9 @@
import org.jboss.messaging.core.server.cluster.ClusterManager;
import org.jboss.messaging.core.server.cluster.Transformer;
import org.jboss.messaging.core.server.cluster.impl.ClusterManagerImpl;
+import org.jboss.messaging.core.server.replication.Replicator;
+import org.jboss.messaging.core.server.replication.impl.JBMThread;
+import org.jboss.messaging.core.server.replication.impl.ReplicatorImpl;
import org.jboss.messaging.core.settings.HierarchicalRepository;
import org.jboss.messaging.core.settings.impl.AddressSettings;
import org.jboss.messaging.core.settings.impl.HierarchicalObjectRepository;
@@ -186,20 +194,13 @@
private final Map<String, ServerSession> sessions = new ConcurrentHashMap<String, ServerSession>();
- private RemotingConnection replicatingConnection;
-
- private Channel replicatingChannel;
-
private final Object initialiseLock = new Object();
private boolean initialised;
-
- private ConnectionManager replicatingConnectionManager;
private int managementConnectorID;
-
+
private static AtomicInteger managementConnectorSequence = new AtomicInteger(0);
-
// Constructors
// ---------------------------------------------------------------------------------
@@ -223,7 +224,7 @@
{
this(configuration, null, securityManager);
}
-
+
public MessagingServerImpl(Configuration configuration,
MBeanServer mbeanServer,
final JBMSecurityManager securityManager)
@@ -252,10 +253,10 @@
this.addressSettingsRepository = new HierarchicalObjectRepository<AddressSettings>();
addressSettingsRepository.setDefault(new AddressSettings());
-
+
this.managementConnectorID = managementConnectorSequence.decrementAndGet();
}
-
+
// lifecycle methods
// ----------------------------------------------------------------
@@ -286,7 +287,7 @@
}
public synchronized void stop() throws Exception
- {
+ {
if (!started)
{
return;
@@ -335,23 +336,10 @@
securityManager.stop();
}
- if (replicatingConnection != null)
- {
- try
- {
- replicatingConnection.destroy();
- }
- catch (Exception ignore)
- {
- }
+ resourceManager.stop();
- replicatingConnection = null;
- replicatingChannel = null;
-
- replicatingConnectionManager.close();
- }
+ clusterQueueStateManager.stop();
- resourceManager.stop();
postOffice.stop();
// Need to shutdown pools before shutting down paging manager to make sure everything is written ok
@@ -492,39 +480,8 @@
}
}
- public void replicateCreateSession(final String name,
- final long replicatedChannelID,
- final long originalChannelID,
- final String username,
- final String password,
- final int minLargeMessageSize,
- final int incrementingVersion,
- final RemotingConnection connection,
- final boolean autoCommitSends,
- final boolean autoCommitAcks,
- final boolean preAcknowledge,
- final boolean xa,
- final int producerWindowSize) throws Exception
- {
- doCreateSession(name,
- replicatedChannelID,
- originalChannelID,
- username,
- password,
- minLargeMessageSize,
- incrementingVersion,
- connection,
- autoCommitSends,
- autoCommitAcks,
- preAcknowledge,
- xa,
- producerWindowSize,
- true);
- }
-
public CreateSessionResponseMessage createSession(final String name,
final long channelID,
- final long replicatedChannelID,
final String username,
final String password,
final int minLargeMessageSize,
@@ -534,13 +491,16 @@
final boolean autoCommitAcks,
final boolean preAcknowledge,
final boolean xa,
- final int sendWindowSize) throws Exception
+ final int sendWindowSize,
+ final boolean direct) throws Exception
{
- checkActivate(connection);
-
+ if (direct)
+ {
+ checkActivate(connection);
+ }
+
return doCreateSession(name,
channelID,
- replicatedChannelID,
username,
password,
minLargeMessageSize,
@@ -598,7 +558,7 @@
{
throw new IllegalArgumentException("node id is null");
}
-
+
synchronized (initialiseLock)
{
if (initialised)
@@ -618,9 +578,12 @@
{
initialised = false;
- throw new IllegalStateException("Live and backup unique ids different (" + liveUniqueID + ":" + backupID + "). You're probably trying to restart a live backup pair after a crash");
+ throw new IllegalStateException("Live and backup unique ids different (" + liveUniqueID +
+ ":" +
+ backupID +
+ "). You're probably trying to restart a live backup pair after a crash");
}
-
+
log.info("Backup server is now operational");
}
}
@@ -730,7 +693,7 @@
if (queue.isDurable())
{
- storageManager.deleteQueueBinding(queue.getPersistenceID());
+ storageManager.deleteQueueBinding(queue.getID());
}
postOffice.removeBinding(queueName);
@@ -746,6 +709,148 @@
activateCallbacks.remove(callback);
}
+ private ConnectorFactory backupConnectorFactory;
+
+ private Map<String, Object> backupConnectorParams;
+
+ private void setupBackupConnectorFactory()
+ {
+ String backupConnectorName = configuration.getBackupConnectorName();
+
+ if (backupConnectorName != null)
+ {
+ TransportConfiguration backupConnector = configuration.getConnectorConfigurations().get(backupConnectorName);
+
+ if (backupConnector == null)
+ {
+ log.warn("connector with name '" + backupConnectorName + "' is not defined in the configuration.");
+ }
+ else
+ {
+
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ Class<?> clz = loader.loadClass(backupConnector.getFactoryClassName());
+ backupConnectorFactory = (ConnectorFactory)clz.newInstance();
+ }
+ catch (Exception e)
+ {
+ throw new IllegalArgumentException("Error instantiating interceptor \"" + backupConnector.getFactoryClassName() +
+ "\"",
+ e);
+ }
+
+ backupConnectorParams = backupConnector.getParams();
+ }
+ }
+ }
+
+ private boolean activatedBackup;
+
+ public synchronized RemotingConnection getReplicatingConnection()
+ {
+ // Note we must always get a new connection each time - since there must
+ // be a one to one correspondence
+ // between connections to clients and replicating connections, since we
+ // need to preserve channel ids
+ // before and after failover
+
+ if (backupConnectorFactory != null)
+ {
+ NoCacheConnectionLifeCycleListener listener = new NoCacheConnectionLifeCycleListener();
+
+ RemotingConnectionImpl replicatingConnection = (RemotingConnectionImpl)RemotingConnectionImpl.createConnection(backupConnectorFactory,
+ backupConnectorParams,
+ ClientSessionFactoryImpl.DEFAULT_CALL_TIMEOUT,
+ threadPool,
+ listener);
+
+ listener.conn = replicatingConnection;
+
+ if (!activatedBackup)
+ {
+ // First time we get channel we send a message down it informing the backup of our node id -
+ // backup and live must have the same node id
+
+ Packet packet = new ReplicateStartupInfoMessage(uuid, storageManager.getCurrentUniqueID());
+
+ Channel channel1 = replicatingConnection.getChannel(1, -1, false);
+
+ ChannelHandler prevHandler = channel1.getHandler();
+
+ log.info("Prev handler is " + prevHandler);
+
+ final Future future = new Future();
+
+ channel1.setHandler(new ChannelHandler()
+ {
+ public void handlePacket(final Packet packet)
+ {
+ if (packet.getType() == PacketImpl.REPLICATION_RESPONSE)
+ {
+ log.info("&&&&&&&&&&&&&&&& got replication response");
+ future.run();
+ }
+ else
+ {
+ throw new IllegalArgumentException("Invalid packet " + packet.getType());
+ }
+ }
+ });
+
+ channel1.send(packet);
+
+ boolean ok = future.await(10000);
+
+ if (!ok)
+ {
+ throw new IllegalStateException("Timed out waiting for response from backup for initialisation");
+ }
+
+ log.info("got response");
+
+ channel1.setHandler(prevHandler);
+
+ activatedBackup = true;
+ }
+
+ // TODO - pinging + execute outstanding results on channels when failure occurs!!!
+
+ return replicatingConnection;
+ }
+ else
+ {
+ return null;
+ }
+
+ }
+
+ private static class NoCacheConnectionLifeCycleListener implements ConnectionLifeCycleListener
+ {
+ private RemotingConnection conn;
+
+ public void connectionCreated(final Connection connection)
+ {
+ }
+
+ public void connectionDestroyed(final Object connectionID)
+ {
+ if (conn != null)
+ {
+ conn.destroy();
+ }
+ }
+
+ public void connectionException(final Object connectionID, final MessagingException me)
+ {
+ if (conn != null)
+ {
+ conn.fail(me);
+ }
+ }
+ }
+
// Public
// ---------------------------------------------------------------------------------------
@@ -782,7 +887,7 @@
if (configuration.isBackup())
{
log.info("A connection has been made to the backup server so it will be activated! This will result in the live server being considered failed.");
-
+
synchronized (this)
{
freezeBackupConnection();
@@ -802,7 +907,7 @@
{
clusterManager.activate();
}
-
+
if (configuration.isFileDeploymentEnabled())
{
queueDeployer = new QueueDeployer(deploymentManager, messagingServerControl);
@@ -854,7 +959,7 @@
{
// Create the pools - we have two pools - one for non scheduled - and another for scheduled
- ThreadFactory tFactory = new JBMThreadFactory("JBM-server-threads" + System.identityHashCode(this), false);
+ ThreadFactory tFactory = new JBMThreadThreadFactory("JBM-server-threads" + System.identityHashCode(this), false);
if (configuration.getThreadPoolMaxSize() == -1)
{
@@ -867,15 +972,24 @@
executorFactory = new OrderedExecutorFactory(threadPool);
- scheduledPool = new ScheduledThreadPoolExecutor(configuration.getScheduledThreadPoolMaxSize(),
- new org.jboss.messaging.utils.JBMThreadFactory("JBM-scheduled-threads",
- false));
+ ThreadFactory scheduledTFactory = new JBMThreadThreadFactory("JBM-scheduled-threads", false);
+ scheduledPool = new ScheduledThreadPoolExecutor(configuration.getScheduledThreadPoolMaxSize(), scheduledTFactory);
+
managementService = new ManagementServiceImpl(mbeanServer, configuration, managementConnectorID);
-
- remotingService = new RemotingServiceImpl(configuration, this, managementService, threadPool, scheduledPool, managementConnectorID);
+
+ remotingService = new RemotingServiceImpl(configuration,
+ this,
+ managementService,
+ threadPool,
+ scheduledPool,
+ managementConnectorID);
+
+ setupBackupConnectorFactory();
}
-
+
+ private ClusterQueueStateManager clusterQueueStateManager;
+
private void initialisePart2() throws Exception
{
// Create the hard-wired components
@@ -891,7 +1005,7 @@
}
else
{
- storageManager = new NullStorageManager();
+ storageManager = new NullStorageManager(configuration.isBackup());
}
securityRepository = new HierarchicalObjectRepository<Set<Role>>();
@@ -911,8 +1025,7 @@
resourceManager = new ResourceManagerImpl((int)(configuration.getTransactionTimeout() / 1000),
configuration.getTransactionTimeoutScanPeriod());
- postOffice = new PostOfficeImpl(this,
- storageManager,
+ postOffice = new PostOfficeImpl(storageManager,
pagingManager,
queueFactory,
managementService,
@@ -921,10 +1034,14 @@
configuration.isWildcardRoutingEnabled(),
configuration.isBackup(),
configuration.getIDCacheSize(),
- configuration.isPersistIDCache(),
- executorFactory,
- addressSettingsRepository);
+ configuration.isPersistIDCache());
+ clusterQueueStateManager = new ClusterQueueStateManagerImpl(executorFactory,
+ addressSettingsRepository,
+ postOffice,
+ storageManager,
+ managementService);
+
messagingServerControl = managementService.registerServer(postOffice,
storageManager,
configuration,
@@ -934,9 +1051,10 @@
remotingService,
this,
queueFactory,
+ clusterQueueStateManager,
configuration.isBackup());
- // Address settings need to deployed initially, since they're require on paging manager.start()
+ // Address settings need to deployed initially, since they're required on paging manager.start()
if (configuration.isFileDeploymentEnabled())
{
@@ -954,6 +1072,11 @@
postOffice.start();
+ if (clusterQueueStateManager != null)
+ {
+ clusterQueueStateManager.start();
+ }
+
pagingManager.start();
managementService.start();
@@ -983,8 +1106,9 @@
deployQueuesFromConfiguration();
// Deploy any predefined queues
-
- // We don't activate queue deployer on the backup - all queues deployed on live are deployed on backup by replicating them
+
+ // We don't activate queue deployer on the backup - all queues deployed on live are deployed on backup by
+ // replicating them
if (configuration.isFileDeploymentEnabled() && !configuration.isBackup())
{
queueDeployer = new QueueDeployer(deploymentManager, messagingServerControl);
@@ -999,11 +1123,11 @@
// Deply any pre-defined diverts
deployDiverts();
- // Set-up the replicating connection
- if (!setupReplicatingConnection())
- {
- return;
- }
+ // // Set-up the replicating connection
+ // if (!setupReplicatingConnection())
+ // {
+ // return;
+ // }
if (configuration.isClustered())
{
@@ -1015,7 +1139,6 @@
managementService,
configuration,
uuid,
- replicatingChannel,
configuration.isBackup());
clusterManager.start();
@@ -1044,90 +1167,90 @@
}
}
- public Channel getReplicatingChannel()
- {
- return replicatingChannel;
- }
+ // public RemotingConnection getReplicatingConnection()
+ // {
+ //
+ // }
- private boolean setupReplicatingConnection() throws Exception
- {
- String backupConnectorName = configuration.getBackupConnectorName();
+ // private boolean setupReplicatingConnection() throws Exception
+ // {
+ // String backupConnectorName = configuration.getBackupConnectorName();
+ //
+ // if (backupConnectorName != null)
+ // {
+ // TransportConfiguration backupConnector = configuration.getConnectorConfigurations().get(backupConnectorName);
+ //
+ // if (backupConnector == null)
+ // {
+ // log.warn("connector with name '" + backupConnectorName + "' is not defined in the configuration.");
+ // }
+ // else
+ // {
+ // replicatingConnectionManager = new ConnectionManagerImpl(null,
+ // backupConnector,
+ // null,
+ // false,
+ // 1,
+ // ClientSessionFactoryImpl.DEFAULT_CALL_TIMEOUT,
+ // ClientSessionFactoryImpl.DEFAULT_CLIENT_FAILURE_CHECK_PERIOD,
+ // ClientSessionFactoryImpl.DEFAULT_CONNECTION_TTL,
+ // 0,
+ // 1.0d,
+ // 0,
+ // threadPool,
+ // scheduledPool);
+ //
+ // replicatingConnection = replicatingConnectionManager.getConnection(1);
+ //
+ // if (replicatingConnection != null)
+ // {
+ // replicatingChannel = replicatingConnection.getChannel(2, -1, false);
+ //
+ // replicatingConnection.addFailureListener(new FailureListener()
+ // {
+ // public boolean connectionFailed(MessagingException me)
+ // {
+ // replicatingChannel.executeOutstandingDelayedResults();
+ //
+ // return true;
+ // }
+ // });
+ //
+ // // First time we get channel we send a message down it informing the backup of our node id -
+ // // backup and live must have the same node id
+ //
+ // Packet packet = new ReplicateStartupInfoMessage(uuid, storageManager.getCurrentUniqueID());
+ //
+ // final Future future = new Future();
+ //
+ // replicatingChannel.replicatePacket(packet, 1, new Runnable()
+ // {
+ // public void run()
+ // {
+ // future.run();
+ // }
+ // });
+ //
+ // //This may take a while especially if the journal is large
+ // boolean ok = future.await(60000);
+ //
+ // if (!ok)
+ // {
+ // throw new IllegalStateException("Timed out waiting for response from backup for initialisation");
+ // }
+ // }
+ // else
+ // {
+ // log.warn("Backup server MUST be started before live server. Initialisation will not proceed.");
+ //
+ // return false;
+ // }
+ // }
+ // }
+ //
+ // return true;
+ // }
- if (backupConnectorName != null)
- {
- TransportConfiguration backupConnector = configuration.getConnectorConfigurations().get(backupConnectorName);
-
- if (backupConnector == null)
- {
- log.warn("connector with name '" + backupConnectorName + "' is not defined in the configuration.");
- }
- else
- {
- replicatingConnectionManager = new ConnectionManagerImpl(null,
- backupConnector,
- null,
- false,
- 1,
- ClientSessionFactoryImpl.DEFAULT_CALL_TIMEOUT,
- ClientSessionFactoryImpl.DEFAULT_CLIENT_FAILURE_CHECK_PERIOD,
- ClientSessionFactoryImpl.DEFAULT_CONNECTION_TTL,
- 0,
- 1.0d,
- 0,
- threadPool,
- scheduledPool);
-
- replicatingConnection = replicatingConnectionManager.getConnection(1);
-
- if (replicatingConnection != null)
- {
- replicatingChannel = replicatingConnection.getChannel(2, -1, false);
-
- replicatingConnection.addFailureListener(new FailureListener()
- {
- public boolean connectionFailed(MessagingException me)
- {
- replicatingChannel.executeOutstandingDelayedResults();
-
- return true;
- }
- });
-
- // First time we get channel we send a message down it informing the backup of our node id -
- // backup and live must have the same node id
-
- Packet packet = new ReplicateStartupInfoMessage(uuid, storageManager.getCurrentUniqueID());
-
- final Future future = new Future();
-
- replicatingChannel.replicatePacket(packet, 1, new Runnable()
- {
- public void run()
- {
- future.run();
- }
- });
-
- //This may take a while especially if the journal is large
- boolean ok = future.await(60000);
-
- if (!ok)
- {
- throw new IllegalStateException("Timed out waiting for response from backup for initialisation");
- }
- }
- else
- {
- log.warn("Backup server MUST be started before live server. Initialisation will not proceed.");
-
- return false;
- }
- }
- }
-
- return true;
- }
-
private void loadJournal() throws Exception
{
List<QueueBindingInfo> queueBindingInfos = new ArrayList<QueueBindingInfo>();
@@ -1180,15 +1303,15 @@
}
private void setNodeID() throws Exception
- {
+ {
if (!configuration.isBackup())
- {
+ {
if (uuid == null)
- {
+ {
uuid = storageManager.getPersistentID();
-
+
if (uuid == null)
- {
+ {
uuid = UUIDGenerator.getInstance().generateUUID();
storageManager.setPersistentID(uuid);
@@ -1198,9 +1321,9 @@
}
}
else
- {
+ {
UUID currentUUID = storageManager.getPersistentID();
-
+
if (currentUUID != null)
{
if (!currentUUID.equals(uuid))
@@ -1222,6 +1345,7 @@
final boolean temporary,
final boolean ignoreIfExists) throws Exception
{
+ log.info("** creating queue " + queueName);
Binding binding = postOffice.getBinding(queueName);
if (binding != null)
@@ -1243,7 +1367,7 @@
filter = new FilterImpl(filterString);
}
- final Queue queue = queueFactory.createQueue(-1, address, queueName, filter, durable, temporary);
+ final Queue queue = queueFactory.createQueue(storageManager.generateUniqueID(), address, queueName, filter, durable, temporary);
binding = new LocalQueueBinding(address, queue, nodeID);
@@ -1322,7 +1446,6 @@
private CreateSessionResponseMessage doCreateSession(final String name,
final long channelID,
- final long oppositeChannelID,
final String username,
final String password,
final int minLargeMessageSize,
@@ -1364,11 +1487,42 @@
}
Channel channel = connection.getChannel(channelID, sendWindowSize, false);
+
+ RemotingConnection replicatingConnection = connection.getReplicatingConnection();
+
+ log.info("getting repl conenction from " + System.identityHashCode(connection) + " it is " + replicatingConnection);
- Channel replicatingChannel = getReplicatingChannel();
+ log.info("Creating session, replicating connection is " + replicatingConnection);
+ final Replicator replicator;
+
+ if (replicatingConnection != null)
+ {
+ Channel replicatingChannel = replicatingConnection.getChannel(channelID, -1, false);
+
+ replicator = new ReplicatorImpl(replicatingChannel);
+
+ replicatingChannel.setHandler(new ChannelHandler()
+ {
+ public void handlePacket(final Packet packet)
+ {
+ if (packet.getType() == PacketImpl.REPLICATION_RESPONSE)
+ {
+ replicator.replicationResponseReceived();
+ }
+ else
+ {
+ throw new IllegalArgumentException("Invalid packet " + packet.getType());
+ }
+ }
+ });
+ }
+ else
+ {
+ replicator = null;
+ }
+
final ServerSessionImpl session = new ServerSessionImpl(name,
- oppositeChannelID,
username,
password,
minLargeMessageSize,
@@ -1387,14 +1541,14 @@
managementService,
queueFactory,
this,
- configuration.getManagementAddress(),
- replicatingChannel,
- backup);
+ configuration.getManagementAddress());
sessions.put(name, session);
+
+ ServerSessionPacketHandler handler = new ServerSessionPacketHandler(session, replicator, configuration);
- ServerSessionPacketHandler handler = new ServerSessionPacketHandler(session);
-
+ log.info(System.identityHashCode(handler)+ " ** creating serversessionpackethandler on backup "+ configuration.isBackup() + " replicator is " + replicator);
+
session.setHandler(handler);
channel.setHandler(handler);
@@ -1441,4 +1595,31 @@
}
}
+ private static class JBMThreadThreadFactory extends JBMThreadFactory
+ {
+ public JBMThreadThreadFactory(final String groupName, final boolean daemon)
+ {
+ super(groupName, daemon);
+ }
+
+ public JBMThreadThreadFactory(final String groupName, final int threadPriority, final boolean daemon)
+ {
+ super(groupName, threadPriority, daemon);
+ }
+
+ @Override
+ public Thread newThread(final Runnable command)
+ {
+ Thread t = new JBMThread(group, command, "Thread-" + threadCount.getAndIncrement() +
+ " (group:" +
+ group.getName() +
+ ")");
+
+ t.setDaemon(daemon);
+ t.setPriority(threadPriority);
+ return t;
+ }
+
+ }
+
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/MessagingServerPacketHandler.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/MessagingServerPacketHandler.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/MessagingServerPacketHandler.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -17,9 +17,11 @@
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.CREATESESSION;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.CREATE_QUEUE;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.REATTACH_SESSION;
-import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.REPLICATE_CREATESESSION;
+import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.REPLICATE_LOCK_SEQUENCES;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.REPLICATE_STARTUP_INFO;
+import java.util.List;
+
import org.jboss.messaging.core.exception.MessagingException;
import org.jboss.messaging.core.logging.Logger;
import org.jboss.messaging.core.management.Notification;
@@ -33,21 +35,24 @@
import org.jboss.messaging.core.remoting.impl.wireformat.MessagingExceptionMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl;
import org.jboss.messaging.core.remoting.impl.wireformat.ReattachSessionMessage;
-import org.jboss.messaging.core.remoting.impl.wireformat.ReplicateCreateSessionMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateAcknowledgeMessage;
+import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateLockSequenceMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRedistributionMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRemoteBindingAddedMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRemoteBindingRemovedMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRemoteConsumerAddedMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateRemoteConsumerRemovedMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateStartupInfoMessage;
+import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicationResponseMessage;
import org.jboss.messaging.core.server.MessageReference;
import org.jboss.messaging.core.server.MessagingServer;
import org.jboss.messaging.core.server.Queue;
import org.jboss.messaging.core.server.cluster.ClusterConnection;
import org.jboss.messaging.core.server.cluster.RemoteQueueBinding;
-import org.jboss.messaging.core.transaction.Transaction;
-import org.jboss.messaging.core.transaction.impl.TransactionImpl;
+import org.jboss.messaging.core.server.replication.ReplicableAction;
+import org.jboss.messaging.core.server.replication.Replicator;
+import org.jboss.messaging.core.server.replication.impl.JBMThread;
+import org.jboss.messaging.utils.Pair;
/**
* A packet handler for all packets that need to be handled at the server level
@@ -56,7 +61,7 @@
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
* @author <a href="ataylor at redhat.com">Andy Taylor</a>
*/
-public class MessagingServerPacketHandler implements ChannelHandler
+public class MessagingServerPacketHandler implements ChannelHandler, ReplicableAction
{
private static final Logger log = Logger.getLogger(MessagingServerPacketHandler.class);
@@ -66,19 +71,81 @@
private final RemotingConnection connection;
+ private Replicator replicator;
+
+ private Packet packet;
+
+ private List<Pair<Long, Integer>> sequences;
+
public MessagingServerPacketHandler(final MessagingServer server,
final Channel channel1,
- final RemotingConnection connection)
+ final RemotingConnection connection,
+ final Replicator replicator)
{
this.server = server;
this.channel1 = channel1;
this.connection = connection;
+
+ this.replicator = replicator;
}
-
+
+ public void run()
+ {
+ handlePacket();
+ }
+
+ public Packet getPacket()
+ {
+ return packet;
+ }
+
public void handlePacket(final Packet packet)
{
+ this.packet = packet;
+
+ log.info("Handling packet " + packet.getType() + " on backup " + server.getConfiguration().isBackup());
+
+ if (server.getConfiguration().isBackup())
+ {
+ log.info("getting current thread");
+
+ JBMThread thread = JBMThread.currentThread();
+
+ thread.setReplay(sequences);
+
+ //thread.setReplay(true);
+
+ log.info("about to call handle packet");
+
+ handlePacket();
+
+ //send the response message
+
+ log.info("sending back replication response");
+
+ if (packet.getType() != PacketImpl.REPLICATE_LOCK_SEQUENCES)
+ {
+ channel1.send(new ReplicationResponseMessage());
+ }
+ }
+ else
+ {
+ log.info("not backup");
+ if (replicator != null)
+ {
+ replicator.execute(this);
+ }
+ else
+ {
+ handlePacket();
+ }
+ }
+ }
+
+ private void handlePacket()
+ {
byte type = packet.getType();
if (!server.isInitialised() && type != PacketImpl.REPLICATE_STARTUP_INFO)
@@ -90,6 +157,13 @@
// reliability replay functionality
switch (type)
{
+ case REPLICATE_LOCK_SEQUENCES:
+ {
+ ReplicateLockSequenceMessage msg = (ReplicateLockSequenceMessage)packet;
+ sequences = msg.getSequences();
+ log.info("Got sequences " + sequences.size());
+ return;
+ }
case REPLICATE_STARTUP_INFO:
{
ReplicateStartupInfoMessage msg = (ReplicateStartupInfoMessage)packet;
@@ -109,18 +183,11 @@
{
CreateSessionMessage request = (CreateSessionMessage)packet;
- handleCreateSession(request);
+ log.info("sequences is " + sequences);
+ handleCreateSession(request, sequences == null);
break;
}
- case REPLICATE_CREATESESSION:
- {
- ReplicateCreateSessionMessage request = (ReplicateCreateSessionMessage)packet;
-
- handleReplicateCreateSession(request);
-
- break;
- }
case REATTACH_SESSION:
{
ReattachSessionMessage request = (ReattachSessionMessage)packet;
@@ -192,16 +259,16 @@
log.error("Invalid packet " + packet);
}
}
+ sequences = null;
}
- private void doHandleCreateSession(final CreateSessionMessage request, final long oppositeChannelID)
+ private void handleCreateSession(final CreateSessionMessage request, final boolean activate)
{
Packet response;
try
- {
+ {
response = server.createSession(request.getName(),
- request.getSessionChannelID(),
- oppositeChannelID,
+ request.getSessionChannelID(),
request.getUsername(),
request.getPassword(),
request.getMinLargeMessageSize(),
@@ -211,7 +278,8 @@
request.isAutoCommitAcks(),
request.isPreAcknowledge(),
request.isXA(),
- request.getWindowSize());
+ request.getWindowSize(),
+ activate);
}
catch (Exception e)
{
@@ -227,68 +295,9 @@
}
}
- channel1.send(response);
+ channel1.send(response);
}
-
- private void handleCreateSession(final CreateSessionMessage request)
- {
- Channel replicatingChannel = server.getReplicatingChannel();
-
- if (replicatingChannel == null)
- {
- doHandleCreateSession(request, -1);
- }
- else
- {
- final long replicatedChannelID = replicatingChannel.getConnection().generateChannelID();
-
- Packet replPacket = new ReplicateCreateSessionMessage(request.getName(),
- replicatedChannelID,
- request.getSessionChannelID(),
- request.getVersion(),
- request.getUsername(),
- request.getPassword(),
- request.getMinLargeMessageSize(),
- request.isXA(),
- request.isAutoCommitSends(),
- request.isAutoCommitAcks(),
- request.isPreAcknowledge(),
- request.getWindowSize());
-
- replicatingChannel.replicatePacket(replPacket, 1, new Runnable()
- {
- public void run()
- {
- doHandleCreateSession(request, replicatedChannelID);
- }
- });
- }
- }
-
- private void handleReplicateCreateSession(final ReplicateCreateSessionMessage request)
- {
- try
- {
- server.replicateCreateSession(request.getName(),
- request.getReplicatedSessionChannelID(),
- request.getOriginalSessionChannelID(),
- request.getUsername(),
- request.getPassword(),
- request.getMinLargeMessageSize(),
- request.getVersion(),
- connection,
- request.isAutoCommitSends(),
- request.isAutoCommitAcks(),
- request.isPreAcknowledge(),
- request.isXA(),
- request.getWindowSize());
- }
- catch (Exception e)
- {
- log.error("Failed to handle replicate create session", e);
- }
- }
-
+
private void handleReattachSession(final ReattachSessionMessage request)
{
Packet response;
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/QueueFactoryImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/QueueFactoryImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/QueueFactoryImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -68,7 +68,7 @@
this.postOffice = postOffice;
}
- public Queue createQueue(final long persistenceID,
+ public Queue createQueue(final long id,
final SimpleString address,
final SimpleString name,
final Filter filter,
@@ -80,7 +80,7 @@
Queue queue;
if (addressSettings.isLastValueQueue())
{
- queue = new LastValueQueue(persistenceID,
+ queue = new LastValueQueue(id,
address,
name,
filter,
@@ -93,7 +93,7 @@
}
else
{
- queue = new QueueImpl(persistenceID,
+ queue = new QueueImpl(id,
address,
name,
filter,
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/QueueImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/QueueImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/QueueImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -28,10 +28,10 @@
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Lock;
import org.jboss.messaging.core.filter.Filter;
import org.jboss.messaging.core.list.PriorityLinkedList;
@@ -43,7 +43,6 @@
import org.jboss.messaging.core.persistence.StorageManager;
import org.jboss.messaging.core.postoffice.Bindings;
import org.jboss.messaging.core.postoffice.PostOffice;
-import org.jboss.messaging.core.remoting.Channel;
import org.jboss.messaging.core.server.Consumer;
import org.jboss.messaging.core.server.Distributor;
import org.jboss.messaging.core.server.HandleStatus;
@@ -52,6 +51,7 @@
import org.jboss.messaging.core.server.ScheduledDeliveryHandler;
import org.jboss.messaging.core.server.ServerMessage;
import org.jboss.messaging.core.server.cluster.impl.Redistributor;
+import org.jboss.messaging.core.server.replication.impl.StatefulObjectReadWriteLock;
import org.jboss.messaging.core.settings.HierarchicalRepository;
import org.jboss.messaging.core.settings.impl.AddressSettings;
import org.jboss.messaging.core.transaction.Transaction;
@@ -63,7 +63,7 @@
import org.jboss.messaging.utils.SimpleString;
/**
- * Implementation of a Queue TODO use Java 5 concurrent queue
+ * Implementation of a Queue
*
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
* @author <a href="ataylor at redhat.com">Andy Taylor</a>
@@ -76,11 +76,9 @@
public static final int REDISTRIBUTOR_BATCH_SIZE = 100;
- private static final boolean trace = log.isTraceEnabled();
-
public static final int NUM_PRIORITIES = 10;
- private volatile long persistenceID = -1;
+ private final long id;
private final SimpleString name;
@@ -114,8 +112,6 @@
private final PagingManager pagingManager;
- private final Semaphore lock = new Semaphore(1);
-
private volatile PagingStore pagingStore;
private final StorageManager storageManager;
@@ -140,7 +136,9 @@
private final Set<Consumer> consumers = new HashSet<Consumer>();
- public QueueImpl(final long persistenceID,
+ private final Lock lock;
+
+ public QueueImpl(final long id,
final SimpleString address,
final SimpleString name,
final Filter filter,
@@ -151,7 +149,7 @@
final StorageManager storageManager,
final HierarchicalRepository<AddressSettings> addressSettingsRepository)
{
- this.persistenceID = persistenceID;
+ this.id = id;
this.address = address;
@@ -183,6 +181,8 @@
direct = true;
scheduledDeliveryHandler = new ScheduledDeliveryHandlerImpl(scheduledExecutor);
+
+ lock = new StatefulObjectReadWriteLock(name.toString(), id, 0).writeLock();
}
// Bindable implementation -------------------------------------------------------------------------------------
@@ -241,6 +241,7 @@
if (tx == null)
{
+
if (durableRef)
{
if (!message.isStored())
@@ -250,7 +251,7 @@
message.setStored();
}
- storageManager.storeReference(ref.getQueue().getPersistenceID(), message.getMessageID());
+ storageManager.storeReference(ref.getQueue().getID(), message.getMessageID());
}
if (scheduledDeliveryTime != null && durableRef)
@@ -274,7 +275,7 @@
tx.putProperty(TransactionPropertyIndexes.CONTAINS_PERSISTENT, true);
storageManager.storeReferenceTransactional(tx.getID(),
- ref.getQueue().getPersistenceID(),
+ ref.getQueue().getID(),
message.getMessageID());
}
@@ -332,33 +333,6 @@
// Queue implementation ----------------------------------------------------------------------------------------
- public void lockDelivery()
- {
- if (backup)
- {
- return;
- }
-
- try
- {
- lock.acquire();
- }
- catch (InterruptedException e)
- {
- log.warn(e.getMessage(), e);
- }
- }
-
- public void unlockDelivery()
- {
- if (backup)
- {
- return;
- }
-
- lock.release();
- }
-
public boolean isDurable()
{
return durable;
@@ -374,16 +348,11 @@
return name;
}
- public long getPersistenceID()
+ public long getID()
{
- return persistenceID;
+ return id;
}
- public void setPersistenceID(final long id)
- {
- persistenceID = id;
- }
-
public Filter getFilter()
{
return filter;
@@ -410,67 +379,100 @@
}
// Only used in testing - do not call directly!
- public synchronized void deliverNow()
+ public void deliverNow()
{
- deliver();
+ lock.lock();
+ try
+ {
+ deliver();
+ }
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized void addConsumer(final Consumer consumer) throws Exception
+ public void addConsumer(final Consumer consumer) throws Exception
{
- cancelRedistributor();
+ lock.lock();
+ try
+ {
+ cancelRedistributor();
- distributionPolicy.addConsumer(consumer);
+ distributionPolicy.addConsumer(consumer);
- consumers.add(consumer);
+ consumers.add(consumer);
+ }
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized boolean removeConsumer(final Consumer consumer) throws Exception
+ public boolean removeConsumer(final Consumer consumer) throws Exception
{
- boolean removed = distributionPolicy.removeConsumer(consumer);
+ lock.lock();
+ try
+ {
+ boolean removed = distributionPolicy.removeConsumer(consumer);
- if (!distributionPolicy.hasConsumers())
+ if (!distributionPolicy.hasConsumers())
+ {
+ promptDelivery = false;
+ }
+
+ consumers.remove(consumer);
+
+ return removed;
+ }
+ finally
{
- promptDelivery = false;
+ lock.unlock();
}
-
- consumers.remove(consumer);
-
- return removed;
}
- public synchronized void addRedistributor(final long delay, final Executor executor, final Channel replicatingChannel)
+ public void addRedistributor(final long delay, final Executor executor)
{
- if (future != null)
+ lock.lock();
+
+ try
{
- future.cancel(false);
+ if (future != null)
+ {
+ future.cancel(false);
- futures.remove(future);
- }
+ futures.remove(future);
+ }
- if (redistributor != null)
- {
- // Just prompt delivery
- deliverAsync(executor);
- }
+ if (redistributor != null)
+ {
+ // Just prompt delivery
+ deliverAsync(executor);
+ }
- if (delay > 0)
- {
- if (consumers.size() == 0)
+ if (delay > 0)
{
- DelayedAddRedistributor dar = new DelayedAddRedistributor(executor, replicatingChannel);
+ if (consumers.size() == 0)
+ {
+ DelayedAddRedistributor dar = new DelayedAddRedistributor(executor);
- future = scheduledExecutor.schedule(dar, delay, TimeUnit.MILLISECONDS);
+ future = scheduledExecutor.schedule(dar, delay, TimeUnit.MILLISECONDS);
- futures.add(future);
+ futures.add(future);
+ }
}
+ else
+ {
+ internalAddRedistributor(executor);
+ }
}
- else
+ finally
{
- internalAddRedistributor(executor, replicatingChannel);
+ lock.unlock();
}
}
- public synchronized void cancelRedistributor() throws Exception
+ private void cancelRedistributor() throws Exception
{
if (redistributor != null)
{
@@ -487,129 +489,201 @@
}
}
- public synchronized int getConsumerCount()
+ public int getConsumerCount()
{
- return consumers.size();
+ lock.lock();
+
+ try
+ {
+ return consumers.size();
+ }
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized Set<Consumer> getConsumers()
+ public Set<Consumer> getConsumers()
{
return consumers;
}
- public synchronized List<MessageReference> list(final Filter filter)
+ public List<MessageReference> list(final Filter filter)
{
- if (filter == null)
+ lock.lock();
+
+ try
{
- return new ArrayList<MessageReference>(messageReferences.getAll());
- }
- else
- {
- ArrayList<MessageReference> list = new ArrayList<MessageReference>();
+ if (filter == null)
+ {
+ return new ArrayList<MessageReference>(messageReferences.getAll());
+ }
+ else
+ {
+ ArrayList<MessageReference> list = new ArrayList<MessageReference>();
- for (MessageReference ref : messageReferences.getAll())
- {
- if (filter.match(ref.getMessage()))
+ for (MessageReference ref : messageReferences.getAll())
{
- list.add(ref);
+ if (filter.match(ref.getMessage()))
+ {
+ list.add(ref);
+ }
}
+
+ return list;
}
-
- return list;
}
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized MessageReference removeReferenceWithID(final long id) throws Exception
+ public MessageReference removeReferenceWithID(final long id) throws Exception
{
- Iterator<MessageReference> iterator = messageReferences.iterator();
+ lock.lock();
- MessageReference removed = null;
-
- while (iterator.hasNext())
+ try
{
- MessageReference ref = iterator.next();
+ Iterator<MessageReference> iterator = messageReferences.iterator();
- if (ref.getMessage().getMessageID() == id)
+ MessageReference removed = null;
+
+ while (iterator.hasNext())
{
- iterator.remove();
+ MessageReference ref = iterator.next();
- removed = ref;
+ if (ref.getMessage().getMessageID() == id)
+ {
+ iterator.remove();
- removeExpiringReference(removed);
+ removed = ref;
- break;
+ removeExpiringReference(removed);
+
+ break;
+ }
}
+
+ if (removed == null)
+ {
+ // Look in scheduled deliveries
+ removed = scheduledDeliveryHandler.removeReferenceWithID(id);
+ }
+
+ return removed;
}
-
- if (removed == null)
+ finally
{
- // Look in scheduled deliveries
- removed = scheduledDeliveryHandler.removeReferenceWithID(id);
+ lock.unlock();
}
-
- return removed;
}
- public synchronized MessageReference removeFirstReference(final long id) throws Exception
+ public MessageReference removeFirstReference(final long id) throws Exception
{
- MessageReference ref = messageReferences.peekFirst();
+ lock.lock();
- if (ref != null && ref.getMessage().getMessageID() == id)
+ try
{
- messageReferences.removeFirst();
+ MessageReference ref = messageReferences.peekFirst();
+ if (ref != null && ref.getMessage().getMessageID() == id)
+ {
+ messageReferences.removeFirst();
+
+ return ref;
+ }
+ else
+ {
+ ref = scheduledDeliveryHandler.removeReferenceWithID(id);
+ }
+
return ref;
}
- else
+ finally
{
- ref = scheduledDeliveryHandler.removeReferenceWithID(id);
+ lock.unlock();
}
-
- return ref;
}
- public synchronized MessageReference getReference(final long id)
+ public MessageReference getReference(final long id)
{
- Iterator<MessageReference> iterator = messageReferences.iterator();
+ lock.lock();
- while (iterator.hasNext())
+ try
{
- MessageReference ref = iterator.next();
+ Iterator<MessageReference> iterator = messageReferences.iterator();
- if (ref.getMessage().getMessageID() == id)
+ while (iterator.hasNext())
{
- return ref;
+ MessageReference ref = iterator.next();
+
+ if (ref.getMessage().getMessageID() == id)
+ {
+ return ref;
+ }
}
+
+ return null;
}
-
- return null;
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized int getMessageCount()
+ public int getMessageCount()
{
- int count = messageReferences.size() + getScheduledCount() + getDeliveringCount();
+ lock.lock();
- // log.info(System.identityHashCode(this) + " message count is " +
- // count +
- // " ( mr:" +
- // messageReferences.size() +
- // " sc:" +
- // getScheduledCount() +
- // " dc:" +
- // getDeliveringCount() +
- // ")");
+ try
+ {
+ int count = messageReferences.size() + getScheduledCount() + getDeliveringCount();
- return count;
+ // log.info(System.identityHashCode(this) + " message count is " +
+ // count +
+ // " ( mr:" +
+ // messageReferences.size() +
+ // " sc:" +
+ // getScheduledCount() +
+ // " dc:" +
+ // getDeliveringCount() +
+ // ")");
+
+ return count;
+ }
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized int getScheduledCount()
+ public int getScheduledCount()
{
- return scheduledDeliveryHandler.getScheduledCount();
+ lock.lock();
+
+ try
+ {
+ return scheduledDeliveryHandler.getScheduledCount();
+ }
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized List<MessageReference> getScheduledMessages()
+ public List<MessageReference> getScheduledMessages()
{
- return scheduledDeliveryHandler.getScheduledReferences();
+ lock.lock();
+
+ try
+ {
+ return scheduledDeliveryHandler.getScheduledReferences();
+ }
+ finally
+ {
+ lock.unlock();
+ }
}
public int getDeliveringCount()
@@ -625,7 +699,7 @@
if (durableRef)
{
- storageManager.storeAcknowledge(persistenceID, message.getMessageID());
+ storageManager.storeAcknowledge(id, message.getMessageID());
}
postAcknowledge(ref);
@@ -639,7 +713,7 @@
if (durableRef)
{
- storageManager.storeAcknowledgeTransactional(tx.getID(), persistenceID, message.getMessageID());
+ storageManager.storeAcknowledgeTransactional(tx.getID(), id, message.getMessageID());
tx.putProperty(TransactionPropertyIndexes.CONTAINS_PERSISTENT, true);
}
@@ -683,15 +757,24 @@
getRefsOperation(tx).addAck(reference);
}
- public synchronized void cancel(final MessageReference reference) throws Exception
+ public void cancel(final MessageReference reference) throws Exception
{
- if (checkDLQ(reference))
+ lock.lock();
+
+ try
{
- if (!scheduledDeliveryHandler.checkAndSchedule(reference, backup))
+ if (checkDLQ(reference))
{
- messageReferences.addFirst(reference, reference.getMessage().getPriority());
+ if (!scheduledDeliveryHandler.checkAndSchedule(reference, backup))
+ {
+ messageReferences.addFirst(reference, reference.getMessage().getPriority());
+ }
}
}
+ finally
+ {
+ lock.unlock();
+ }
}
public void expire(final MessageReference ref) throws Exception
@@ -744,214 +827,294 @@
return deleteMatchingReferences(null);
}
- public synchronized int deleteMatchingReferences(final Filter filter) throws Exception
+ public int deleteMatchingReferences(final Filter filter) throws Exception
{
- int count = 0;
+ lock.lock();
- Transaction tx = new TransactionImpl(storageManager);
+ try
+ {
+ int count = 0;
- Iterator<MessageReference> iter = messageReferences.iterator();
+ Transaction tx = new TransactionImpl(storageManager);
- while (iter.hasNext())
- {
- MessageReference ref = iter.next();
+ Iterator<MessageReference> iter = messageReferences.iterator();
- if (filter == null || filter.match(ref.getMessage()))
+ while (iter.hasNext())
{
- deliveringCount.incrementAndGet();
- acknowledge(tx, ref);
- iter.remove();
- count++;
+ MessageReference ref = iter.next();
+
+ if (filter == null || filter.match(ref.getMessage()))
+ {
+ deliveringCount.incrementAndGet();
+ acknowledge(tx, ref);
+ iter.remove();
+ count++;
+ }
}
- }
- List<MessageReference> cancelled = scheduledDeliveryHandler.cancel();
- for (MessageReference messageReference : cancelled)
- {
- if (filter == null || filter.match(messageReference.getMessage()))
+ List<MessageReference> cancelled = scheduledDeliveryHandler.cancel();
+ for (MessageReference messageReference : cancelled)
{
- deliveringCount.incrementAndGet();
- acknowledge(tx, messageReference);
- count++;
+ if (filter == null || filter.match(messageReference.getMessage()))
+ {
+ deliveringCount.incrementAndGet();
+ acknowledge(tx, messageReference);
+ count++;
+ }
}
- }
- tx.commit();
+ tx.commit();
- return count;
+ return count;
+ }
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized boolean deleteReference(final long messageID) throws Exception
+ public boolean deleteReference(final long messageID) throws Exception
{
- boolean deleted = false;
+ lock.lock();
- Transaction tx = new TransactionImpl(storageManager);
+ try
+ {
+ boolean deleted = false;
- Iterator<MessageReference> iter = messageReferences.iterator();
+ Transaction tx = new TransactionImpl(storageManager);
- while (iter.hasNext())
- {
- MessageReference ref = iter.next();
- if (ref.getMessage().getMessageID() == messageID)
+ Iterator<MessageReference> iter = messageReferences.iterator();
+
+ while (iter.hasNext())
{
- deliveringCount.incrementAndGet();
- acknowledge(tx, ref);
- iter.remove();
- deleted = true;
- break;
+ MessageReference ref = iter.next();
+ if (ref.getMessage().getMessageID() == messageID)
+ {
+ deliveringCount.incrementAndGet();
+ acknowledge(tx, ref);
+ iter.remove();
+ deleted = true;
+ break;
+ }
}
- }
- tx.commit();
+ tx.commit();
- return deleted;
+ return deleted;
+ }
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized boolean expireReference(final long messageID) throws Exception
+ public boolean expireReference(final long messageID) throws Exception
{
- Iterator<MessageReference> iter = messageReferences.iterator();
+ lock.lock();
- while (iter.hasNext())
+ try
{
- MessageReference ref = iter.next();
- if (ref.getMessage().getMessageID() == messageID)
+ Iterator<MessageReference> iter = messageReferences.iterator();
+
+ while (iter.hasNext())
{
- deliveringCount.incrementAndGet();
- expire(ref);
- iter.remove();
- return true;
+ MessageReference ref = iter.next();
+ if (ref.getMessage().getMessageID() == messageID)
+ {
+ deliveringCount.incrementAndGet();
+ expire(ref);
+ iter.remove();
+ return true;
+ }
}
+ return false;
}
- return false;
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized int expireReferences(final Filter filter) throws Exception
+ public int expireReferences(final Filter filter) throws Exception
{
- Transaction tx = new TransactionImpl(storageManager);
+ lock.lock();
- int count = 0;
- Iterator<MessageReference> iter = messageReferences.iterator();
+ try
+ {
+ Transaction tx = new TransactionImpl(storageManager);
- while (iter.hasNext())
- {
- MessageReference ref = iter.next();
- if (filter == null || filter.match(ref.getMessage()))
+ int count = 0;
+ Iterator<MessageReference> iter = messageReferences.iterator();
+
+ while (iter.hasNext())
{
- deliveringCount.incrementAndGet();
- expire(tx, ref);
- iter.remove();
- count++;
+ MessageReference ref = iter.next();
+ if (filter == null || filter.match(ref.getMessage()))
+ {
+ deliveringCount.incrementAndGet();
+ expire(tx, ref);
+ iter.remove();
+ count++;
+ }
}
- }
- tx.commit();
+ tx.commit();
- return count;
+ return count;
+ }
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized void expireReferences() throws Exception
+ public void expireReferences() throws Exception
{
- for (MessageReference expiringMessageReference : expiringMessageReferences)
+ lock.lock();
+
+ try
{
- if (expiringMessageReference.getMessage().isExpired())
+ for (MessageReference expiringMessageReference : expiringMessageReferences)
{
- expireReference(expiringMessageReference.getMessage().getMessageID());
+ if (expiringMessageReference.getMessage().isExpired())
+ {
+ expireReference(expiringMessageReference.getMessage().getMessageID());
+ }
}
}
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized boolean sendMessageToDeadLetterAddress(final long messageID) throws Exception
+ public boolean sendMessageToDeadLetterAddress(final long messageID) throws Exception
{
- Iterator<MessageReference> iter = messageReferences.iterator();
+ lock.lock();
- while (iter.hasNext())
+ try
{
- MessageReference ref = iter.next();
- if (ref.getMessage().getMessageID() == messageID)
+ Iterator<MessageReference> iter = messageReferences.iterator();
+
+ while (iter.hasNext())
{
- deliveringCount.incrementAndGet();
- sendToDeadLetterAddress(ref);
- iter.remove();
- return true;
+ MessageReference ref = iter.next();
+ if (ref.getMessage().getMessageID() == messageID)
+ {
+ deliveringCount.incrementAndGet();
+ sendToDeadLetterAddress(ref);
+ iter.remove();
+ return true;
+ }
}
+ return false;
}
- return false;
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized boolean moveReference(final long messageID, final SimpleString toAddress) throws Exception
+ public boolean moveReference(final long messageID, final SimpleString toAddress) throws Exception
{
- Iterator<MessageReference> iter = messageReferences.iterator();
+ lock.lock();
- while (iter.hasNext())
+ try
{
- MessageReference ref = iter.next();
- if (ref.getMessage().getMessageID() == messageID)
+ Iterator<MessageReference> iter = messageReferences.iterator();
+
+ while (iter.hasNext())
{
- iter.remove();
- deliveringCount.incrementAndGet();
- move(toAddress, ref);
- return true;
+ MessageReference ref = iter.next();
+ if (ref.getMessage().getMessageID() == messageID)
+ {
+ iter.remove();
+ deliveringCount.incrementAndGet();
+ move(toAddress, ref);
+ return true;
+ }
}
+ return false;
}
- return false;
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized int moveReferences(final Filter filter, final SimpleString toAddress) throws Exception
+ public int moveReferences(final Filter filter, final SimpleString toAddress) throws Exception
{
- Transaction tx = new TransactionImpl(storageManager);
+ lock.lock();
- int count = 0;
- Iterator<MessageReference> iter = messageReferences.iterator();
+ try
+ {
+ Transaction tx = new TransactionImpl(storageManager);
- while (iter.hasNext())
- {
- MessageReference ref = iter.next();
- if (filter == null || filter.match(ref.getMessage()))
+ int count = 0;
+ Iterator<MessageReference> iter = messageReferences.iterator();
+
+ while (iter.hasNext())
{
- deliveringCount.incrementAndGet();
- move(toAddress, tx, ref, false);
- iter.remove();
- count++;
+ MessageReference ref = iter.next();
+ if (filter == null || filter.match(ref.getMessage()))
+ {
+ deliveringCount.incrementAndGet();
+ move(toAddress, tx, ref, false);
+ iter.remove();
+ count++;
+ }
}
- }
- List<MessageReference> cancelled = scheduledDeliveryHandler.cancel();
- for (MessageReference ref : cancelled)
- {
- if (filter == null || filter.match(ref.getMessage()))
+ List<MessageReference> cancelled = scheduledDeliveryHandler.cancel();
+ for (MessageReference ref : cancelled)
{
- deliveringCount.incrementAndGet();
- move(toAddress, tx, ref, false);
- acknowledge(tx, ref);
- count++;
+ if (filter == null || filter.match(ref.getMessage()))
+ {
+ deliveringCount.incrementAndGet();
+ move(toAddress, tx, ref, false);
+ acknowledge(tx, ref);
+ count++;
+ }
}
- }
- tx.commit();
+ tx.commit();
- return count;
+ return count;
+ }
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized boolean changeReferencePriority(final long messageID, final byte newPriority) throws Exception
+ public boolean changeReferencePriority(final long messageID, final byte newPriority) throws Exception
{
- List<MessageReference> refs = list(null);
- for (MessageReference ref : refs)
+ lock.lock();
+ try
{
- ServerMessage message = ref.getMessage();
- if (message.getMessageID() == messageID)
+ List<MessageReference> refs = list(null);
+ for (MessageReference ref : refs)
{
- message.setPriority(newPriority);
- // delete and add the reference so that it
- // goes to the right queues for the new priority
+ ServerMessage message = ref.getMessage();
+ if (message.getMessageID() == messageID)
+ {
+ message.setPriority(newPriority);
+ // delete and add the reference so that it
+ // goes to the right queues for the new priority
- // FIXME - why deleting the reference?? This will delete it from storage!!
+ // FIXME - why deleting the reference?? This will delete it from storage!!
- deleteReference(messageID);
- addLast(ref);
- return true;
+ deleteReference(messageID);
+ addLast(ref);
+ return true;
+ }
}
+ return false;
}
- return false;
+ finally
+ {
+ lock.unlock();
+ }
}
public boolean isBackup()
@@ -959,64 +1122,98 @@
return backup;
}
- public synchronized void setBackup()
+ public void setBackup()
{
backup = true;
direct = false;
}
- public synchronized boolean activate()
+ public boolean activate()
{
- consumersToFailover = consumers.size();
-
- if (consumersToFailover == 0)
+ lock.lock();
+ try
{
- backup = false;
+ consumersToFailover = consumers.size();
- return true;
+ if (consumersToFailover == 0)
+ {
+ backup = false;
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
- else
+ finally
{
- return false;
+ lock.unlock();
}
}
- public synchronized void activateNow(final Executor executor)
+ public void activateNow(final Executor executor)
{
- if (backup)
+ lock.lock();
+ try
{
- log.info("Timed out waiting for all consumers to reconnect to queue " + name +
- " so queue will be activated now");
+ if (backup)
+ {
+ log.info("Timed out waiting for all consumers to reconnect to queue " + name +
+ " so queue will be activated now");
- backup = false;
+ backup = false;
- scheduledDeliveryHandler.reSchedule();
+ scheduledDeliveryHandler.reSchedule();
- deliverAsync(executor);
+ deliverAsync(executor);
+ }
}
+ finally
+ {
+ lock.unlock();
+ }
}
- public synchronized boolean consumerFailedOver()
+ public boolean consumerFailedOver()
{
- consumersToFailover--;
-
- if (consumersToFailover == 0)
+ lock.lock();
+ try
{
- // All consumers for the queue have failed over, can re-activate it now
+ consumersToFailover--;
- backup = false;
+ if (consumersToFailover == 0)
+ {
+ // All consumers for the queue have failed over, can re-activate it now
- scheduledDeliveryHandler.reSchedule();
+ backup = false;
- return true;
+ scheduledDeliveryHandler.reSchedule();
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
- else
+ finally
{
- return false;
+ lock.unlock();
}
}
+ public void lock()
+ {
+ lock.lock();
+ }
+
+ public void unlock()
+ {
+ lock.unlock();
+ }
+
// Public
// -----------------------------------------------------------------------------
@@ -1048,17 +1245,12 @@
// Private
// ------------------------------------------------------------------------------
- private void internalAddRedistributor(final Executor executor, final Channel replicatingChannel)
+ private void internalAddRedistributor(final Executor executor)
{
// create the redistributor only once if there are no local consumers
if (consumers.size() == 0 && redistributor == null)
{
- redistributor = new Redistributor(this,
- storageManager,
- postOffice,
- executor,
- REDISTRIBUTOR_BATCH_SIZE,
- replicatingChannel);
+ redistributor = new Redistributor(this, storageManager, postOffice, executor, REDISTRIBUTOR_BATCH_SIZE);
distributionPolicy.addConsumer(redistributor);
@@ -1228,181 +1420,198 @@
/*
* Attempt to deliver all the messages in the queue
*/
- private synchronized void deliver()
+ private void deliver()
{
- // We don't do actual delivery if the queue is on a backup node - this is
- // because it's async and could get out of step
- // with the live node. Instead, when we replicate the delivery we remove
- // the ref from the queue
+ lock.lock();
- if (backup)
+ try
{
- return;
- }
+ // We don't do actual delivery if the queue is on a backup node - this is
+ // because it's async and could get out of step
+ // with the live node. Instead, when we replicate the delivery we remove
+ // the ref from the queue
- direct = false;
+ if (backup)
+ {
+ return;
+ }
- MessageReference reference;
+ direct = false;
- Iterator<MessageReference> iterator = null;
+ MessageReference reference;
- while (true)
- {
- if (iterator == null)
+ Iterator<MessageReference> iterator = null;
+
+ while (true)
{
- reference = messageReferences.peekFirst();
- }
- else
- {
- if (iterator.hasNext())
+ if (iterator == null)
{
- reference = iterator.next();
+ reference = messageReferences.peekFirst();
}
else
{
- reference = null;
+ if (iterator.hasNext())
+ {
+ reference = iterator.next();
+ }
+ else
+ {
+ reference = null;
+ }
}
- }
- if (reference == null)
- {
- if (iterator == null)
+ if (reference == null)
{
- if (pagingStore != null)
+ if (iterator == null)
{
- // If the queue is empty, we need to check if there are pending messages, and throw a warning
- if (pagingStore.isPaging() && !pagingStore.isDropWhenMaxSize())
+ if (pagingStore != null)
{
- // This is just a *request* to depage. Depage will only happens if there is space on the Address
- // and GlobalSize
- pagingStore.startDepaging();
+ // If the queue is empty, we need to check if there are pending messages, and throw a warning
+ if (pagingStore.isPaging() && !pagingStore.isDropWhenMaxSize())
+ {
+ // This is just a *request* to depage. Depage will only happens if there is space on the Address
+ // and GlobalSize
+ pagingStore.startDepaging();
- log.warn("The Queue " + name +
- " is empty, however there are pending messages on Paging for the address " +
- pagingStore.getStoreName() +
- " waiting message ACK before they could be routed");
+ log.warn("The Queue " + name +
+ " is empty, however there are pending messages on Paging for the address " +
+ pagingStore.getStoreName() +
+ " waiting message ACK before they could be routed");
+ }
}
+ // We delivered all the messages - go into direct delivery
+ direct = true;
+
+ promptDelivery = false;
}
- // We delivered all the messages - go into direct delivery
- direct = true;
-
- promptDelivery = false;
+ return;
}
- return;
- }
- // PagingManager would be null only on testcases
- if (pagingStore == null && pagingManager != null)
- {
- // TODO: It would be better if we could initialize the pagingStore during the construction
- try
+ // PagingManager would be null only on testcases
+ if (pagingStore == null && pagingManager != null)
{
- pagingStore = pagingManager.getPageStore(reference.getMessage().getDestination());
+ // TODO: It would be better if we could initialize the pagingStore during the construction
+ try
+ {
+ pagingStore = pagingManager.getPageStore(reference.getMessage().getDestination());
+ }
+ catch (Exception e)
+ {
+ // This shouldn't happen, and if it happens, this shouldn't abort the route
+ }
}
- catch (Exception e)
- {
- // This shouldn't happen, and if it happens, this shouldn't abort the route
- }
- }
- HandleStatus status = deliver(reference);
+ HandleStatus status = deliver(reference);
- if (status == HandleStatus.HANDLED)
- {
- if (iterator == null)
+ if (status == HandleStatus.HANDLED)
{
- messageReferences.removeFirst();
+ if (iterator == null)
+ {
+ messageReferences.removeFirst();
+ }
+ else
+ {
+ iterator.remove();
+ }
}
- else
+ else if (status == HandleStatus.BUSY)
{
- iterator.remove();
+ // All consumers busy - give up
+ break;
}
+ else if (status == HandleStatus.NO_MATCH && iterator == null)
+ {
+ // Consumers not all busy - but filter not accepting - iterate
+ // back
+ // through the queue
+ iterator = messageReferences.iterator();
+ }
}
- else if (status == HandleStatus.BUSY)
- {
- // All consumers busy - give up
- break;
- }
- else if (status == HandleStatus.NO_MATCH && iterator == null)
- {
- // Consumers not all busy - but filter not accepting - iterate
- // back
- // through the queue
- iterator = messageReferences.iterator();
- }
}
+ finally
+ {
+ lock.unlock();
+ }
}
- private synchronized void add(final MessageReference ref, final boolean first)
+ private void add(final MessageReference ref, final boolean first)
{
- if (!first)
+ lock.lock();
+ try
{
- messagesAdded.incrementAndGet();
- }
+ if (!first)
+ {
+ messagesAdded.incrementAndGet();
+ }
- if (scheduledDeliveryHandler.checkAndSchedule(ref, backup))
- {
- return;
- }
+ if (scheduledDeliveryHandler.checkAndSchedule(ref, backup))
+ {
+ return;
+ }
- boolean add = false;
+ boolean add = false;
- if (direct && !backup)
- {
- // Deliver directly
+ if (direct && !backup)
+ {
+ // Deliver directly
- HandleStatus status = deliver(ref);
+ HandleStatus status = deliver(ref);
- if (status == HandleStatus.HANDLED)
- {
- // Ok
+ if (status == HandleStatus.HANDLED)
+ {
+ // Ok
+ }
+ else if (status == HandleStatus.BUSY)
+ {
+ add = true;
+ }
+ else if (status == HandleStatus.NO_MATCH)
+ {
+ add = true;
+ }
+
+ if (add)
+ {
+ direct = false;
+ }
}
- else if (status == HandleStatus.BUSY)
+ else
{
add = true;
}
- else if (status == HandleStatus.NO_MATCH)
- {
- add = true;
- }
if (add)
{
- direct = false;
+ if (ref.getMessage().getExpiration() != 0)
+ {
+ expiringMessageReferences.addIfAbsent(ref);
+ }
+
+ if (first)
+ {
+ messageReferences.addFirst(ref, ref.getMessage().getPriority());
+ }
+ else
+ {
+ messageReferences.addLast(ref, ref.getMessage().getPriority());
+ }
+
+ if (!direct && promptDelivery)
+ {
+ // We have consumers with filters which don't match, so we need
+ // to prompt delivery every time
+ // a new message arrives - this is why you really shouldn't use
+ // filters with queues - in most cases
+ // it's an ant-pattern since it would cause a queue scan on each
+ // message
+ deliver();
+ }
}
}
- else
+ finally
{
- add = true;
+ lock.unlock();
}
-
- if (add)
- {
- if (ref.getMessage().getExpiration() != 0)
- {
- expiringMessageReferences.addIfAbsent(ref);
- }
-
- if (first)
- {
- messageReferences.addFirst(ref, ref.getMessage().getPriority());
- }
- else
- {
- messageReferences.addLast(ref, ref.getMessage().getPriority());
- }
-
- if (!direct && promptDelivery)
- {
- // We have consumers with filters which don't match, so we need
- // to prompt delivery every time
- // a new message arrives - this is why you really shouldn't use
- // filters with queues - in most cases
- // it's an ant-pattern since it would cause a queue scan on each
- // message
- deliver();
- }
- }
}
private HandleStatus deliver(final MessageReference reference)
@@ -1474,9 +1683,10 @@
}
}
- void postRollback(LinkedList<MessageReference> refs) throws Exception
+ protected void postRollback(LinkedList<MessageReference> refs) throws Exception
{
- synchronized (this)
+ lock.lock();
+ try
{
for (MessageReference ref : refs)
{
@@ -1490,6 +1700,10 @@
deliver();
}
+ finally
+ {
+ lock.unlock();
+ }
}
// Inner classes
@@ -1502,15 +1716,7 @@
// Must be set to false *before* executing to avoid race
waitingToDeliver.set(false);
- QueueImpl.this.lockDelivery();
- try
- {
- deliver();
- }
- finally
- {
- QueueImpl.this.unlockDelivery();
- }
+ deliver();
}
}
@@ -1565,10 +1771,15 @@
QueueImpl queue = entry.getKey();
- synchronized (queue)
+ queue.lock.lock();
+ try
{
queue.postRollback(refs);
}
+ finally
+ {
+ queue.lock.unlock();
+ }
}
}
@@ -1596,10 +1807,15 @@
for (MessageReference ref : refsToAck)
{
- synchronized (ref.getQueue())
+ ref.getQueue().lock();
+ try
{
postAcknowledge(ref);
}
+ finally
+ {
+ ref.getQueue().unlock();
+ }
}
}
@@ -1635,23 +1851,24 @@
{
private final Executor executor;
- private final Channel replicatingChannel;
-
- DelayedAddRedistributor(final Executor executor, final Channel replicatingChannel)
+ private DelayedAddRedistributor(final Executor executor)
{
this.executor = executor;
-
- this.replicatingChannel = replicatingChannel;
}
public void run()
{
- synchronized (QueueImpl.this)
+ lock.lock();
+ try
{
- internalAddRedistributor(executor, replicatingChannel);
+ internalAddRedistributor(executor);
futures.remove(this);
}
+ finally
+ {
+ lock.unlock();
+ }
}
}
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/ServerConsumerImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/ServerConsumerImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/ServerConsumerImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -26,9 +26,7 @@
import java.util.LinkedList;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
import org.jboss.messaging.core.buffers.ChannelBuffers;
import org.jboss.messaging.core.client.management.impl.ManagementHelper;
@@ -43,19 +41,17 @@
import org.jboss.messaging.core.postoffice.Binding;
import org.jboss.messaging.core.postoffice.QueueBinding;
import org.jboss.messaging.core.remoting.Channel;
-import org.jboss.messaging.core.remoting.Packet;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionReceiveContinuationMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionReceiveMessage;
-import org.jboss.messaging.core.remoting.impl.wireformat.replication.SessionReplicateDeliveryMessage;
import org.jboss.messaging.core.remoting.spi.MessagingBuffer;
import org.jboss.messaging.core.server.HandleStatus;
import org.jboss.messaging.core.server.LargeServerMessage;
import org.jboss.messaging.core.server.MessageReference;
-import org.jboss.messaging.core.server.MessagingServer;
import org.jboss.messaging.core.server.Queue;
import org.jboss.messaging.core.server.ServerConsumer;
import org.jboss.messaging.core.server.ServerMessage;
import org.jboss.messaging.core.server.ServerSession;
+import org.jboss.messaging.core.server.replication.impl.StatefulObjectReadWriteLock;
import org.jboss.messaging.core.transaction.Transaction;
import org.jboss.messaging.core.transaction.impl.TransactionImpl;
import org.jboss.messaging.utils.TypedProperties;
@@ -77,19 +73,10 @@
// Static ---------------------------------------------------------------------------------------
- private static final boolean trace = log.isTraceEnabled();
-
- private static void trace(final String message)
- {
- log.trace(message);
- }
-
// Attributes -----------------------------------------------------------------------------------
private final long id;
- private final long replicatedSessionID;
-
private final Queue messageQueue;
private final Filter filter;
@@ -100,17 +87,15 @@
private final Executor executor;
- private final Lock lock = new ReentrantLock();
+ private final Lock lock;
- private AtomicInteger availableCredits = new AtomicInteger(0);
+ private int availableCredits;
private boolean started;
private volatile LargeMessageDeliverer largeMessageDeliverer = null;
- // We will only be sending one largeMessage at any time, however during replication you may have
- // more than one LargeMessage pending on the replicationBuffer
- private final AtomicInteger pendingLargeMessagesCounter = new AtomicInteger(0);
+ private volatile boolean hasPendingLargeMessage;
/**
* if we are a browse only consumer we don't need to worry about acknowledgemenets or being started/stopeed by the session.
@@ -127,8 +112,6 @@
private final Channel channel;
- private final Channel replicatingChannel;
-
private volatile boolean closed;
private final boolean preAcknowledge;
@@ -137,10 +120,11 @@
private final Binding binding;
+ private boolean flowControl = true;
+
// Constructors ---------------------------------------------------------------------------------
public ServerConsumerImpl(final long id,
- final long replicatedSessionID,
final ServerSession session,
final QueueBinding binding,
final Filter filter,
@@ -149,7 +133,6 @@
final StorageManager storageManager,
final PagingManager pagingManager,
final Channel channel,
- final Channel replicatingChannel,
final boolean preAcknowledge,
final boolean updateDeliveries,
final Executor executor,
@@ -157,8 +140,6 @@
{
this.id = id;
- this.replicatedSessionID = replicatedSessionID;
-
this.filter = filter;
this.session = session;
@@ -177,8 +158,6 @@
this.channel = channel;
- this.replicatingChannel = replicatingChannel;
-
this.preAcknowledge = preAcknowledge;
this.pagingManager = pagingManager;
@@ -188,7 +167,9 @@
this.minLargeMessageSize = session.getMinLargeMessageSize();
this.updateDeliveries = updateDeliveries;
-
+
+ lock = new StatefulObjectReadWriteLock("consumer " + id, storageManager.generateUniqueID(), 0).writeLock();
+
binding.getQueue().addConsumer(this);
}
@@ -300,6 +281,7 @@
public void setStarted(final boolean started)
{
lock.lock();
+
try
{
this.started = browseOnly || started;
@@ -315,32 +297,40 @@
promptDelivery();
}
}
-
+
public void receiveCredits(final int credits) throws Exception
{
- if (credits == -1)
- {
- // No flow control
- availableCredits = null;
- }
- else
- {
- int previous = availableCredits.getAndAdd(credits);
+ boolean promptDelivery = false;
- if (trace)
+ lock.lock();
+
+ try
+ {
+ if (credits == -1)
{
- log.trace("Received " + credits +
- " credits, previous value = " +
- previous +
- " currentValue = " +
- availableCredits.get());
+ // No flow control
+ flowControl = false;
}
-
- if (previous <= 0 && previous + credits > 0)
+ else
{
- promptDelivery();
+ if (availableCredits <= 0 && availableCredits + credits > 0)
+ {
+ promptDelivery = true;
+ }
+
+ availableCredits += credits;
}
}
+ finally
+ {
+ lock.unlock();
+ }
+
+ if (promptDelivery)
+ {
+ promptDelivery();
+ }
+
}
public Queue getQueue()
@@ -365,7 +355,7 @@
if (ref == null)
{
- throw new IllegalStateException(System.identityHashCode(this) + " Could not find reference on consumerID=" +
+ throw new IllegalStateException(System.identityHashCode(this) + " Could not find reference on consumer ID=" +
id +
", messageId = " +
messageID +
@@ -428,49 +418,6 @@
return ref;
}
- public void deliverReplicated(final long messageID) throws Exception
- {
- MessageReference ref = messageQueue.removeFirstReference(messageID);
-
- if (ref == null)
- {
- // The order is correct, but it hasn't been depaged yet, so we need to force a depage
- PagingStore store = pagingManager.getPageStore(binding.getAddress());
-
- // force a depage
- if (!store.readPage()) // This returns false if there are no pages
- {
- throw new IllegalStateException("Cannot find Reference[" + messageID +
- "] in queue " +
- messageQueue.getName());
- }
- else
- {
- ref = messageQueue.removeFirstReference(messageID);
-
- if (ref == null)
- {
- throw new IllegalStateException("Cannot find Reference[" + messageID +
- "] after depaging on Queue " +
- messageQueue.getName());
- }
- }
- }
-
- // We call doHandle rather than handle, since we don't want to check available credits
- // This is because delivery and receive credits can be processed in different order on live
- // and backup, and otherwise we could have a situation where the delivery is replicated
- // but the credits haven't arrived yet, so the delivery gets rejected on backup
- HandleStatus handled = doHandle(ref);
-
- if (handled != HandleStatus.HANDLED)
- {
- throw new IllegalStateException("Reference " + ref +
- " was not handled on backup node, handleStatus = " +
- handled);
- }
- }
-
public void failedOver()
{
if (messageQueue.consumerFailedOver())
@@ -482,50 +429,36 @@
}
}
- public void lock()
- {
- lock.lock();
- }
-
- public void unlock()
- {
- lock.unlock();
- }
-
// Public ---------------------------------------------------------------------------------------
/** To be used on tests only */
- public AtomicInteger getAvailableCredits()
+ public int getAvailableCredits()
{
- return availableCredits;
+ lock.lock();
+ try
+ {
+ return availableCredits;
+ }
+ finally
+ {
+ lock.unlock();
+ }
}
// Private --------------------------------------------------------------------------------------
private void promptDelivery()
{
- if (trace)
+ // largeMessageDeliverer is aways set inside a lock
+ // if we don't acquire a lock, we will have NPE eventually
+ if (largeMessageDeliverer != null)
{
- log.trace("Starting prompt delivery");
+ resumeLargeMessage();
}
- lock.lock();
- try
+ else
{
- // largeMessageDeliverer is aways set inside a lock
- // if we don't acquire a lock, we will have NPE eventually
- if (largeMessageDeliverer != null)
- {
- resumeLargeMessage();
- }
- else
- {
- session.promptDelivery(messageQueue);
- }
+ session.promptDelivery(messageQueue);
}
- finally
- {
- lock.unlock();
- }
}
/**
@@ -550,19 +483,11 @@
private HandleStatus doHandle(final MessageReference ref) throws Exception
{
- if (availableCredits != null && availableCredits.get() <= 0)
- {
- return HandleStatus.BUSY;
- }
-
lock.lock();
try
{
- // If the consumer is stopped then we don't accept the message, it
- // should go back into the
- // queue for delivery later.
- if (!started)
+ if ((flowControl && availableCredits <= 0) || !started)
{
return HandleStatus.BUSY;
}
@@ -571,15 +496,8 @@
// If there is a pendingLargeMessage we can't take another message
// This has to be checked inside the lock as the set to null is done inside the lock
- if (pendingLargeMessagesCounter.get() > 0)
+ if (hasPendingLargeMessage)
{
- if (messageQueue.isBackup())
- {
- log.warn("doHandle: rejecting message while send is pending, ignoring reference = " + ref +
- " backup = " +
- messageQueue.isBackup());
- }
-
return HandleStatus.BUSY;
}
@@ -603,12 +521,9 @@
// If updateDeliveries = false (set by strict-update),
// the updateDeliveryCount would still be updated after cancel
- if (updateDeliveries)
+ if (updateDeliveries && ref.getMessage().isDurable() && ref.getQueue().isDurable())
{
- if (ref.getMessage().isDurable() && ref.getQueue().isDurable())
- {
- storageManager.updateDeliveryCount(ref);
- }
+ storageManager.updateDeliveryCount(ref);
}
if (preAcknowledge)
@@ -644,44 +559,11 @@
private void deliverLargeMessage(final MessageReference ref, final ServerMessage message)
{
- pendingLargeMessagesCounter.incrementAndGet();
+ hasPendingLargeMessage = true;
- final LargeMessageDeliverer localDeliverer = new LargeMessageDeliverer((LargeServerMessage)message, ref);
+ largeMessageDeliverer = new LargeMessageDeliverer((LargeServerMessage)message, ref);
- if (replicatingChannel == null)
- {
- // it doesn't need lock because deliverLargeMesasge is already inside the lock()
- largeMessageDeliverer = localDeliverer;
- largeMessageDeliverer.deliver();
- }
- else
- {
- Packet replPacket = new SessionReplicateDeliveryMessage(id, message.getMessageID());
- replPacket.setChannelID(channel.getID());
-
- replicatingChannel.replicatePacket(replPacket, replicatedSessionID, new Runnable()
- {
- public void run()
- {
- // setting & unsetting largeMessageDeliver is done inside the lock,
- // so this needs to be locked
- lock.lock();
- try
- {
- largeMessageDeliverer = localDeliverer;
- if (largeMessageDeliverer.deliver())
- {
- promptDelivery();
- }
- }
- finally
- {
- lock.unlock();
- }
- }
- });
- }
-
+ largeMessageDeliverer.deliver();
}
/**
@@ -692,48 +574,18 @@
{
final SessionReceiveMessage packet = new SessionReceiveMessage(id, message, ref.getDeliveryCount());
- if (availableCredits != null)
+ if (flowControl)
{
- availableCredits.addAndGet(-packet.getRequiredBufferSize());
- if (trace)
- {
- log.trace("Taking " + packet.getRequiredBufferSize() + " out of flow control");
- }
+ availableCredits -= packet.getRequiredBufferSize();
}
- if (replicatingChannel == null)
- {
- // Not replicated - just send now
-
- if (trace)
- {
- log.trace("delivering Message " + ref + " on backup");
- }
- channel.send(packet);
- }
- else
- {
- Packet replPacket = new SessionReplicateDeliveryMessage(id, message.getMessageID());
- replPacket.setChannelID(channel.getID());
-
- replicatingChannel.replicatePacket(replPacket, replicatedSessionID, new Runnable()
- {
- public void run()
- {
- if (trace)
- {
- log.trace("delivering Message " + ref + " on live");
- }
- channel.send(packet);
- }
- });
- }
+ channel.send(packet);
}
// Inner classes
// ------------------------------------------------------------------------
- final Runnable resumeLargeMessageRunnable = new Runnable()
+ private final Runnable resumeLargeMessageRunnable = new Runnable()
{
public void run()
{
@@ -792,7 +644,7 @@
return true;
}
- if (availableCredits != null && availableCredits.get() <= 0)
+ if (flowControl && availableCredits <= 0)
{
return false;
}
@@ -818,7 +670,7 @@
int precalculateAvailableCredits;
- if (availableCredits != null)
+ if (flowControl)
{
// Flow control needs to be done in advance.
precalculateAvailableCredits = preCalculateFlowControl(initialMessage);
@@ -832,7 +684,7 @@
{
channel.send(initialMessage);
- if (availableCredits != null)
+ if (flowControl)
{
precalculateAvailableCredits -= initialMessage.getRequiredBufferSize();
}
@@ -840,12 +692,8 @@
while (positionPendingLargeMessage < sizePendingLargeMessage)
{
- if (precalculateAvailableCredits <= 0 && availableCredits != null)
+ if (flowControl && precalculateAvailableCredits <= 0)
{
- if (trace)
- {
- trace("deliverLargeMessage: Leaving loop of send LargeMessage because of credits, backup = " + messageQueue.isBackup());
- }
return false;
}
@@ -853,7 +701,7 @@
int chunkLen = chunk.getBody().length;
- if (availableCredits != null)
+ if (flowControl)
{
if ((precalculateAvailableCredits -= chunk.getRequiredBufferSize()) < 0)
{
@@ -861,15 +709,6 @@
}
}
- if (trace)
- {
- trace("deliverLargeMessage: Sending " + chunk.getRequiredBufferSize() +
- " availableCredits now is " +
- availableCredits +
- " isBackup = " +
- messageQueue.isBackup());
- }
-
channel.send(chunk);
positionPendingLargeMessage += chunkLen;
@@ -880,11 +719,6 @@
log.warn("Flowcontrol logic is not working properly... creidts = " + precalculateAvailableCredits);
}
- if (trace)
- {
- trace("Finished deliverLargeMessage isBackup = " + messageQueue.isBackup());
- }
-
close();
return true;
@@ -933,43 +767,33 @@
largeMessageDeliverer = null;
- pendingLargeMessagesCounter.decrementAndGet();
+ hasPendingLargeMessage = false;
}
/**
- * Credits flow control are calculated in advance.
+ * Credits flow control are calculated in advance. - WHY?
* @return
*/
- private int preCalculateFlowControl(SessionReceiveMessage firstPacket)
+ private int preCalculateFlowControl(final SessionReceiveMessage firstPacket)
{
- while (true)
+ final int currentCredit = availableCredits;
+ int precalculatedCredits = 0;
+
+ if (firstPacket != null)
{
- final int currentCredit = availableCredits.get();
- int precalculatedCredits = 0;
+ precalculatedCredits = firstPacket.getRequiredBufferSize();
+ }
- if (firstPacket != null)
- {
- precalculatedCredits = firstPacket.getRequiredBufferSize();
- }
+ long chunkLen = 0;
+ for (long i = positionPendingLargeMessage; precalculatedCredits < currentCredit && i < sizePendingLargeMessage; i += chunkLen)
+ {
+ chunkLen = (int)Math.min(sizePendingLargeMessage - i, minLargeMessageSize);
+ precalculatedCredits += chunkLen + SessionReceiveContinuationMessage.SESSION_RECEIVE_CONTINUATION_BASE_SIZE;
+ }
- long chunkLen = 0;
- for (long i = positionPendingLargeMessage; precalculatedCredits < currentCredit && i < sizePendingLargeMessage; i += chunkLen)
- {
- chunkLen = (int)Math.min(sizePendingLargeMessage - i, minLargeMessageSize);
- precalculatedCredits += chunkLen + SessionReceiveContinuationMessage.SESSION_RECEIVE_CONTINUATION_BASE_SIZE;
- }
+ availableCredits = currentCredit - precalculatedCredits;
- // The calculation of credits and taking credits out has to be taken atomically.
- // Since we are not sending anything to the client during this calculation, this is unlikely to happen
- if (availableCredits.compareAndSet(currentCredit, currentCredit - precalculatedCredits))
- {
- if (trace)
- {
- log.trace("Taking " + precalculatedCredits + " credits out on preCalculateFlowControl (largeMessage)");
- }
- return precalculatedCredits;
- }
- }
+ return precalculatedCredits;
}
private SessionReceiveContinuationMessage createChunkSend()
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/ServerSessionImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/ServerSessionImpl.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/ServerSessionImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -50,7 +50,6 @@
import org.jboss.messaging.core.remoting.impl.wireformat.MessagingExceptionMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.NullResponseMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl;
-import org.jboss.messaging.core.remoting.impl.wireformat.PacketsConfirmedMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.RollbackMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionAcknowledgeMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionBindingQueryMessage;
@@ -78,7 +77,6 @@
import org.jboss.messaging.core.remoting.impl.wireformat.SessionXASetTimeoutMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionXASetTimeoutResponseMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionXAStartMessage;
-import org.jboss.messaging.core.remoting.impl.wireformat.replication.SessionReplicateDeliveryMessage;
import org.jboss.messaging.core.remoting.spi.MessagingBuffer;
import org.jboss.messaging.core.security.CheckType;
import org.jboss.messaging.core.security.SecurityStore;
@@ -112,23 +110,12 @@
private static final Logger log = Logger.getLogger(ServerSessionImpl.class);
- private static final boolean trace = log.isTraceEnabled();
-
- private static void trace(String message)
- {
- log.trace(message);
- }
-
// Static -------------------------------------------------------------------------------
// Attributes ----------------------------------------------------------------------------
private volatile long id;
- // The id of the opposite channel - i.e. if this is the live then its the id on the backup, if this is the backup
- // then it's the id on the live, or -1 if non clustered
- private volatile long oppositeChannelID;
-
private final String username;
private final String password;
@@ -145,7 +132,7 @@
private RemotingConnection remotingConnection;
- private Channel replicatingChannel;
+ // private Channel replicatingChannel;
private final Map<Long, ServerConsumer> consumers = new ConcurrentHashMap<Long, ServerConsumer>();
@@ -181,8 +168,6 @@
private final SimpleString nodeID;
- private boolean backup;
-
// The current currentLargeMessage being processed
// In case of replication, currentLargeMessage should only be accessed within the replication callbacks
private volatile LargeServerMessage currentLargeMessage;
@@ -192,7 +177,7 @@
// Constructors ---------------------------------------------------------------------------------
public ServerSessionImpl(final String name,
- final long oppositeChannelID,
+ // final long oppositeChannelID,
final String username,
final String password,
final int minLargeMessageSize,
@@ -211,13 +196,14 @@
final ManagementService managementService,
final QueueFactory queueFactory,
final MessagingServer server,
- final SimpleString managementAddress,
- final Channel replicatingChannel,
- final boolean backup) throws Exception
+ final SimpleString managementAddress
+ // final Channel replicatingChannel,
+ // final boolean backup
+ ) throws Exception
{
this.id = channel.getID();
- this.oppositeChannelID = oppositeChannelID;
+ // this.oppositeChannelID = oppositeChannelID;
this.username = username;
@@ -264,10 +250,10 @@
this.nodeID = server.getNodeID();
- this.replicatingChannel = replicatingChannel;
+ // this.replicatingChannel = replicatingChannel;
- this.backup = backup;
-
+ // this.backup = backup;
+
remotingConnection.addFailureListener(this);
remotingConnection.addCloseListener(this);
@@ -363,505 +349,22 @@
queue.deliverAsync(executor);
}
- public void handleCreateConsumer(final SessionCreateConsumerMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleCreateConsumer(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleCreateConsumer(packet);
- }
- });
- }
- }
-
- public void handleCreateQueue(final CreateQueueMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleCreateQueue(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleCreateQueue(packet);
- }
- });
- }
- }
-
- public void handleDeleteQueue(final SessionDeleteQueueMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleDeleteQueue(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleDeleteQueue(packet);
- }
- });
- }
- }
-
- public void handleExecuteQueueQuery(final SessionQueueQueryMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleExecuteQueueQuery(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleExecuteQueueQuery(packet);
- }
- });
- }
- }
-
- public void handleExecuteBindingQuery(final SessionBindingQueryMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleExecuteBindingQuery(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleExecuteBindingQuery(packet);
- }
- });
- }
- }
-
- public void handleAcknowledge(final SessionAcknowledgeMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleAcknowledge(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleAcknowledge(packet);
- }
- });
- }
- }
-
- public void handleExpired(final SessionExpiredMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleExpired(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleExpired(packet);
- }
- });
- }
- }
-
- public void handleCommit(final Packet packet)
- {
- if (replicatingChannel == null)
- {
- doHandleCommit(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleCommit(packet);
- }
- });
- }
- }
-
- public void handleRollback(final RollbackMessage packet)
- {
-
- if (replicatingChannel == null)
- {
- doHandleRollback(packet);
- }
- else
- {
- final HashSet<Queue> queues = lockUsedQueues(null);
-
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- try
- {
- doHandleRollback(packet);
- }
- finally
- {
- for (Queue queue : queues)
- {
- queue.unlockDelivery();
- }
- }
- }
- });
- }
- }
-
- public void handleXACommit(final SessionXACommitMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleXACommit(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleXACommit(packet);
- }
- });
- }
- }
-
- public void handleXAEnd(final SessionXAEndMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleXAEnd(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleXAEnd(packet);
- }
- });
- }
- }
-
- public void handleXAForget(final SessionXAForgetMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleXAForget(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleXAForget(packet);
- }
- });
- }
- }
-
- public void handleXAJoin(final SessionXAJoinMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleXAJoin(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleXAJoin(packet);
- }
- });
- }
- }
-
- public void handleXAResume(final SessionXAResumeMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleXAResume(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleXAResume(packet);
- }
- });
- }
- }
-
- public void handleXARollback(final SessionXARollbackMessage packet)
- {
-
- if (replicatingChannel == null)
- {
- doHandleXARollback(packet);
- }
- else
- {
- final Set<Queue> queues = lockUsedQueues(packet.getXid());
-
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- try
- {
- doHandleXARollback(packet);
- }
- finally
- {
- for (Queue queue : queues)
- {
- queue.unlockDelivery();
- }
- }
- }
- });
- }
- }
-
- public void handleXAStart(final SessionXAStartMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleXAStart(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleXAStart(packet);
- }
- });
- }
- }
-
- public void handleXASuspend(final Packet packet)
- {
- if (replicatingChannel == null)
- {
- doHandleXASuspend(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleXASuspend(packet);
- }
- });
- }
- }
-
- public void handleXAPrepare(final SessionXAPrepareMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleXAPrepare(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleXAPrepare(packet);
- }
- });
- }
- }
-
- public void handleGetInDoubtXids(final Packet packet)
- {
- if (replicatingChannel == null)
- {
- doHandleGetInDoubtXids(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleGetInDoubtXids(packet);
- }
- });
- }
- }
-
- public void handleGetXATimeout(final Packet packet)
- {
- if (replicatingChannel == null)
- {
- doHandleGetXATimeout(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleGetXATimeout(packet);
- }
- });
- }
- }
-
- public void handleSetXATimeout(final SessionXASetTimeoutMessage packet)
- {
- if (replicatingChannel == null)
- {
- doHandleSetXATimeout(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doHandleSetXATimeout(packet);
- }
- });
- }
- }
-
- private void lockConsumers()
- {
- for (ServerConsumer consumer : consumers.values())
- {
- consumer.lock();
- }
- }
-
- private void unlockConsumers()
- {
- for (ServerConsumer consumer : consumers.values())
- {
- consumer.unlock();
- }
- }
-
public void handleStart(final Packet packet)
{
- if (replicatingChannel == null)
- {
- setStarted(true);
+ setStarted(true);
- channel.confirm(packet);
- }
- else
- {
- lockConsumers();
-
- try
- {
- setStarted(true);
-
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- // setStarted(true);
-
- channel.confirm(packet);
- }
- });
- }
- finally
- {
- unlockConsumers();
- }
- }
+ channel.confirm(packet);
}
public void handleStop(final Packet packet)
{
final Packet response = new NullResponseMessage();
- // We need to stop the session *before* replicating, to avoid this situation:
- // session stop,
- // stop is replicated
- // delivery occurs, local is not stopped yet
- // stop is processed on backup
- // backup is stopped
- // delivery is processed on backup
- // it's stopped so barfs and cannot process delivery
+ setStarted(false);
- if (replicatingChannel == null)
- {
- setStarted(false);
+ channel.confirm(packet);
- channel.confirm(packet);
-
- channel.send(response);
- }
- else
- {
- lockConsumers();
-
- try
- {
-
- setStarted(false);
-
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- channel.confirm(packet);
-
- channel.send(response);
-
- }
- });
- }
- finally
- {
- unlockConsumers();
- }
- }
+ channel.send(response);
}
public void handleFailedOver(final Packet packet)
@@ -874,112 +377,9 @@
}
}
- public void handleClose(final Packet packet)
- {
-
- if (replicatingChannel == null)
- {
- doHandleClose(packet);
- }
- else
- {
- final HashSet<Queue> queues = lockUsedQueues(null);
-
- // We need to stop the consumers first before replicating, to ensure no deliveries occur after this,
- // but we need to process the actual close() when the replication response returns, otherwise things
- // can happen like acks can come in after close
-
- for (ServerConsumer consumer : consumers.values())
- {
- consumer.setStarted(false);
- }
-
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- try
- {
- doHandleClose(packet);
- }
- finally
- {
- for (Queue queue : queues)
- {
- queue.unlockDelivery();
- }
- }
- }
- });
- }
- }
-
- public void handleCloseConsumer(final SessionConsumerCloseMessage packet)
- {
- final ServerConsumer consumer = consumers.get(packet.getConsumerID());
-
- consumer.setStarted(false);
-
- if (replicatingChannel == null)
- {
- doHandleCloseConsumer(packet, consumer);
- }
- else
- {
- final Queue queue;
-
- if (consumer.getCountOfPendingDeliveries() > 0)
- {
- queue = consumer.getQueue();
- queue.lockDelivery();
- }
- else
- {
- queue = null;
- }
-
- // We need to stop the consumer first before replicating, to ensure no deliveries occur after this,
- // but we need to process the actual close() when the replication response returns, otherwise things
- // can happen like acks can come in after close
-
- consumer.setStarted(false);
-
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- try
- {
- doHandleCloseConsumer(packet, consumer);
- }
- finally
- {
- if (queue != null)
- {
- queue.unlockDelivery();
- }
- }
- }
- });
- }
- }
-
public void handleReceiveConsumerCredits(final SessionConsumerFlowCreditMessage packet)
{
- if (replicatingChannel == null)
- {
- doReceiveCredits(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doReceiveCredits(packet);
- }
- });
- }
+ doReceiveCredits(packet);
}
public void handleSendLargeMessage(final SessionSendLargeMessage packet)
@@ -996,236 +396,24 @@
// With a send we must make sure it is replicated to backup before being processed on live
// or can end up with delivery being processed on backup before original send
- if (replicatingChannel == null)
+ if (currentLargeMessage != null)
{
- if (currentLargeMessage != null)
- {
- log.warn("Replacing incomplete LargeMessage with ID=" + currentLargeMessage.getMessageID());
- }
-
- currentLargeMessage = msg;
-
- doSendLargeMessage(packet);
+ log.warn("Replacing incomplete LargeMessage with ID=" + currentLargeMessage.getMessageID());
}
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- if (trace)
- {
- trace("(Replication) SendLargeMessage, id=" + msg.getMessageID());
- }
- if (currentLargeMessage != null)
- {
- log.warn("Replacing incomplete LargeMessage with ID=" + currentLargeMessage.getMessageID());
- }
+ currentLargeMessage = msg;
- currentLargeMessage = msg;
-
- doSendLargeMessage(packet);
- }
- });
- }
+ doSendLargeMessage(packet);
}
- public void handleSend(final SessionSendMessage packet)
+ public void handleCloseConsumer(final SessionConsumerCloseMessage packet)
{
- if (replicatingChannel == null)
- {
- doSend(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doSend(packet);
- }
- });
- }
- }
-
- public void handleSendContinuations(final SessionSendContinuationMessage packet)
- {
- if (replicatingChannel == null)
- {
- doSendContinuations(packet);
- }
- else
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, new Runnable()
- {
- public void run()
- {
- doSendContinuations(packet);
- }
- });
- }
- }
-
- public void handleReplicatedDelivery(final SessionReplicateDeliveryMessage packet)
- {
- ServerConsumer consumer = consumers.get(packet.getConsumerID());
-
- if (consumer == null)
- {
- throw new IllegalStateException("Cannot handle replicated delivery, consumer is closed " + packet.getConsumerID() +
- " session " +
- id +
- " " +
- System.identityHashCode(this));
- }
-
- try
- {
- consumer.deliverReplicated(packet.getMessageID());
- }
- catch (Exception e)
- {
- log.error("Failed to handle replicated delivery", e);
- }
- }
-
- public void handlePacketsConfirmed(final PacketsConfirmedMessage packet)
- {
- if (replicatingChannel != null)
- {
- replicatingChannel.replicatePacket(packet, oppositeChannelID, null);
- }
- }
-
- public int transferConnection(final RemotingConnection newConnection, final int lastReceivedCommandID)
- {
- boolean wasStarted = this.started;
-
- if (wasStarted)
- {
- this.setStarted(false);
- }
-
- if (backup)
- {
- // Put the id back to the original client session id
- this.id = this.oppositeChannelID;
-
- this.oppositeChannelID = -1;
-
- backup = false;
- }
-
- remotingConnection.removeFailureListener(this);
- remotingConnection.removeCloseListener(this);
-
- // Note. We do not destroy the replicating connection here. In the case the live server has really crashed
- // then the connection will get cleaned up anyway when the server ping timeout kicks in.
- // In the case the live server is really still up, i.e. a split brain situation (or in tests), then closing
- // the replicating connection will cause the outstanding responses to be be replayed on the live server,
- // if these reach the client who then subsequently fails over, on reconnection to backup, it will have
- // received responses that the backup did not know about.
-
- channel.transferConnection(newConnection, this.id, replicatingChannel);
-
- newConnection.syncIDGeneratorSequence(remotingConnection.getIDGeneratorSequence());
-
- remotingConnection = newConnection;
-
- remotingConnection.addFailureListener(this);
- remotingConnection.addCloseListener(this);
-
- int serverLastReceivedCommandID = channel.getLastReceivedCommandID();
-
- channel.replayCommands(lastReceivedCommandID, this.id);
-
- if (wasStarted)
- {
- this.setStarted(true);
- }
-
- return serverLastReceivedCommandID;
- }
-
- public Channel getChannel()
- {
- return channel;
- }
-
- // FailureListener implementation
- // --------------------------------------------------------------------
-
- public boolean connectionFailed(final MessagingException me)
- {
- try
- {
- log.warn("Client connection failed, clearing up resources for session " + name);
-
- for (Runnable runner : failureRunners)
- {
- try
- {
- runner.run();
- }
- catch (Throwable t)
- {
- log.error("Failed to execute failure runner", t);
- }
- }
-
- handleClose(new PacketImpl(PacketImpl.SESS_CLOSE));
-
- log.warn("Cleared up resources for session " + name);
- }
- catch (Throwable t)
- {
- log.error("Failed to close connection " + this);
- }
-
- return true;
- }
-
- public void connectionClosed()
- {
- try
- {
- for (Runnable runner : failureRunners)
- {
- try
- {
- runner.run();
- }
- catch (Throwable t)
- {
- log.error("Failed to execute failure runner", t);
- }
- }
- }
- catch (Throwable t)
- {
- log.error("Failed fire listeners " + this);
- }
-
- }
-
- // Public
- // ----------------------------------------------------------------------------
-
- public Transaction getTransaction()
- {
- return tx;
- }
-
- // Private
- // ----------------------------------------------------------------------------
-
- private void doHandleCloseConsumer(final SessionConsumerCloseMessage packet, final ServerConsumer consumer)
- {
Packet response;
try
{
+ final ServerConsumer consumer = consumers.get(packet.getConsumerID());
+
consumer.close();
response = new NullResponseMessage();
@@ -1249,7 +437,7 @@
channel.send(response);
}
- private void doHandleCreateConsumer(final SessionCreateConsumerMessage packet)
+ public void handleCreateConsumer(final SessionCreateConsumerMessage packet)
{
SimpleString name = packet.getQueueName();
@@ -1263,6 +451,8 @@
{
Binding binding = postOffice.getBinding(name);
+ log.info("binding is " + binding);
+
if (binding == null || binding.getType() != BindingType.LOCAL_QUEUE)
{
throw new MessagingException(MessagingException.QUEUE_DOES_NOT_EXIST, "Binding " + name + " does not exist");
@@ -1284,7 +474,12 @@
// We consume a copy of the queue - TODO - this is a temporary measure
// and will disappear once we can provide a proper iterator on the queue
- theQueue = queueFactory.createQueue(-1, binding.getAddress(), name, filter, false, true);
+ theQueue = queueFactory.createQueue(storageManager.generateUniqueID(),
+ binding.getAddress(),
+ name,
+ filter,
+ false,
+ true);
// There's no need for any special locking since the list method is synchronized
List<MessageReference> refs = ((Queue)binding.getBindable()).list(filter);
@@ -1301,8 +496,9 @@
theQueue = (Queue)binding.getBindable();
}
+ log.info("*********** creating consumer");
+
ServerConsumer consumer = new ServerConsumerImpl(idGenerator.generateID(),
- oppositeChannelID,
this,
(QueueBinding)binding,
filter,
@@ -1311,7 +507,6 @@
storageManager,
postOffice.getPagingManager(),
channel,
- replicatingChannel,
preAcknowledge,
updateDeliveries,
executor,
@@ -1362,11 +557,11 @@
channel.confirm(packet);
channel.send(response);
-
}
- private void doHandleCreateQueue(final CreateQueueMessage packet)
+ public void handleCreateQueue(final CreateQueueMessage packet)
{
+ log.info("processing create queue");
SimpleString address = packet.getAddress();
final SimpleString name = packet.getQueueName();
@@ -1406,7 +601,7 @@
public void run()
{
try
- {
+ {
if (postOffice.getBinding(name) != null)
{
postOffice.removeBinding(name);
@@ -1424,6 +619,8 @@
}
catch (Exception e)
{
+ log.error("Failed to process action", e);
+
if (e instanceof MessagingException)
{
response = new MessagingExceptionMessage((MessagingException)e);
@@ -1437,9 +634,11 @@
channel.confirm(packet);
channel.send(response);
+
+ log.info("processed create queue");
}
- private void doHandleDeleteQueue(final SessionDeleteQueueMessage packet)
+ public void handleDeleteQueue(final SessionDeleteQueueMessage packet)
{
SimpleString name = packet.getQueueName();
@@ -1477,7 +676,7 @@
channel.send(response);
}
- private void doHandleExecuteQueueQuery(final SessionQueueQueryMessage packet)
+ public void handleExecuteQueueQuery(final SessionQueueQueryMessage packet)
{
SimpleString name = packet.getQueueName();
@@ -1530,7 +729,7 @@
channel.send(response);
}
- private void doHandleExecuteBindingQuery(final SessionBindingQueryMessage packet)
+ public void handleExecuteBindingQuery(final SessionBindingQueryMessage packet)
{
SimpleString address = packet.getAddress();
@@ -1576,7 +775,7 @@
channel.send(response);
}
- private void doHandleAcknowledge(final SessionAcknowledgeMessage packet)
+ public void handleAcknowledge(final SessionAcknowledgeMessage packet)
{
Packet response = null;
@@ -1616,7 +815,7 @@
}
}
- private void doHandleExpired(final SessionExpiredMessage packet)
+ public void handleExpired(final SessionExpiredMessage packet)
{
try
{
@@ -1636,7 +835,7 @@
channel.confirm(packet);
}
- private void doHandleCommit(final Packet packet)
+ public void handleCommit(final Packet packet)
{
Packet response = null;
@@ -1669,7 +868,7 @@
channel.send(response);
}
- private void doHandleRollback(final RollbackMessage packet)
+ public void handleRollback(final RollbackMessage packet)
{
Packet response = null;
@@ -1698,7 +897,7 @@
channel.send(response);
}
- private void doHandleXACommit(final SessionXACommitMessage packet)
+ public void handleXACommit(final SessionXACommitMessage packet)
{
Packet response = null;
@@ -1761,7 +960,7 @@
channel.send(response);
}
- private void doHandleXAEnd(final SessionXAEndMessage packet)
+ public void handleXAEnd(final SessionXAEndMessage packet)
{
Packet response = null;
@@ -1835,7 +1034,7 @@
channel.send(response);
}
- private void doHandleXAForget(final SessionXAForgetMessage packet)
+ public void handleXAForget(final SessionXAForgetMessage packet)
{
// Do nothing since we don't support heuristic commits / rollback from the
// resource manager
@@ -1847,7 +1046,7 @@
channel.send(response);
}
- private void doHandleXAJoin(final SessionXAJoinMessage packet)
+ public void handleXAJoin(final SessionXAJoinMessage packet)
{
Packet response = null;
@@ -1898,7 +1097,7 @@
channel.send(response);
}
- private void doHandleXAResume(final SessionXAResumeMessage packet)
+ public void handleXAResume(final SessionXAResumeMessage packet)
{
Packet response = null;
@@ -1960,7 +1159,7 @@
channel.send(response);
}
- private void doHandleXARollback(final SessionXARollbackMessage packet)
+ public void handleXARollback(final SessionXARollbackMessage packet)
{
Packet response = null;
@@ -2023,7 +1222,7 @@
channel.send(response);
}
- private void doHandleXAStart(final SessionXAStartMessage packet)
+ public void handleXAStart(final SessionXAStartMessage packet)
{
Packet response = null;
@@ -2074,7 +1273,7 @@
channel.send(response);
}
- private void doHandleXASuspend(final Packet packet)
+ public void handleXASuspend(final Packet packet)
{
Packet response = null;
@@ -2123,7 +1322,7 @@
channel.send(response);
}
- private void doHandleXAPrepare(final SessionXAPrepareMessage packet)
+ public void handleXAPrepare(final SessionXAPrepareMessage packet)
{
Packet response = null;
@@ -2183,7 +1382,7 @@
channel.send(response);
}
- private void doHandleGetInDoubtXids(final Packet packet)
+ public void handleGetInDoubtXids(final Packet packet)
{
Packet response = new SessionXAGetInDoubtXidsResponseMessage(resourceManager.getPreparedTransactions());
@@ -2192,7 +1391,7 @@
channel.send(response);
}
- private void doHandleGetXATimeout(final Packet packet)
+ public void handleGetXATimeout(final Packet packet)
{
Packet response = new SessionXAGetTimeoutResponseMessage(resourceManager.getTimeoutSeconds());
@@ -2201,7 +1400,7 @@
channel.send(response);
}
- private void doHandleSetXATimeout(final SessionXASetTimeoutMessage packet)
+ public void handleSetXATimeout(final SessionXASetTimeoutMessage packet)
{
Packet response = new SessionXASetTimeoutResponseMessage(resourceManager.setTimeoutSeconds(packet.getTimeoutSeconds()));
@@ -2210,113 +1409,12 @@
channel.send(response);
}
- private void doHandleClose(final Packet packet)
+ public void handleSend(final SessionSendMessage packet)
{
Packet response = null;
try
{
- close();
-
- response = new NullResponseMessage();
- }
- catch (Exception e)
- {
- log.error("Failed to close", e);
-
- if (e instanceof MessagingException)
- {
- response = new MessagingExceptionMessage((MessagingException)e);
- }
- else
- {
- response = new MessagingExceptionMessage(new MessagingException(MessagingException.INTERNAL_ERROR));
- }
- }
-
- channel.confirm(packet);
-
- // We flush the confirmations to make sure any send confirmations get handled on the client side
- channel.flushConfirmations();
-
- channel.send(response);
-
- channel.close();
- }
-
- private void setStarted(final boolean s)
- {
- Set<ServerConsumer> consumersClone = new HashSet<ServerConsumer>(consumers.values());
-
- for (ServerConsumer consumer : consumersClone)
- {
- consumer.setStarted(s);
- }
-
- started = s;
- }
-
- /**
- * We need to create the LargeMessage before replicating the packet, or else we won't know how to extract the destination,
- * which is stored on the header
- * @param packet
- * @throws Exception
- */
- private LargeServerMessage doCreateLargeMessage(final SessionSendLargeMessage packet)
- {
- try
- {
- return createLargeMessageStorage(packet.getLargeMessageHeader());
- }
- catch (Exception e)
- {
- log.error("Failed to create large message", e);
- Packet response = null;
-
- channel.confirm(packet);
- if (response != null)
- {
- channel.send(response);
- }
- return null;
- }
- }
-
- private void doReceiveCredits(final SessionConsumerFlowCreditMessage packet)
- {
- try
- {
- consumers.get(packet.getConsumerID()).receiveCredits(packet.getCredits());
- }
- catch (Exception e)
- {
- log.error("Failed to receive credits", e);
- }
- channel.confirm(packet);
- }
-
- private void doSendLargeMessage(final SessionSendLargeMessage packet)
- {
- try
- {
- long id = storageManager.generateUniqueID();
-
- currentLargeMessage.setMessageID(id);
- }
- catch (Exception e)
- {
- log.error("Failed to send message", e);
- }
-
- channel.confirm(packet);
- }
-
- private void doSend(final SessionSendMessage packet)
- {
- Packet response = null;
-
- try
- {
ServerMessage message = packet.getServerMessage();
long id = storageManager.generateUniqueID();
@@ -2367,7 +1465,7 @@
/**
* @param packet
*/
- private void doSendContinuations(final SessionSendContinuationMessage packet)
+ public void handleSendContinuations(final SessionSendContinuationMessage packet)
{
Packet response = null;
@@ -2421,6 +1519,234 @@
}
}
+ public void handleClose(final Packet packet)
+ {
+ Packet response = null;
+
+ try
+ {
+ close();
+
+ response = new NullResponseMessage();
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to close", e);
+
+ if (e instanceof MessagingException)
+ {
+ response = new MessagingExceptionMessage((MessagingException)e);
+ }
+ else
+ {
+ response = new MessagingExceptionMessage(new MessagingException(MessagingException.INTERNAL_ERROR));
+ }
+ }
+
+ channel.confirm(packet);
+
+ // We flush the confirmations to make sure any send confirmations get handled on the client side
+ channel.flushConfirmations();
+
+ channel.send(response);
+
+ channel.close();
+ }
+
+ public int transferConnection(final RemotingConnection newConnection, final int lastReceivedCommandID)
+ {
+ boolean wasStarted = this.started;
+
+ if (wasStarted)
+ {
+ this.setStarted(false);
+ }
+
+ // backup = false;
+
+ remotingConnection.removeFailureListener(this);
+ remotingConnection.removeCloseListener(this);
+
+ // Note. We do not destroy the replicating connection here. In the case the live server has really crashed
+ // then the connection will get cleaned up anyway when the server ping timeout kicks in.
+ // In the case the live server is really still up, i.e. a split brain situation (or in tests), then closing
+ // the replicating connection will cause the outstanding responses to be be replayed on the live server,
+ // if these reach the client who then subsequently fails over, on reconnection to backup, it will have
+ // received responses that the backup did not know about.
+
+ channel.transferConnection(newConnection);
+
+ newConnection.syncIDGeneratorSequence(remotingConnection.getIDGeneratorSequence());
+
+ remotingConnection = newConnection;
+
+ remotingConnection.addFailureListener(this);
+ remotingConnection.addCloseListener(this);
+
+ int serverLastReceivedCommandID = channel.getLastReceivedCommandID();
+
+ channel.replayCommands(lastReceivedCommandID);
+
+ if (wasStarted)
+ {
+ this.setStarted(true);
+ }
+
+ return serverLastReceivedCommandID;
+ }
+
+ public Channel getChannel()
+ {
+ return channel;
+ }
+
+ // FailureListener implementation
+ // --------------------------------------------------------------------
+
+ public boolean connectionFailed(final MessagingException me)
+ {
+ try
+ {
+ log.warn("Client connection failed, clearing up resources for session " + name);
+
+ for (Runnable runner : failureRunners)
+ {
+ try
+ {
+ runner.run();
+ }
+ catch (Throwable t)
+ {
+ log.error("Failed to execute failure runner", t);
+ }
+ }
+
+ handleClose(new PacketImpl(PacketImpl.SESS_CLOSE));
+
+ log.warn("Cleared up resources for session " + name);
+ }
+ catch (Throwable t)
+ {
+ log.error("Failed to close connection " + this);
+ }
+
+ return true;
+ }
+
+ public void connectionClosed()
+ {
+ try
+ {
+ for (Runnable runner : failureRunners)
+ {
+ try
+ {
+ runner.run();
+ }
+ catch (Throwable t)
+ {
+ log.error("Failed to execute failure runner", t);
+ }
+ }
+ }
+ catch (Throwable t)
+ {
+ log.error("Failed fire listeners " + this);
+ }
+
+ }
+
+ // Public
+ // ----------------------------------------------------------------------------
+
+ public Transaction getTransaction()
+ {
+ return tx;
+ }
+
+ // Private
+ // ----------------------------------------------------------------------------
+
+ private void setStarted(final boolean s)
+ {
+ Set<ServerConsumer> consumersClone = new HashSet<ServerConsumer>(consumers.values());
+
+ for (ServerConsumer consumer : consumersClone)
+ {
+ consumer.setStarted(s);
+ }
+
+ started = s;
+ }
+
+ /**
+ * We need to create the LargeMessage before replicating the packet, or else we won't know how to extract the destination,
+ * which is stored on the header
+ * @param packet
+ * @throws Exception
+ */
+ private LargeServerMessage doCreateLargeMessage(final SessionSendLargeMessage packet)
+ {
+ try
+ {
+ LargeServerMessage largeMessage = storageManager.createLargeMessage();
+
+ MessagingBuffer headerBuffer = ChannelBuffers.wrappedBuffer(packet.getLargeMessageHeader());
+
+ largeMessage.decodeProperties(headerBuffer);
+
+ return largeMessage;
+ }
+ catch (Exception e)
+ {
+ Packet response = null;
+
+ channel.confirm(packet);
+
+ if (response != null)
+ {
+ channel.send(response);
+ }
+
+ return null;
+ }
+ }
+
+ private void doReceiveCredits(final SessionConsumerFlowCreditMessage packet)
+ {
+ try
+ {
+ log.info("packet consumer id is "+ packet.getConsumerID());
+
+ ServerConsumer consumer = consumers.get(packet.getConsumerID());
+
+ log.info("consumer is " + consumer);
+
+ consumer.receiveCredits(packet.getCredits());
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to receive credits", e);
+ }
+ channel.confirm(packet);
+ }
+
+ private void doSendLargeMessage(final SessionSendLargeMessage packet)
+ {
+ try
+ {
+ long id = storageManager.generateUniqueID();
+
+ currentLargeMessage.setMessageID(id);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to send message", e);
+ }
+
+ channel.confirm(packet);
+ }
+
private void handleManagementMessage(final ServerMessage message) throws Exception
{
try
@@ -2448,17 +1774,6 @@
}
}
- private LargeServerMessage createLargeMessageStorage(final byte[] header) throws Exception
- {
- LargeServerMessage largeMessage = storageManager.createLargeMessage();
-
- MessagingBuffer headerBuffer = ChannelBuffers.wrappedBuffer(header);
-
- largeMessage.decodeProperties(headerBuffer);
-
- return largeMessage;
- }
-
private void doRollback(final boolean lastMessageAsDelived, final Transaction theTx) throws Exception
{
boolean wasStarted = started;
@@ -2530,39 +1845,4 @@
postOffice.route(msg, tx);
}
}
-
- /**
- * We need to avoid delivery when rolling back while doing replication, or the backup node could be on a different order
- * @return
- */
- private HashSet<Queue> lockUsedQueues(Xid xid)
- {
- final HashSet<Queue> queues = new HashSet<Queue>();
-
- for (ServerConsumer consumer : consumers.values())
- {
- queues.add(consumer.getQueue());
- }
-
- Transaction localTX;
- if (xid == null)
- {
- localTX = tx;
- }
- else
- {
- localTX = resourceManager.getTransaction(xid);
- }
-
- if (localTX != null)
- {
- queues.addAll(localTX.getDistinctQueues());
- }
-
- for (Queue queue : queues)
- {
- queue.lockDelivery();
- }
- return queues;
- }
}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/ServerSessionPacketHandler.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/ServerSessionPacketHandler.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/impl/ServerSessionPacketHandler.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -14,6 +14,7 @@
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.CREATE_QUEUE;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.DELETE_QUEUE;
+import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.REPLICATE_LOCK_SEQUENCES;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_ACKNOWLEDGE;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_BINDINGQUERY;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_CLOSE;
@@ -24,7 +25,6 @@
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_FAILOVER_COMPLETE;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_FLOWTOKEN;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_QUEUEQUERY;
-import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_REPLICATE_DELIVERY;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_ROLLBACK;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_SEND;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_SEND_CONTINUATION;
@@ -44,12 +44,15 @@
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_XA_START;
import static org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl.SESS_XA_SUSPEND;
+import java.util.List;
+
+import org.jboss.messaging.core.config.Configuration;
import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.core.remoting.Channel;
import org.jboss.messaging.core.remoting.ChannelHandler;
import org.jboss.messaging.core.remoting.Packet;
import org.jboss.messaging.core.remoting.impl.wireformat.CreateQueueMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.PacketImpl;
-import org.jboss.messaging.core.remoting.impl.wireformat.PacketsConfirmedMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.RollbackMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionAcknowledgeMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionBindingQueryMessage;
@@ -71,8 +74,13 @@
import org.jboss.messaging.core.remoting.impl.wireformat.SessionXARollbackMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionXASetTimeoutMessage;
import org.jboss.messaging.core.remoting.impl.wireformat.SessionXAStartMessage;
-import org.jboss.messaging.core.remoting.impl.wireformat.replication.SessionReplicateDeliveryMessage;
+import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateLockSequenceMessage;
+import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicationResponseMessage;
import org.jboss.messaging.core.server.ServerSession;
+import org.jboss.messaging.core.server.replication.ReplicableAction;
+import org.jboss.messaging.core.server.replication.Replicator;
+import org.jboss.messaging.core.server.replication.impl.JBMThread;
+import org.jboss.messaging.utils.Pair;
/**
* A ServerSessionPacketHandler
@@ -81,33 +89,112 @@
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
* @author <a href="mailto:andy.taylor at jboss.org>Andy Taylor</a>
*/
-public class ServerSessionPacketHandler implements ChannelHandler
+public class ServerSessionPacketHandler implements ChannelHandler, ReplicableAction
{
private static final Logger log = Logger.getLogger(ServerSessionPacketHandler.class);
private final ServerSession session;
-
- public ServerSessionPacketHandler(final ServerSession session)
+
+ private final Replicator replicator;
+
+ private Packet packet;
+
+ //private boolean backup;
+
+ private Configuration config;
+
+ private List<Pair<Long, Integer>> sequences;
+
+ private final Channel channel;
+
+ public ServerSessionPacketHandler(final ServerSession session, final Replicator replicator, final Configuration config)
{
this.session = session;
+
+ this.replicator = replicator;
+
+ this.channel = session.getChannel();
+
+ this.config = config;
}
public long getID()
{
return session.getID();
}
-
+
+ public void run()
+ {
+ handlePacket();
+ }
+
+ public Packet getPacket()
+ {
+ return packet;
+ }
+
public void handlePacket(final Packet packet)
{
+ this.packet = packet;
+
+ log.info(System.identityHashCode(this)+ " Handling packet " + packet.getType() + " on backup " + config.isBackup());
+
+ if (config.isBackup())
+ {
+ JBMThread thread = JBMThread.currentThread();
+
+ thread.setReplay(sequences);
+
+ // thread.setReplay(true);
+
+ handlePacket();
+
+ //send the response message
+
+ if (packet.getType() != PacketImpl.REPLICATE_LOCK_SEQUENCES)
+ {
+ channel.send(new ReplicationResponseMessage());
+ }
+ }
+ else
+ {
+ if (replicator != null)
+ {
+ replicator.execute(this);
+ }
+ else
+ {
+ log.info("replicator is null");
+ handlePacket();
+ }
+ }
+ }
+
+ private void dumpSequences(List<Pair<Long, Integer>> sequences)
+ {
+ log.info("Sequences size is " + sequences.size());
+ for (Pair<Long, Integer> pair: sequences)
+ {
+ log.info(pair.a + ": " + pair.b);
+ }
+ }
+
+ private void handlePacket()
+ {
byte type = packet.getType();
try
{
switch (type)
{
- case PacketImpl.PACKETS_CONFIRMED:
+ case REPLICATE_LOCK_SEQUENCES:
{
- session.handlePacketsConfirmed((PacketsConfirmedMessage)packet);
+ ReplicateLockSequenceMessage msg = (ReplicateLockSequenceMessage)packet;
+ sequences = msg.getSequences();
+
+ log.info("Session, set sequences");
+ dumpSequences(sequences);
+
break;
}
case SESS_CREATECONSUMER:
@@ -118,6 +205,7 @@
}
case CREATE_QUEUE:
{
+ log.info("Got create queue message");
CreateQueueMessage request = (CreateQueueMessage)packet;
session.handleCreateQueue(request);
break;
@@ -281,12 +369,6 @@
session.handleSendContinuations(message);
break;
}
- case SESS_REPLICATE_DELIVERY:
- {
- SessionReplicateDeliveryMessage message = (SessionReplicateDeliveryMessage)packet;
- session.handleReplicatedDelivery(message);
- break;
- }
}
}
catch (Throwable t)
Added: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/ReplicableAction.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/ReplicableAction.java (rev 0)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/ReplicableAction.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+
+package org.jboss.messaging.core.server.replication;
+
+import org.jboss.messaging.core.remoting.Packet;
+
+/**
+ * A ReplicableAction
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ *
+ */
+public interface ReplicableAction extends Runnable
+{
+ Packet getPacket();
+}
Added: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/Replicator.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/Replicator.java (rev 0)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/Replicator.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -0,0 +1,45 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+
+package org.jboss.messaging.core.server.replication;
+
+import org.jboss.messaging.core.remoting.Channel;
+
+
+/**
+ * A Replicator
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ *
+ */
+public interface Replicator
+{
+ void execute(ReplicableAction action);
+
+ void registerWaitingChannel(Channel channel);
+
+ boolean isResponseReceived();
+
+ void replicationResponseReceived();
+}
Added: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/JBMThread.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/JBMThread.java (rev 0)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/JBMThread.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -0,0 +1,134 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.messaging.core.server.replication.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.messaging.core.server.replication.Replicator;
+import org.jboss.messaging.utils.Pair;
+
+/**
+ * A JBMThread
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ *
+ */
+public class JBMThread extends Thread
+{
+ private static enum ThreadState
+ {
+ RECORD, REPLAY, END_RECORD;
+ }
+
+ private ThreadState state;
+
+ private List<Pair<Long, Integer>> objectSequences;
+
+ private int pos;
+
+ private Replicator replicator;
+
+ public static JBMThread currentThread()
+ {
+ return (JBMThread)Thread.currentThread();
+ }
+
+ public JBMThread(final ThreadGroup threadGroup, final String name)
+ {
+ super(threadGroup, name);
+ }
+
+ public JBMThread(final ThreadGroup threadGroup, final Runnable target, final String name)
+ {
+ super(threadGroup, target, name);
+ }
+
+ public boolean isReplay()
+ {
+ return state == ThreadState.REPLAY;
+ }
+
+ public boolean isRecording()
+ {
+ return state == ThreadState.RECORD;
+ }
+
+ public void setReplay(final List<Pair<Long, Integer>> objectSequences)
+ {
+ this.objectSequences = objectSequences;
+
+ this.state = ThreadState.REPLAY;
+
+ this.pos = 0;
+ }
+
+ public void setRecord(final Replicator replicator)
+ {
+ if (this.objectSequences == null)
+ {
+ this.objectSequences = new ArrayList<Pair<Long, Integer>>();
+ }
+ else
+ {
+ this.objectSequences.clear();
+ }
+
+ this.state = ThreadState.RECORD;
+
+ this.pos = 0;
+
+ this.replicator = replicator;
+ }
+
+ public void endRecord()
+ {
+ this.state = ThreadState.END_RECORD;
+ }
+
+ public Pair<Long, Integer> getNextSequence()
+ {
+ return objectSequences.get(pos++);
+ }
+
+ public void addSequence(final Pair<Long, Integer> currentSequence)
+ {
+ objectSequences.add(currentSequence);
+ }
+
+ public List<Pair<Long, Integer>> getSequences()
+ {
+ return objectSequences;
+ }
+
+ public Replicator getReplicator()
+ {
+ return replicator;
+ }
+
+ public void setReplicator(final Replicator replicator)
+ {
+ this.replicator = replicator;
+ }
+}
Added: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/PriorityLock.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/PriorityLock.java (rev 0)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/PriorityLock.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -0,0 +1,138 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.messaging.core.server.replication.impl;
+
+import java.util.PriorityQueue;
+import java.util.Queue;
+import java.util.concurrent.locks.LockSupport;
+
+import org.jboss.messaging.core.logging.Logger;
+
+/**
+ * A PriorityLock
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ *
+ */
+public class PriorityLock
+{
+ private static final Logger log = Logger.getLogger(PriorityLock.class);
+
+ private final Queue<QueueEntry> waiting;
+
+ private volatile int currentSequence;
+
+ private Thread owner;
+
+ public PriorityLock(final int sequence)
+ {
+ waiting = new PriorityQueue<QueueEntry>();
+
+ this.currentSequence = sequence;
+ }
+
+ public void lock(final int sequence)
+ {
+ //log.info(this + " trying to get lock on backup " + sequence);
+
+ Thread currentThread = Thread.currentThread();
+
+ if (sequence != currentSequence)
+ {
+ QueueEntry entry = new QueueEntry(sequence, currentThread);
+
+ synchronized (waiting)
+ {
+ waiting.add(entry);
+ }
+
+ while (sequence != currentSequence)
+ {
+ log.info("parking lock, expected " + sequence + " current " + currentSequence);
+ LockSupport.park();
+ }
+ }
+
+ owner = currentThread;
+
+ //log.info(this + " got lock om backup " + sequence, new Exception());
+ }
+
+ public void unlock()
+ {
+ if (owner != Thread.currentThread())
+ {
+ throw new IllegalMonitorStateException();
+ }
+
+ currentSequence++;
+
+ QueueEntry entry;
+
+ synchronized (waiting)
+ {
+ entry = waiting.peek();
+
+ if (entry != null && entry.thread == owner)
+ {
+ waiting.poll();
+ }
+
+ entry = waiting.peek();
+
+ log.info("size " + waiting.size());
+ }
+
+ if (entry != null)
+ {
+ LockSupport.unpark(entry.thread);
+ }
+ }
+
+ private static final class QueueEntry implements Comparable<QueueEntry>
+ {
+ private final int sequence;
+
+ private final Thread thread;
+
+ private QueueEntry(final int sequence, final Thread thread)
+ {
+ this.sequence = sequence;
+
+ if (thread == null)
+ {
+ throw new NullPointerException("Null thread");
+ }
+
+ this.thread = thread;
+ }
+
+ public int compareTo(final QueueEntry entry)
+ {
+ int i = entry.sequence;
+
+ return sequence < i ? -1 : (sequence == i ? 0 : 1);
+ }
+ }
+}
Added: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/ReplicatorImpl.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/ReplicatorImpl.java (rev 0)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/ReplicatorImpl.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -0,0 +1,128 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.messaging.core.server.replication.impl;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.core.remoting.Channel;
+import org.jboss.messaging.core.remoting.Packet;
+import org.jboss.messaging.core.remoting.impl.wireformat.replication.ReplicateLockSequenceMessage;
+import org.jboss.messaging.core.server.replication.ReplicableAction;
+import org.jboss.messaging.core.server.replication.Replicator;
+import org.jboss.messaging.utils.Pair;
+
+/**
+ * A ReplicatorImpl
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ *
+ */
+public class ReplicatorImpl implements Replicator
+{
+ private static final Logger log = Logger.getLogger(ReplicatorImpl.class);
+
+ private Channel replicatingChannel;
+
+ private Set<Channel> waitingChannels = new HashSet<Channel>();
+
+ private boolean responseReceived;
+
+ public ReplicatorImpl(final Channel replicatingChannel)
+ {
+ this.replicatingChannel = replicatingChannel;
+ }
+
+ public void registerWaitingChannel(final Channel channel)
+ {
+ this.waitingChannels.add(channel);
+ }
+
+ public synchronized void replicationResponseReceived()
+ {
+ log.info("** got replication response in replicator");
+
+ for (Channel channel : waitingChannels)
+ {
+ channel.replicationResponseReceived(this);
+ }
+
+ responseReceived = true;
+ }
+
+ public synchronized boolean isResponseReceived()
+ {
+ return responseReceived;
+ }
+
+ public void execute(final ReplicableAction action)
+ {
+ // First we execute the action
+
+ log.info("Running action locally");
+
+ JBMThread thread = JBMThread.currentThread();
+
+ //List<Pair<Long, Integer>> sequences = new ArrayList<Pair<Long, Integer>>();
+
+ thread.setRecord(this);
+
+ action.run();
+
+ thread.endRecord();
+
+ log.info("Ran action locally");
+
+ List<Pair<Long, Integer>> sequences = JBMThread.currentThread().getSequences();
+
+ dumpSequences(sequences);
+
+ // We then send the sequences to the backup
+
+ log.info("Replicated sequences");
+
+ Packet packet = new ReplicateLockSequenceMessage(sequences);
+
+ replicatingChannel.send(packet);
+
+ // Next we replicate the actual action
+
+ replicatingChannel.send(action.getPacket());
+
+ log.info("replicated packet " + action.getPacket().getType());
+ }
+
+ private void dumpSequences(List<Pair<Long, Integer>> sequences)
+ {
+ log.info("Sequences size is " + sequences.size());
+ for (Pair<Long, Integer> pair: sequences)
+ {
+ log.info(pair.a + ": " + pair.b);
+ }
+ }
+
+}
Added: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/StatefulObjectReadWriteLock.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/StatefulObjectReadWriteLock.java (rev 0)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/core/server/replication/impl/StatefulObjectReadWriteLock.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -0,0 +1,243 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.messaging.core.server.replication.impl;
+
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.utils.ConcurrentHashSet;
+import org.jboss.messaging.utils.Pair;
+
+/**
+ * A StatefulObjectReadWriteLock
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ *
+ */
+public class StatefulObjectReadWriteLock implements ReadWriteLock
+{
+ private static final Logger log = Logger.getLogger(StatefulObjectReadWriteLock.class);
+
+ private final Lock readLock = new StatefulObjectReadLock();
+
+ private final Lock writeLock = new StatefulObjectWriteLock();
+
+ private long objectID;
+
+ private final ReadWriteLock rwLock;
+
+ private final AtomicInteger counter;
+
+ private final PriorityLock sequencedLock;
+
+ private String name;
+
+ public StatefulObjectReadWriteLock(final String name, final long objectID, final int initialCount)
+ {
+ this.name = name;
+
+ this.objectID = objectID;
+
+ rwLock = new ReentrantReadWriteLock();
+
+ sequencedLock = new PriorityLock(initialCount);
+
+ counter = new AtomicInteger(initialCount);
+ }
+
+ public Lock readLock()
+ {
+ return readLock;
+ }
+
+ public Lock writeLock()
+ {
+ return writeLock;
+ }
+
+ //For debug
+ private Set<Thread> owners = new ConcurrentHashSet<Thread>();
+
+ private boolean doLock(long time, TimeUnit unit, boolean read) throws InterruptedException
+ {
+ JBMThread thread = JBMThread.currentThread();
+
+ //debug only
+ if (owners.contains(thread))
+ {
+ throw new IllegalStateException("Stateful lock is NOT re-entrant!");
+ }
+
+ if (thread.isReplay())
+ {
+ Pair<Long, Integer> sequence = thread.getNextSequence();
+
+ log.info(name + " Attempting to get lock on backup " + sequence.b, new Exception());
+
+ if (sequence.a != objectID)
+ {
+ throw new IllegalStateException("Invalid object id " + sequence.a + " expected " + objectID);
+ }
+
+ sequencedLock.lock(sequence.b);
+
+ owners.add(thread);
+
+ return true;
+ }
+ else
+ {
+ boolean ok;
+
+ if (read)
+ {
+ ok = rwLock.readLock().tryLock(time, unit);
+ }
+ else
+ {
+ ok = rwLock.writeLock().tryLock(time, unit);
+ }
+
+ if (ok)
+ {
+ log.info(name + " added sequence on live " + counter.get(), new Exception());
+
+ thread.addSequence(new Pair<Long, Integer>(objectID, counter.getAndIncrement()));
+
+ owners.add(thread);
+ }
+
+ return ok;
+ }
+ }
+
+ private void doUnlock(final boolean read)
+ {
+ JBMThread thread = JBMThread.currentThread();
+
+ if (thread.isReplay())
+ {
+ sequencedLock.unlock();
+ }
+ else
+ {
+ if (read)
+ {
+ rwLock.readLock().unlock();
+ }
+ else
+ {
+ rwLock.writeLock().unlock();
+ }
+ }
+
+ owners.remove(thread);
+ }
+
+ private class StatefulObjectReadLock implements Lock
+ {
+ public void lock()
+ {
+ //throw new UnsupportedOperationException();
+ try
+ {
+ doLock(10000, TimeUnit.MILLISECONDS, true);
+ }
+ catch (InterruptedException e)
+ {
+ }
+ }
+
+ public void lockInterruptibly() throws InterruptedException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Condition newCondition()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean tryLock()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean tryLock(long time, TimeUnit unit) throws InterruptedException
+ {
+ return doLock(time, unit, true);
+ }
+
+ public void unlock()
+ {
+ doUnlock(true);
+ }
+ }
+
+ private class StatefulObjectWriteLock implements Lock
+ {
+ public void lock()
+ {
+ //throw new UnsupportedOperationException();
+ try
+ {
+ doLock(10000, TimeUnit.MILLISECONDS, false);
+ }
+ catch (InterruptedException e)
+ {
+ }
+ }
+
+ public void lockInterruptibly() throws InterruptedException
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Condition newCondition()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean tryLock()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean tryLock(long time, TimeUnit unit) throws InterruptedException
+ {
+ return doLock(time, unit, false);
+ }
+
+ public void unlock()
+ {
+ doUnlock(false);
+ }
+ }
+}
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/integration/logging/JBMLoggerFormatter.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/integration/logging/JBMLoggerFormatter.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/integration/logging/JBMLoggerFormatter.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -41,11 +41,12 @@
StringBuffer sb = new StringBuffer();
// Minimize memory allocations here.
date.setTime(record.getMillis());
+ sb.append("[").append(Thread.currentThread().getName()).append("] ");
sb.append(dateFormat.format(date)).append(" ");
sb.append(record.getLevel()). append(" [");
sb.append(record.getLoggerName()).append("]").append(" ");
sb.append(record.getMessage());
- sb.append(" ");
+
sb.append(lineSeparator);
if (record.getThrown() != null)
{
Modified: branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/utils/JBMThreadFactory.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/utils/JBMThreadFactory.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/src/main/org/jboss/messaging/utils/JBMThreadFactory.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -33,13 +33,13 @@
*/
public class JBMThreadFactory implements ThreadFactory
{
- private final ThreadGroup group;
+ protected final ThreadGroup group;
- private final AtomicInteger threadCount = new AtomicInteger(0);
+ protected final AtomicInteger threadCount = new AtomicInteger(0);
- private final int threadPriority;
+ protected final int threadPriority;
- private final boolean daemon;
+ protected final boolean daemon;
public JBMThreadFactory(final String groupName, final boolean daemon)
{
Modified: branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/integration/cluster/failover/SimpleAutomaticFailoverTest.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/integration/cluster/failover/SimpleAutomaticFailoverTest.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/integration/cluster/failover/SimpleAutomaticFailoverTest.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -89,13 +89,21 @@
sf.setProducerWindowSize(32 * 1024);
+ log.info("creating session");
+
ClientSession session = sf.createSession(false, true, true);
+
+ log.info("created session");
session.createQueue(ADDRESS, ADDRESS, null, false);
+
+ log.info("created queue");
ClientProducer producer = session.createProducer(ADDRESS);
+
+ log.info("created producer");
- final int numMessages = 100;
+ final int numMessages = 1;
for (int i = 0; i < numMessages; i++)
{
@@ -108,10 +116,16 @@
message.getBody().writeString("aardvarks");
producer.send(message);
}
+
+ // Thread.sleep(30000);
ClientConsumer consumer = session.createConsumer(ADDRESS);
+
+ log.info("created consumer");
session.start();
+
+ log.info("started session");
for (int i = 0; i < numMessages; i++)
{
@@ -122,6 +136,8 @@
message2.acknowledge();
}
+
+ log.info("consumed messages");
ClientMessage message3 = consumer.receive(250);
Modified: branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/BindingImplTest.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/BindingImplTest.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/unit/core/postoffice/impl/BindingImplTest.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -1299,7 +1299,7 @@
/* (non-Javadoc)
* @see org.jboss.messaging.core.server.Queue#getPersistenceID()
*/
- public long getPersistenceID()
+ public long getID()
{
return 0;
Modified: branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/unit/core/server/impl/QueueImplTest.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/unit/core/server/impl/QueueImplTest.java 2009-06-26 05:09:10 UTC (rev 7477)
+++ branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/unit/core/server/impl/QueueImplTest.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -66,13 +66,13 @@
Queue queue = new QueueImpl(id, address1, queue1, null, false, true, scheduledExecutor, null, null, null);
- assertEquals(id, queue.getPersistenceID());
+ assertEquals(id, queue.getID());
final long id2 = 456;
queue.setPersistenceID(id2);
- assertEquals(id2, queue.getPersistenceID());
+ assertEquals(id2, queue.getID());
}
public void testName()
Added: branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/unit/core/server/replication/impl/NewSequencedLockTest.java
===================================================================
--- branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/unit/core/server/replication/impl/NewSequencedLockTest.java (rev 0)
+++ branches/Branch_MultiThreaded_Replication/tests/src/org/jboss/messaging/tests/unit/core/server/replication/impl/NewSequencedLockTest.java 2009-06-26 09:46:34 UTC (rev 7478)
@@ -0,0 +1,215 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005-2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.messaging.tests.unit.core.server.replication.impl;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import junit.framework.TestCase;
+
+import org.jboss.messaging.core.logging.Logger;
+import org.jboss.messaging.core.server.replication.impl.PriorityLock;
+
+/**
+ * A NewSequencedLockTest
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ *
+ *
+ */
+public class NewSequencedLockTest extends TestCase
+{
+ private static final Logger log = Logger.getLogger(NewSequencedLockTest.class);
+
+ public void testAscending() throws Exception
+ {
+ for (int i = 0; i < 1000; i++)
+ {
+ log.info("iter " + i);
+ this.doTestSequences(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
+ }
+ }
+
+ public void testDescending() throws Exception
+ {
+ for (int i = 0; i < 1000; i++)
+ {
+ log.info("iter " + i);
+ this.doTestSequences(9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
+ }
+ }
+
+ public void testAlternate() throws Exception
+ {
+ for (int i = 0; i < 1000; i++)
+ {
+ log.info("iter " + i);
+ this.doTestSequences(9, 0, 8, 1, 7, 2, 6, 3, 5, 4);
+ }
+ }
+
+ public void testRandom() throws Exception
+ {
+ for (int i = 0; i < 1000; i++)
+ {
+ log.info("iter " + i);
+ this.doTestSequences(3, 9, 5, 7, 1, 2, 0, 8, 6, 4);
+ }
+ }
+
+ public void testSpeed() throws Exception
+ {
+ PriorityLock lock = new PriorityLock();
+
+ AtomicInteger counter = new AtomicInteger(0);
+
+ final int numThreads = 10;
+
+ final int acquires = 10000000;
+
+ MyThread2[] threads = new MyThread2[numThreads];
+
+ for (int i = 0; i < numThreads; i++)
+ {
+ threads[i] = new MyThread2(lock, acquires, counter);
+ }
+
+ long start = System.currentTimeMillis();
+
+ for (int i = 0; i < numThreads; i++)
+ {
+ threads[i].start();
+ }
+
+ for (int i = 0; i < numThreads; i++)
+ {
+ threads[i].join();
+ }
+
+ long end = System.currentTimeMillis();
+
+ double rate = 1000 * ((double)acquires * numThreads) / (end - start);
+
+ System.out.println("Rate " + rate);
+
+ }
+
+ class MyThread2 extends Thread
+ {
+ private int acquireCount;
+
+ private final AtomicInteger counter;
+
+ private final PriorityLock lock;
+
+ MyThread2(final PriorityLock lock, final int acquires, final AtomicInteger counter)
+ {
+ this.lock= lock;
+
+ this.acquireCount = acquires;
+
+ this.counter = counter;
+ }
+
+ public void run()
+ {
+ for (int i = 0; i < acquireCount; i++)
+ {
+ lock.lock(counter.getAndIncrement());
+
+ lock.unlock();
+ }
+ }
+ }
+
+ private void doTestSequences(final int... sequences) throws Exception
+ {
+ PriorityLock lock = new PriorityLock();
+
+ AtomicInteger counter = new AtomicInteger(0);
+
+ MyThread[] threads = new MyThread[sequences.length];
+
+ for (int i = 0; i < sequences.length; i++)
+ {
+ threads[i] = new MyThread(sequences[i], counter, lock);
+ }
+
+ for (int i = 0; i < sequences.length; i++)
+ {
+ threads[i].start();
+ }
+
+ for (int i = 0; i < sequences.length; i++)
+ {
+ threads[i].join();
+ }
+
+ for (int i = 0; i < sequences.length; i++)
+ {
+ assertEquals(sequences[i], threads[i].getObtainedSeq());
+ }
+ }
+
+ class MyThread extends Thread
+ {
+ private AtomicInteger counter;
+
+ private PriorityLock lock;
+
+ private final int seq;
+
+ private volatile int obtainedSeq;
+
+ MyThread(final int seq, final AtomicInteger counter, final PriorityLock lock)
+ {
+ this.seq = seq;
+
+ this.counter = counter;
+
+ this.lock = lock;
+ }
+
+ public void run()
+ {
+ // log.info(System.identityHashCode(this) + " Will attempt to obtain lock with sequence " + seq);
+
+ lock.lock(seq);
+
+ // log.info(System.identityHashCode(this) + " Obtained lock with sequence " + seq);
+
+ try
+ {
+ obtainedSeq = counter.getAndIncrement();
+ }
+ finally
+ {
+ lock.unlock();
+ }
+ }
+
+ public int getObtainedSeq()
+ {
+ return this.obtainedSeq;
+ }
+ }
+}
More information about the jboss-cvs-commits
mailing list