diff options
| author | Alan Conway <aconway@apache.org> | 2012-11-14 16:04:04 +0000 |
|---|---|---|
| committer | Alan Conway <aconway@apache.org> | 2012-11-14 16:04:04 +0000 |
| commit | 30abd1273d8a256e91026432811a957e84193a27 (patch) | |
| tree | f5aabeedba6b33fb9685ff441063194bdde3863a /cpp/src/qpid/broker/QueueRegistry.cpp | |
| parent | 9a4bf82944e03e088a2ef392c2313748c984cf11 (diff) | |
| download | qpid-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.cpp | 28 |
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){ |
