![JAR search and dependency download from the Maven repository](/logo.png)
joynr.dispatching.subscription.SubscriptionManager.js Maven / Gradle / Ivy
/*jslint es5: true */
/*
* #%L
* %%
* Copyright (C) 2011 - 2016 BMW Car IT GmbH
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
define("joynr/dispatching/subscription/SubscriptionManager", [
"global/Promise",
"joynr/messaging/MessagingQos",
"joynr/messaging/util/MulticastWildcardRegexFactory",
"joynr/start/settings/defaultMessagingSettings",
"joynr/proxy/SubscriptionQos",
"joynr/dispatching/types/SubscriptionStop",
"joynr/dispatching/types/SubscriptionRequest",
"joynr/dispatching/types/MulticastSubscriptionRequest",
"joynr/dispatching/types/BroadcastSubscriptionRequest",
"joynr/dispatching/subscription/SubscriptionListener",
"joynr/dispatching/subscription/util/SubscriptionUtil",
"joynr/util/LongTimer",
"joynr/system/LoggerFactory",
"uuid",
"joynr/util/UtilInternal",
"joynr/util/Typing",
"joynr/types/TypeRegistrySingleton",
"joynr/exceptions/PublicationMissedException",
"joynr/util/JSONSerializer"
], function(
Promise,
MessagingQos,
MulticastWildcardRegexFactory,
defaultMessagingSettings,
SubscriptionQos,
SubscriptionStop,
SubscriptionRequest,
MulticastSubscriptionRequest,
BroadcastSubscriptionRequest,
SubscriptionListener,
SubscriptionUtil,
LongTimer,
LoggerFactory,
uuid,
Util,
Typing,
TypeRegistrySingleton,
PublicationMissedException,
JSONSerializer) {
/**
* @name SubscriptionManager
* @constructor
* @param {Dispatcher}
* dispatcher
*/
function SubscriptionManager(dispatcher) {
var multicastWildcardRegexFactory = new MulticastWildcardRegexFactory();
var log = LoggerFactory.getLogger("joynr.dispatching.subscription.SubscriptionManager");
var typeRegistry = TypeRegistrySingleton.getInstance();
if (!(this instanceof SubscriptionManager)) {
// in case someone calls constructor without new keyword (e.g. var c =
// Constructor({..}))
return new SubscriptionManager(dispatcher);
}
// stores subscriptionId - SubscriptionInfo pairs
var subscriptionInfos = {};
// stores subscriptionId - SubscriptionListener
var subscriptionListeners = {};
// stores the object which is returned by setTimeout mapped to the subscriptionId
var publicationCheckTimerIds = {};
var subscriptionReplyCallers = {};
var started = true;
var multicastSubscribers = {};
function isReady() {
return started;
}
/**
* @param {String}
* subscriptionId Id of the subscription to check
* @returns {Number} time of last received publication
*/
function getLastPublicationTime(subscriptionId) {
return subscriptionInfos[subscriptionId].lastPublicationTime_ms;
}
function setLastPublicationTime(subscriptionId, time_ms) {
subscriptionInfos[subscriptionId].lastPublicationTime_ms = time_ms;
}
/**
* @param {String}
* subscriptionId Id of the subscription to check
* @param {Number}
* delay_ms Delay to the next publication check.
* @returns {Boolean} true if subscription is expired, false if end date is not reached.
*/
function subscriptionEnds(subscriptionId, delay_ms) {
if (subscriptionInfos[subscriptionId] === undefined) {
log.warn("subscriptionEnds has been called with unresolved subscriptionId \""
+ subscriptionId
+ "\"");
return true;
}
var expiryDateMs = subscriptionInfos[subscriptionId].qos.expiryDateMs;
// log.debug("Checking subscription end for subscriptionId: " + subscriptionId + "
// expiryDateMs: " + expiryDateMs + "
// current time: " + Date.now());
var ends = expiryDateMs <= Date.now() + delay_ms;
// if (ends === true) {
// log.info("Subscription end date reached for id: " + subscriptionId);
// }
return ends;
}
/**
* @param {String}
* subscriptionId Id of the subscription to check
* @param {Number}
* alertAfterIntervalMs maximum delay between two incoming publications
*/
function checkPublication(subscriptionId, alertAfterIntervalMs) {
var subscriptionListener = subscriptionListeners[subscriptionId];
var timeSinceLastPublication = Date.now() - getLastPublicationTime(subscriptionId);
// log.debug("timeSinceLastPublication : " + timeSinceLastPublication + "
// alertAfterIntervalMs: " + alertAfterIntervalMs);
if (alertAfterIntervalMs > 0 && timeSinceLastPublication >= alertAfterIntervalMs) {
// log.warn("publication missed for subscription id: " + subscriptionId);
if (subscriptionListener.onError) {
var publicationMissedException = new PublicationMissedException({
detailMessage : "alertAfterIntervalMs period exceeded without receiving publication",
subscriptionId : subscriptionId
});
subscriptionListener.onError(publicationMissedException);
}
}
var delay_ms;
if (timeSinceLastPublication > alertAfterIntervalMs) {
delay_ms = alertAfterIntervalMs;
} else {
delay_ms = alertAfterIntervalMs - timeSinceLastPublication;
}
if (!subscriptionEnds(subscriptionId, delay_ms)) {
// log.debug("Rescheduling checkPublication with delay: " + delay_ms);
publicationCheckTimerIds[subscriptionId] =
LongTimer.setTimeout(function checkPublicationDelay() {
checkPublication(subscriptionId, alertAfterIntervalMs);
}, delay_ms);
}
}
function calculateTtl(subscriptionQos) {
var ttl;
if (subscriptionQos.expiryDateMs === SubscriptionQos.NO_EXPIRY_DATE) {
return defaultMessagingSettings.MAX_MESSAGING_TTL_MS;
}
ttl = subscriptionQos.expiryDateMs - Date.now();
if (ttl > defaultMessagingSettings.MAX_MESSAGING_TTL_MS) {
return defaultMessagingSettings.MAX_MESSAGING_TTL_MS;
}
return ttl;
}
function storeSubscriptionRequest(settings, subscriptionRequest) {
var onReceiveWrapper;
if (settings.attributeType !== undefined) {
onReceiveWrapper = function(response) {
settings.onReceive(Typing.augmentTypes(response[0], typeRegistry, settings.attributeType));
};
} else {
onReceiveWrapper = function(response) {
var responseKey;
for (responseKey in response) {
if (response.hasOwnProperty(responseKey)) {
response[responseKey] = Typing.augmentTypes(response[responseKey],
typeRegistry,
settings.broadcastParameter[responseKey].type);
}
}
settings.onReceive(response);
};
}
subscriptionListeners[subscriptionRequest.subscriptionId] = new SubscriptionListener({
onReceive : onReceiveWrapper,
onError : settings.onError,
onSubscribed : settings.onSubscribed
});
var subscriptionInfo = Util.extend({
proxyId : settings.proxyId,
providerId : settings.providerId,
lastPublicationTime_ms : 0
}, subscriptionRequest);
subscriptionInfos[subscriptionRequest.subscriptionId] = subscriptionInfo;
var alertAfterIntervalMs = subscriptionRequest.qos.alertAfterIntervalMs;
if (alertAfterIntervalMs !== undefined && alertAfterIntervalMs > 0) {
publicationCheckTimerIds[subscriptionRequest.subscriptionId] =
LongTimer.setTimeout(
function checkPublicationAlertAfterInterval() {
checkPublication(
subscriptionRequest.subscriptionId,
alertAfterIntervalMs);
},
alertAfterIntervalMs);
}
}
function removeRequestFromMulticastSubscribers(multicastId, subscriptionId) {
var i,multicastIdPattern, subscribers;
for (multicastIdPattern in multicastSubscribers) {
if (multicastSubscribers.hasOwnProperty(multicastIdPattern)) {
subscribers = multicastSubscribers[multicastIdPattern];
for(i=0;i 0;
};
this.hasOpenSubscriptions = function() {
var hasSubscriptionInfos = Object.keys(subscriptionInfos).length > 0;
var hasSubscriptionListeners = Object.keys(subscriptionListeners).length > 0;
var hasPublicationCheckTimerIds = Object.keys(publicationCheckTimerIds).length > 0;
var hasSubscriptionReplyCallers = Object.keys(subscriptionReplyCallers).length > 0;
return hasSubscriptionInfos ||
hasSubscriptionListeners ||
hasPublicationCheckTimerIds ||
hasSubscriptionReplyCallers ||
this.hasMulticastSubscriptions();
};
/**
* Shutdown the subscription manager
*
* @function
* @name SubscriptionManager#shutdown
*/
this.shutdown = function shutdown() {
var subscriptionId;
for (subscriptionId in publicationCheckTimerIds) {
if (publicationCheckTimerIds.hasOwnProperty(subscriptionId)) {
var timerId = publicationCheckTimerIds[subscriptionId];
if (timerId !== undefined) {
LongTimer.clearTimeout(timerId);
}
}
}
publicationCheckTimerIds = {};
for (subscriptionId in subscriptionReplyCallers) {
if (subscriptionReplyCallers.hasOwnProperty(subscriptionId)) {
var subscriptionReplyCaller = subscriptionReplyCallers[subscriptionId];
if (subscriptionReplyCaller) {
subscriptionReplyCaller.reject(new Error("Subscription Manager is already shut down"));
}
}
}
subscriptionReplyCallers = {};
started = false;
};
}
return SubscriptionManager;
});
© 2015 - 2025 Weber Informatics LLC | Privacy Policy