- In controllers: all reference to map config are now camelized, for instance: mapconfig -> mapConfig or mapconfigProvider -> mapConfigProvider - In controllers: all map config providers created in req/res cycle are saved into `res.locals` and `mapConfigProvider` as key. - In map-config-providers: all of them implement `.getAffectedTables()`, in order to calculate the tables involved for a given map-config. For that, `pgConnection` and `affectedTablesCache` are injected as constructor argument. - Named Map Provider: rename references from `affectedTablesAndLastUpdate` to `affectedTables`. - Named Map Provider Cache: In order to create new named map providers, needs affectedTablesCache. - Extract locals middlewares (surrogate-key and cache-channel) from controllers and create an unified version of them. - Extract last-modified middleware from named maps controller (draft).
96 lines
3.2 KiB
JavaScript
96 lines
3.2 KiB
JavaScript
var _ = require('underscore');
|
|
var dot = require('dot');
|
|
var NamedMapMapConfigProvider = require('../models/mapconfig/provider/named-map-provider');
|
|
var templateName = require('../backends/template_maps').templateName;
|
|
var queue = require('queue-async');
|
|
|
|
var LruCache = require("lru-cache");
|
|
|
|
function NamedMapProviderCache(
|
|
templateMaps,
|
|
pgConnection,
|
|
metadataBackend,
|
|
userLimitsApi,
|
|
mapConfigAdapter,
|
|
affectedTablesCache
|
|
) {
|
|
this.templateMaps = templateMaps;
|
|
this.pgConnection = pgConnection;
|
|
this.metadataBackend = metadataBackend;
|
|
this.userLimitsApi = userLimitsApi;
|
|
this.mapConfigAdapter = mapConfigAdapter;
|
|
this.affectedTablesCache = affectedTablesCache;
|
|
|
|
this.providerCache = new LruCache({ max: 2000 });
|
|
}
|
|
|
|
module.exports = NamedMapProviderCache;
|
|
|
|
NamedMapProviderCache.prototype.get = function(user, templateId, config, authToken, params, callback) {
|
|
var namedMapKey = createNamedMapKey(user, templateId);
|
|
var namedMapProviders = this.providerCache.get(namedMapKey) || {};
|
|
|
|
var providerKey = createProviderKey(config, authToken, params);
|
|
if (!namedMapProviders.hasOwnProperty(providerKey)) {
|
|
namedMapProviders[providerKey] = new NamedMapMapConfigProvider(
|
|
this.templateMaps,
|
|
this.pgConnection,
|
|
this.metadataBackend,
|
|
this.userLimitsApi,
|
|
this.mapConfigAdapter,
|
|
this.affectedTablesCache,
|
|
user,
|
|
templateId,
|
|
config,
|
|
authToken,
|
|
params
|
|
);
|
|
this.providerCache.set(namedMapKey, namedMapProviders);
|
|
|
|
// early exit, if provider did not exist we just return it
|
|
return callback(null, namedMapProviders[providerKey]);
|
|
}
|
|
|
|
var namedMapProvider = namedMapProviders[providerKey];
|
|
|
|
var self = this;
|
|
queue(2)
|
|
.defer(namedMapProvider.getTemplate.bind(namedMapProvider))
|
|
.defer(this.templateMaps.getTemplate.bind(this.templateMaps), user, templateId)
|
|
.awaitAll(function templatesQueueDone(err, results) {
|
|
if (err) {
|
|
return callback(err);
|
|
}
|
|
|
|
// We want to reset provider its template has changed
|
|
// Ideally this should be done in a passive mode where this cache gets notified of template changes
|
|
var uniqueFingerprints = _.uniq(results.map(self.templateMaps.fingerPrint)).length;
|
|
if (uniqueFingerprints > 1) {
|
|
namedMapProvider.reset();
|
|
}
|
|
return callback(null, namedMapProvider);
|
|
});
|
|
};
|
|
|
|
NamedMapProviderCache.prototype.invalidate = function(user, templateId) {
|
|
this.providerCache.del(createNamedMapKey(user, templateId));
|
|
};
|
|
|
|
function createNamedMapKey(user, templateId) {
|
|
return user + ':' + templateName(templateId);
|
|
}
|
|
|
|
var providerKey = '{{=it.authToken}}:{{=it.configHash}}:{{=it.format}}:{{=it.layer}}:{{=it.scale_factor}}';
|
|
var providerKeyTpl = dot.template(providerKey);
|
|
|
|
function createProviderKey(config, authToken, params) {
|
|
var tplValues = _.defaults({}, params, {
|
|
authToken: authToken || '',
|
|
configHash: NamedMapMapConfigProvider.configHash(config),
|
|
layer: '',
|
|
format: '',
|
|
scale_factor: 1
|
|
});
|
|
return providerKeyTpl(tplValues);
|
|
}
|