void SubscriptionService::onServerStop(RcfServer &server) { RCF_UNUSED_VARIABLE(server); mPeriodicTimer.stop(); Subscriptions subs; { Lock writeLock(mSubscriptionsMutex); subs = mSubscriptions; } for (Subscriptions::iterator iter = subs.begin(); iter != subs.end(); ++iter) { SubscriptionPtr subscriptionPtr = iter->lock(); if (subscriptionPtr) { subscriptionPtr->close(); } } { Lock writeLock(mSubscriptionsMutex); RCF_ASSERT(mSubscriptions.empty()); } mSubscriptions.clear(); subs.clear(); mpServer = NULL; }
void SubscriptionService::pingAllSubscriptions() { // Send oneway pings on all our subscriptions, so the publisher // knows we're still alive. Subscriptions subs; { Lock lock(mSubscriptionsMutex); subs = mSubscriptions; } Subscriptions::iterator iter; for (iter = subs.begin(); iter != subs.end(); ++iter) { SubscriptionPtr subPtr = iter->lock(); if (subPtr) { Subscription & sub = * subPtr; if (sub.mPingsEnabled && sub.isConnected()) { // Lock will be unlocked when the asynchronous send completes. // Using recursive lock here because the ping may result in a // disconnect, which will then automatically close the connection // and close the subscription, which requires the lock to be taken again. boost::shared_ptr<RecursiveLock> lockPtr( new RecursiveLock(sub.mMutex) ); // TODO: async pings bool asyncPings = false; if (asyncPings) { AsioErrorCode ecDummy; sub.mConnectionPtr->getClientStub().ping( RCF::AsyncOneway(boost::bind( &SubscriptionService::sOnPingCompleted, lockPtr))); } else { try { sub.mConnectionPtr->getClientStub().ping(RCF::Oneway); } catch(const RCF::Exception & e) { std::string errMsg = e.getErrorString(); RCF_UNUSED_VARIABLE(errMsg); } } } } } }
void SubscriptionService::harvestExpiredSubscriptions() { // Kill off subscriptions that haven't received any recent pings. Subscriptions subsToDrop; { Lock lock(mSubscriptionsMutex); Subscriptions::iterator iter; for (iter = mSubscriptions.begin(); iter != mSubscriptions.end(); ++iter) { SubscriptionPtr subPtr = iter->lock(); if (subPtr) { Subscription & sub = * subPtr; RecursiveLock lock(sub.mMutex); RcfSessionPtr sessionPtr = sub.mRcfSessionWeakPtr.lock(); if (!sessionPtr) { RCF_LOG_2()(sub.mPublisherUrl)(sub.mTopic) << "Dropping subscription. Publisher has closed connection."; subsToDrop.insert(*iter); } else if (sub.mPingsEnabled) { boost::uint32_t pingIntervalMs = sub.mPingIntervalMs; if (pingIntervalMs) { RCF::Timer pingTimer(sessionPtr->getPingTimestamp()); if (pingTimer.elapsed(5000 + 2*pingIntervalMs)) { RCF_LOG_2()(sub.mPublisherUrl)(sub.mTopic)(sub.mPingIntervalMs) << "Dropping subscription. Publisher has not sent pings."; subsToDrop.insert(*iter); } } } } } for (iter = subsToDrop.begin(); iter != subsToDrop.end(); ++iter) { mSubscriptions.erase(*iter); } } subsToDrop.clear(); }
TMessageSystem::Subscriptions::iterator TMessageSystem::FindSubscription(Subscriptions& subscriptions, const MessageID& messageId) { auto it = subscriptions.begin(); const auto iend = subscriptions.end(); while (it != iend) { if (it->first != messageId) { ++it; } else { break; } } return it; }