UNPKG

vulcain-corejs

Version:
167 lines (165 loc) 6.26 kB
"use strict"; const system_1 = require("./../globals/system"); const configurationManager_1 = require("../configurationSources/configurationManager"); const propertiesFactory_1 = require("./propertiesFactory"); const configurationSourceBuilder_1 = require("../configurationSources/configurationSourceBuilder"); const rx = require("rx"); const conventions_1 = require("../../utils/conventions"); /** * * Provides dynamic properties updated when config change. * Accessing a dynamic property is very fast. The last value is cached and updated on the fly * from a <b>ConfigurationSource</b> at fixed interval. * Updates are made using polling requests on a list of sources. * <p> * Dynamic properties are read only. You can set a value but it will be valid only as a default value. * </p> * <code> * let i:number = DynamicProperties.instance.getProperty("prop1"); * let i2:number = DynamicProperties.instance.getOrDefaultProperty("prop1", 1); * </code> */ class DynamicProperties { /** * Private constructor * <param name="pollingIntervalInSeconds"></param> * <param name="sourceTimeoutInMs"></param> */ constructor(pollingIntervalInSeconds, sourceTimeoutInMs) { this._properties = new Map(); this._propertyChanged = new rx.Subject(); this._factory = new propertiesFactory_1.PropertiesFactory(this); this.reset(pollingIntervalInSeconds, sourceTimeoutInMs); } /// <summary> /// Raises when a property has changed /// </summary> get propertyChanged() { return this._propertyChanged; } /** * for test only */ // static __forcePollingAsync() { // return DynamicProperties.instance._configurationManager.startAsync(); // } /// <summary> /// Get the dynamic properties factory /// </summary> static get factory() { return DynamicProperties.instance._factory; } /// <summary> /// Get a singleton instance /// </summary> static get instance() { if (!DynamicProperties._instance) { DynamicProperties.init(); } return DynamicProperties._instance; } /// <summary> /// Initialise dynamic properties configuration. Can be call only once and before any call to DynamicProperties.instance. /// </summary> /// <param name="pollingIntervalInSeconds">Polling interval in seconds (default 60)</param> /// <param name="sourceTimeoutInMs">Max time allowed to a source to retrieve new values (Cancel the request but doesn't raise an error)</param> /// <returns>ConfigurationSourceBuilder</returns> static init(pollingIntervalInSeconds, sourceTimeoutInMs) { if (DynamicProperties._instance) DynamicProperties._instance.reset(); DynamicProperties._instance = new DynamicProperties(pollingIntervalInSeconds || 60, sourceTimeoutInMs || 1000); return new configurationSourceBuilder_1.ConfigurationSourceBuilder(DynamicProperties._instance._configurationManager); } addProperty(name, prop) { this._properties.set(name, prop); } static registerPropertyAsDependency(name, defaultValue) { let p = system_1.System.manifest.configurations[name]; if (p && p !== "any") return; let schema = "any"; if (typeof defaultValue === "number" || defaultValue) { schema = typeof defaultValue; } system_1.System.manifest.configurations[name] = schema; } /** /// Reset configuration and properties. /// All current properties will be invalid and all current sources will be lost. /// </summary> /// <param name="pollingIntervalInSeconds"></param> /// <param name="sourceTimeoutInMs"></param> */ reset(pollingIntervalInSeconds, sourceTimeoutInMs) { this._propertyChanged.dispose(); this._propertyChanged = new rx.Subject(); let tmp = this._properties; let tmp2 = this._configurationManager; this._properties = new Map(); this._configurationManager = new configurationManager_1.ConfigurationManager(this, pollingIntervalInSeconds || 60, sourceTimeoutInMs || 2000); if (tmp) { for (let prop of tmp.values()) { if (prop.dispose) prop.dispose(); } tmp.clear(); } if (tmp2) tmp2.dispose(); } get pollingIntervalInSeconds() { return this._configurationManager ? this._configurationManager.pollingIntervalInSeconds : 0; } onPropertyChanged(property, action) { system_1.System.log.info(null, "CONFIG: Property changed " + property.name); this._propertyChanged.onNext(property); } // for tests only startPollingAsync(source) { return this._configurationManager.startAsync(source && [source], false); } /// <summary> /// Get a property or null if not exists /// </summary> /// <param name="name">Property name</param> /// <returns>A dynamic property instance or null if not exists.</returns> getProperty(name) { let prop = this._properties.get(name); if (!prop) { if (!prop) { let env = process.env[conventions_1.Conventions.toEnvironmentVariableName(name)]; if (env !== undefined) { prop = this._factory.asProperty(env, name, true); } } } return prop; } clear() { this._properties.clear(); } Updater_getOrCreate(name, factory) { let prop = this._properties.get(name); if (!prop) { prop = factory(); this._properties.set(name, prop); } return prop; } Updater_removeProperty(name) { let p = this._properties.get(name); p && p.reset(); } dispose() { for (let prop of this._properties.values()) { if (prop.dispose) prop.dispose(); } this._configurationManager.dispose(); this._properties.clear(); this._factory = null; this._propertyChanged.dispose(); } } exports.DynamicProperties = DynamicProperties; //# sourceMappingURL=dynamicProperties.js.map