void SubscriptionManager::registerSubscription( const std::string& subscribeToName, std::shared_ptr<ISubscriptionCallback> subscriptionCaller, const Variant& qosVariant, SubscriptionRequest& subscriptionRequest) { // Register the subscription std::string subscriptionId = subscriptionRequest.getSubscriptionId(); JOYNR_LOG_DEBUG(logger, "Subscription registered. ID={}", subscriptionId); if (subscriptions.contains(subscriptionId)) { // pre-existing subscription: remove it first from the internal data structure unregisterSubscription(subscriptionId); } std::int64_t now = std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now().time_since_epoch()).count(); subscriptionRequest.setQos(qosVariant); const SubscriptionQos* qos = subscriptionRequest.getSubscriptionQosPtr(); if (qos->getExpiryDateMs() != SubscriptionQos::NO_EXPIRY_DATE() && qos->getExpiryDateMs() < now) { throw std::invalid_argument("Subscription ExpiryDate " + std::to_string(qos->getExpiryDateMs()) + " in the past. Now: " + std::to_string(now)); } auto subscription = std::make_shared<Subscription>(subscriptionCaller); subscriptions.insert(subscriptionId, subscription); { std::lock_guard<std::recursive_mutex> subscriptionLocker(subscription->mutex); if (SubscriptionUtil::getAlertInterval(qosVariant) > 0 && SubscriptionUtil::getPeriodicPublicationInterval(qosVariant) > 0) { JOYNR_LOG_DEBUG(logger, "Will notify if updates are missed."); std::int64_t alertAfterInterval = SubscriptionUtil::getAlertInterval(qosVariant); JoynrTimePoint expiryDate(std::chrono::milliseconds(qos->getExpiryDateMs())); if (qos->getExpiryDateMs() == SubscriptionQos::NO_EXPIRY_DATE()) { expiryDate = JoynrTimePoint( std::chrono::milliseconds(std::numeric_limits<std::int64_t>::max())); } std::int64_t periodicPublicationInterval = SubscriptionUtil::getPeriodicPublicationInterval(qosVariant); subscription->missedPublicationRunnableHandle = missedPublicationScheduler->schedule( new MissedPublicationRunnable(expiryDate, periodicPublicationInterval, subscriptionId, subscription, *this, alertAfterInterval), std::chrono::milliseconds(alertAfterInterval)); } else if (qos->getExpiryDateMs() != SubscriptionQos::NO_EXPIRY_DATE()) { std::int64_t now = std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now().time_since_epoch()).count(); subscription->subscriptionEndRunnableHandle = missedPublicationScheduler->schedule( new SubscriptionEndRunnable(subscriptionId, *this), std::chrono::milliseconds(qos->getExpiryDateMs() - now)); } } subscriptionRequest.setSubscriptionId(subscriptionId); subscriptionRequest.setSubscribeToName(subscribeToName); }