void Cluster::configChange(const MemberId&, const std::string& membersStr, const std::string& leftStr, const std::string& joinedStr, Lock& l) { if (state == LEFT) return; MemberSet members = decodeMemberSet(membersStr); MemberSet left = decodeMemberSet(leftStr); MemberSet joined = decodeMemberSet(joinedStr); QPID_LOG(notice, *this << " configuration change: " << members); QPID_LOG_IF(notice, !left.empty(), *this << " Members left: " << left); QPID_LOG_IF(notice, !joined.empty(), *this << " Members joined: " << joined); // If we are still joining, make sure there is someone to give us an update. elders = intersection(elders, members); if (elders.empty() && INIT < state && state < CATCHUP) { QPID_LOG(critical, "Cannot update, all potential updaters left the cluster."); leave(l); return; } bool memberChange = map.configChange(members); // Update initital status for members joining or leaving. initMap.configChange(members); if (initMap.isResendNeeded()) { mcast.mcastControl( ClusterInitialStatusBody( ProtocolVersion(), CLUSTER_VERSION, state > INIT, clusterId, store.getState(), store.getShutdownId(), initMap.getFirstConfigStr(), vectorToUrlArray(getUrls(l)) ), self); } if (initMap.transitionToComplete()) initMapCompleted(l); if (state >= CATCHUP && memberChange) { memberUpdate(l); if (elders.empty()) becomeElder(l); } updateMgmtMembership(l); // Update on every config change for consistency }
void Cluster::processFrame(const EventFrame& e, Lock& l) { if (e.isCluster()) { QPID_LOG_IF(trace, loggable(e.frame), *this << " DLVR: " << e); ClusterDispatcher dispatch(*this, e.connectionId.getMember(), l); if (!framing::invoke(dispatch, *e.frame.getBody()).wasHandled()) throw Exception(QPID_MSG("Invalid cluster control")); } else if (state >= CATCHUP) { map.incrementFrameSeq(); ConnectionPtr connection = getConnection(e, l); if (connection) { QPID_LOG_IF(trace, loggable(e.frame), *this << " DLVR " << map.getFrameSeq() << ": " << e); connection->deliveredFrame(e); } else throw Exception(QPID_MSG("Unknown connection: " << e)); } else // Drop connection frames while state < CATCHUP QPID_LOG_IF(trace, loggable(e.frame), *this << " DROP (joining): " << e); }
void Cluster::initialStatus(const MemberId& member, uint32_t version, bool active, const framing::Uuid& id, framing::cluster::StoreState store, const framing::Uuid& shutdownId, const std::string& firstConfig, const framing::Array& urls, Lock& l) { if (version != CLUSTER_VERSION) { QPID_LOG(critical, *this << " incompatible cluster versions " << version << " != " << CLUSTER_VERSION); leave(l); return; } QPID_LOG_IF(debug, state == PRE_INIT, *this << " received initial status from " << member); initMap.received( member, ClusterInitialStatusBody(ProtocolVersion(), version, active, id, store, shutdownId, firstConfig, urls) ); if (initMap.transitionToComplete()) initMapCompleted(l); }
Exception::Exception(const std::string& msg) throw() : message(msg) { QPID_LOG_IF(debug, !msg.empty(), "Exception constructed: " << message); }