Пример #1
0
    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;
    }
Пример #2
0
    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);
                        }
                    }
                }
            }
        }
    }
Пример #3
0
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;
}
Пример #4
0
void SubscribeDB::getUnexpiredSubscriptionsAndIncrementCSeq (
  const UtlString& component,
  const UtlString& key,
  const UtlString& eventTypeKey,
  const int& timeNow,
  Subscriptions& subscriptions)
{
  removeExpired(component, timeNow);
  //query="key=",key,"and eventtypekey=",eventTypeKey;
   mongo::BSONObj query = BSON("$findAndModify" 
           << BSON("query"
           << BSON(
              Subscription::key_fld() << key.str() <<
              Subscription::eventTypeKey_fld() << eventTypeKey.str())) << "," <<
              BSON("update" << BSON_INC(Subscription::notifyCseq_fld() << "1")  )  );

  mongo::ScopedDbConnection conn(_info.getConnectionString());
  mongo::BSONObj result;
  if (conn->runCommand(_info.getNS(), query, result))
  {
    for (mongo::BSONObjIterator iter = result.begin(); iter.more();)
    {
      subscriptions.push_back(Subscription(iter.next().embeddedObject()));
    }
  }

  //while (pCursor.get() && pCursor->more())
  //{
  //    subscriptions.push_back(Subscription(pCursor->next()));
  //}
  conn.done();
}
Пример #5
0
void FillSubscriptionsListBox(wxListBox * box)
{
	char * s;
	int i = 0;
	wxString * str;
	Subscriptions * subs = new Subscriptions();
	
	while ((s = subs->GetNext()) != NULL)
	{
		if (strlen(s) > 0)
		{
			str = new wxString(s, wxConvUTF8);
			box->InsertItems(1, str, i);
			i++;
		}
	}
}
Пример #6
0
void SubscribeDB::getAll(Subscriptions& subscriptions)
{
	mongo::BSONObj query;
	mongo::ScopedDbConnection conn(_info.getConnectionString());
	auto_ptr<mongo::DBClientCursor> pCursor = conn->query(_info.getNS(), query);
	while (pCursor.get() && pCursor->more()) {
		subscriptions.push_back(Subscription(pCursor->next()));
	}
	conn.done();
}
Пример #7
0
    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();
    }
Пример #8
0
void SubscribeDB::getUnexpiredSubscriptions (
    const UtlString& component,
    const UtlString& key,
    const UtlString& eventTypeKey,
    const int& timeNow,
    Subscriptions& subscriptions)
{
    removeExpired(component, timeNow);
    //query="key=",key,"and eventtypekey=",eventTypeKey;
     mongo::BSONObj query = BSON(
        Subscription::key_fld() << key.str() <<
        Subscription::eventTypeKey_fld() << eventTypeKey.str());

    mongo::ScopedDbConnection conn(_info.getConnectionString());
    auto_ptr<mongo::DBClientCursor> pCursor = conn->query(_info.getNS(), query);
    while (pCursor.get() && pCursor->more())
    {
        subscriptions.push_back(Subscription(pCursor->next()));
    }
    conn.done();
}
Пример #9
0
HTTPCode SubscriberManager::modify_subscriptions(
                                    const std::string& public_id,
                                    const Subscriptions& update_subscriptions,
                                    const std::vector<std::string>& remove_subscriptions,
                                    HSSConnection::irs_info& irs_info,
                                    SAS::TrailId trail)
{
  int now = time(NULL);

  // Get cached subscriber information from the HSS.
  std::string aor_id;
  HTTPCode rc = get_cached_default_id(public_id,
                                      aor_id,
                                      irs_info,
                                      trail);
  if (rc != HTTP_OK)
  {
    TRC_DEBUG("Unable to modify subscription for %s - HSS lookup failed with "
              " return code %d",
              public_id.c_str(), rc);
    return rc;
  }

  AoR* orig_aor = NULL;
  uint64_t unused_version;
  rc = _s4->handle_get(aor_id,
                       &orig_aor,
                       unused_version,
                       trail);

  // There must be an existing AoR since there must be bindings to subscribe to.
  if (rc != HTTP_OK)
  {
    TRC_DEBUG("Modifying subscription for AoR %s failed during S4 lookup "
              "with return code %d",
              aor_id.c_str(),
              rc);
    return rc;
  }

  PatchObject patch_object;
  build_patch(patch_object,
              update_subscriptions,
              remove_subscriptions,
              irs_info._associated_uris);

  // PATCH the existing AoR.
  AoR* updated_aor = NULL;
  rc = _s4->handle_patch(aor_id,
                         patch_object,
                         &updated_aor,
                         trail);

  if (rc != HTTP_OK)
  {
    TRC_DEBUG("Modifying subscription for AoR %s failed during S4 update with "
              "return code %d",
              aor_id.c_str(),
              rc);
  }
  else
  {
    // At this point modifying the subscription has been successful - we'll return
    // OK to the client.

    // Write an analytics log for the modified subscription.
    std::string subscription_id = (remove_subscriptions.empty()) ?
                                    update_subscriptions.begin()->first :
                                    remove_subscriptions[0];
    log_subscriptions(aor_id,
                      *orig_aor,
                      *updated_aor,
                      {subscription_id},
                      now);

    // Finally, send any NOTIFYs.
    send_notifys(aor_id,
                 orig_aor,
                 updated_aor,
                 SubscriberDataUtils::EventTrigger::USER,
                 now,
                 trail);
  }

  // Delete both AoRs - the client doesn't need either of these.
  delete orig_aor; orig_aor = NULL;
  delete updated_aor; updated_aor = NULL;

  return rc;
}