diffusion
Version:
Diffusion JavaScript client
128 lines (101 loc) • 4.07 kB
JavaScript
var TimeSeriesEntry = require('routing/topic-cache-time-series-entry');
var NoValueEntry = require('routing/topic-cache-no-value-entry');
var DatatypeEntry = require('routing/topic-cache-datatype-entry');
var UnsubscribeReason = require('../../topics/topics').UnsubscribeReason;
var TopicType = require('../../topics/topics').TopicType;
var TopicDetails = require('topics/details/topic-details');
module.exports = function TopicCache(datatypes) {
var byPath = {};
var byId = {};
this.handleSubscription = function(info, registry) {
var path = info.path;
var streams = registry.streamsFor(path, info.specification);
var entry;
var details = TopicDetails.detailsFromSpecification(info.specification);
switch (info.specification.type) {
case TopicType.JSON :
case TopicType.BINARY :
case TopicType.STRING :
case TopicType.DOUBLE :
case TopicType.INT64 :
case TopicType.RECORD_V2 :
var datatype = datatypes.get(info.specification.type);
entry = new DatatypeEntry(streams, path, details, info.specification, datatype);
break;
case TopicType.TIME_SERIES :
var eventType = datatypes.get(info.specification.properties.TIME_SERIES_EVENT_VALUE_TYPE);
entry = new TimeSeriesEntry(streams, path, details, info.specification, eventType);
break;
default :
entry = new NoValueEntry(streams, path, details, info.specification);
}
var oldByPath = byPath[path];
byPath[path] = entry;
if (oldByPath) {
throw new Error("Existing cache entry for " + path);
}
var oldById = byId[info.id];
byId[info.id] = entry;
if (oldById) {
throw new Error("Existing cache entry for " + info.id);
}
entry.notifyInitialSubscription(registry);
};
this.notifyUnsubscriptionOfAllTopics = function(registry) {
for (var id in byId) {
byId[id].notifyUnsubscription(UnsubscribeReason.SUBSCRIPTION_REFRESH, registry);
}
byPath = {};
byId = {};
};
this.handleValue = function(session, id, content, registry) {
var errorHandler = session.getErrorHandler();
var entry = byId[id];
if (entry) {
entry.handleValue(content, registry, errorHandler);
} else {
errorHandler(new Error("Data loss on topic with ID: " + id + " - possibly due to reconnection"));
}
};
this.handleDelta = function(session, id, delta, registry) {
var errorHandler = session.getErrorHandler();
var entry = byId[id];
if (entry) {
entry.handleDelta(delta, registry, errorHandler);
} else {
errorHandler(new Error("Data loss on topic with ID: " + id + " - possibly due to reconnection"));
}
};
this.handleUnsubscription = function(id, reason, registry) {
var entry = byId[id];
delete byId[id];
if (entry) {
var path = entry.getTopicPath();
delete byPath[path];
entry.notifyUnsubscription(reason, registry);
}
};
this.newStream = function(selector, stream, registry) {
for (var path in byPath) {
var entry = byPath[path];
var specification = entry.getTopicSpecification();
if (selector.selects(path) && stream.selects(specification)) {
entry.addStream(stream.adapter?stream.adapter(specification):stream, registry);
}
}
};
this.removeStream = function(stream, registry) {
for (var path in byPath) {
byPath[path].removeStream(stream, registry);
}
};
this.removeAllStreams = function() {
for (var path in byPath) {
byPath[path].removeAllStreams();
}
};
this.clear = function() {
byPath = {};
byId = {};
};
};