summaryrefslogtreecommitdiff
path: root/cpp/src/qpid/broker/QueueRegistry.cpp
diff options
context:
space:
mode:
authorAlan Conway <aconway@apache.org>2012-11-14 16:04:04 +0000
committerAlan Conway <aconway@apache.org>2012-11-14 16:04:04 +0000
commit30abd1273d8a256e91026432811a957e84193a27 (patch)
treef5aabeedba6b33fb9685ff441063194bdde3863a /cpp/src/qpid/broker/QueueRegistry.cpp
parent9a4bf82944e03e088a2ef392c2313748c984cf11 (diff)
downloadqpid-python-30abd1273d8a256e91026432811a957e84193a27.tar.gz
QPID-4428: HA add UUID tag to avoid using an out of date queue/exchange.
Imagine a cluster with primary A and backups B and C. A queue Q is created on A and replicated to B, C. Now A dies and B takes over as primary. Before C can connect to B, a client destroys Q and creates a new queue with the same name. When B connects it sees Q and incorrectly assumes it is the same Q that it has already replicated. Now C has an inconsistent replica of Q. The fix is to tag queues/exchanges with a UUID so a backup can tell if a queue is not the same as the one it has already replicated, even if the names are the same. This all also applies to exchanges. - Minor imrovements to printing UUIDs in a FieldTable. - Fix comparison of void Variants, added operator != git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1409241 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp/src/qpid/broker/QueueRegistry.cpp')
-rw-r--r--cpp/src/qpid/broker/QueueRegistry.cpp28
1 files changed, 15 insertions, 13 deletions
diff --git a/cpp/src/qpid/broker/QueueRegistry.cpp b/cpp/src/qpid/broker/QueueRegistry.cpp
index ed9f01c8b2..b59eb530f0 100644
--- a/cpp/src/qpid/broker/QueueRegistry.cpp
+++ b/cpp/src/qpid/broker/QueueRegistry.cpp
@@ -69,23 +69,25 @@ QueueRegistry::declare(const string& name, const QueueSettings& settings,
queue->create();
}
queues[name] = queue;
+ // NOTE: raiseEvent and queueCreate must be called with the lock held in
+ // order to ensure events are generated in the correct order.
+ // Call queueCreate before raiseEvents so it can add arguments that
+ // will be included in the management event.
+ if (getBroker()) getBroker()->getConfigurationObservers().queueCreate(queue);
result = std::pair<Queue::shared_ptr, bool>(queue, true);
} else {
result = std::pair<Queue::shared_ptr, bool>(i->second, false);
}
- // NOTE: raiseEvent must be called with the lock held in order to
- // ensure management events are generated in the correct order.
- if (getBroker() && getBroker()->getManagementAgent() && connectionId.size() && userId.size()) {
+ if (getBroker() && getBroker()->getManagementAgent()) {
getBroker()->getManagementAgent()->raiseEvent(
_qmf::EventQueueDeclare(
connectionId, userId, name,
settings.durable, owner, settings.autodelete,
alternate ? alternate->getName() : string(),
- settings.asMap(),
+ result.first->getSettings().asMap(),
result.second ? "created" : "existing"));
}
}
- if (getBroker() && result.second) getBroker()->getConfigurationObservers().queueCreate(result.first);
return result;
}
@@ -99,17 +101,17 @@ void QueueRegistry::destroy(
if (i != queues.end()) {
q = i->second;
queues.erase(i);
- if (getBroker() && getBroker()->getManagementAgent() &&
- connectionId.size() && userId.size())
- {
- // NOTE: raiseEvent must be called with the lock held in order to
- // ensure management events are generated in the correct order.
- getBroker()->getManagementAgent()->raiseEvent(
- _qmf::EventQueueDelete(connectionId, userId, name));
+ if (getBroker()) {
+ // NOTE: queueDestroy and raiseEvent must be called with the
+ // lock held in order to ensure events are generated
+ // in the correct order.
+ getBroker()->getConfigurationObservers().queueDestroy(q);
+ if (getBroker()->getManagementAgent())
+ getBroker()->getManagementAgent()->raiseEvent(
+ _qmf::EventQueueDelete(connectionId, userId, name));
}
}
}
- if (getBroker() && q) getBroker()->getConfigurationObservers().queueDestroy(q);
}
Queue::shared_ptr QueueRegistry::find(const string& name){