Because of some testing restiction on ES6 constructors, all the classes are namspaces with RedisUrlCache
Redis-url-cache supports either a promise API or a node.js callback API ( with err as a first callback parameter ). To use the promise, you need to require the CacheEnginePromise class, or the CacheEngineCB for the callback
var CacheEngine = require('redis-url-cache').RedisUrlCache.CacheEnginePromise;
//or
var CacheEngine = require('redis-url-cache').RedisUrlCache.CacheEngineCB;
All subsequent usage will then use promise or callbacks depending on which class you used to initiate your cacheEngine object.
Please not that Instance and Cache Creator don't use promise.
constructor(defaultDomain:string, instance: Instance)
The constructor is the same whenever you use the promise or the callback CacheEngine. It must takes a default domain and an initialized Instance.
url(url: string): UrlCB
url(url: string): UrlPromise
It will return a UrlCB or a UrlPromise.
The URL can be relative or absolute. If the URL is relative, then the default domain specified in the CacheEngine constructor will be used.
//With callbacks
clearDomain(domain?: string, callback: CallBackBooleanParam): void
//with promises
clearDomain(domain?: string): Promise
The domain is the full hostname (ex: http://www.domain.com:8080) you want all the cached url deleted from.
If no domain is specified, then the default domain will be cleared.
//With callbacks
clearInstance(callback: CallBackBooleanParam): void
//with promises
clearInstance(): Promise
This will delete all cached URL associated with the instance associated with the CacheEngine.
//With callbacks
getStoredHostNames(callback: CallBackStringArrayParam): void
//with promises
getStoredHostNames(): Promise
Retrieves an array of string representing all the domain that contains URL cached.
//With callbacks
getStoredURLs(domain: string, callback: CallBackStringArrayParam): void
//with promises
getStoredURLs(domain: string): Promise
Retrieves all urls stored within the domain specified. If no domain is provided, it will return the urls stored for the default domain
You need to store the CacheRules at least once into the REDIS store to use the instance. This class will return a callback error if a CacheRule configuration already exists for this instance
A typical workflow:
static createCache(instanceName: string, force: boolean, redisConfig: RedisStorageConfig, rules: CacheRules, callback: Function(error: string)): void
The CacheRuleManager class alows you to add/delete the CacheRule config stored into Redis
All 3 of addMaxAgeRule(), addAlwaysRule() and addNeverRule() share the same sets of parameters [domain, path and ignoreQuery].
When parsed by CacheEngine.url(), the url format is separated in two parts.
scheme:[//[user:password@]host[:port]] is matched against the domain
[/]path[?query] is matched against the path RegExp. The query will be ignored if the ignoreQuery
parameter is set to true
A typical CacheRuleManager usage would be:
// This assumes a config has already been created with CacheRuleCreator
const instance = new Instance('INSTANCE1', redisConfig, err => {
if(err) throw err;
// retrives the cacheRuleManager
const cacheRuleManager = instance.getManager();
//adds an always rule
cacheRuleManager.addAlwaysRule(/localhost/, /.*/, (err) => {
if (err) throw err;
//notifies all existing CacheEngine running in other process for the change
instance.publish();
}
});
addMaxAgeRule( domain: string | RegExp, path: RegExp, ttl: number, ignoreQuery?:boolean): void
All urls matching this rule will be cached with an expiration time specified by ttl in seconds
addAlwaysRule( domain: string | RegExp, path: RegExp, ignoreQuery?:boolean): void
All URLs matching this rule will be cached
addNeverRule( domain: string | RegExp, path: RegExp, ignoreQuery?:boolean): void
All URLs matching this rule will never be cached
removeAll(): void
This will clear all the cache rules from the config, making all the URLs matching the default strategy.
removeAllMaxAgeRules(): void
Removes all the maxAge CacheRules- good for unit testing integration
removeAllNeverRules(): void
Removes all the never CacheRules- good for unit testing integration
removeAllAlwaysRules(): void
Removes all the always CacheRules - good for unit testing integration
removeRule(domain:string | RegExp, rule: RegExp)
It will traverse all the never, always and maxAge rules and if i finds a matching rule, will remove it.
setDefault(strategy: string): void
When the url doesn't match any rules, then this classification will be applied. Can only accept always or never.
getRules(): CacheRules
Returns an object representing the active rules used by the instance
This JSON object defines how you connect to the REDIS data store. INternally, redis-url-cache uses node-redis. This config bject ise exactly the same as defined here : Redis.createClient() config
A very basic redis config object example:
var redisConfig = {
host: 127.0.0.1,
port: 6379s,
socket_keepalive: true
}
This JSON object defines which URL will be cached, which ones will be ignored and for how long
Under the hood the typescript definition for this config is:
export interface RegexRule {
regex: RegExp,
ignoreQuery?: boolean
}
export interface MaxAgeRegexRule extends RegexRule{
maxAge: number
}
export interface DomainRule {
domain: string | RegExp,
rules: T[]
}
export interface CacheRules{
maxAge: DomainRule[],
always: DomainRule[],
never: DomainRule[],
default: string
}
For those with no typescript knowledge , here is an example:
var cacheRules = {
maxAge: [
{
domain: /code\.jquery\.com/,
rules: [
regex: /.*/,
maxAge: 2592000
]
}
],
always: [
{
domain: /.*/,
rules: [
{ regex: /\.gif$/ }
]
}
],
never: [],
default: 'never'
}
In this example, every url coming from cdn.jquery.com will be cached for 30 days, all url ending with .gif will be stored indefinitvely, and every thing else will be excluded from caching.
Several cacheEngines can share the same instance, which helps improves performances. Although it isn't not really possible yet to share cache between different instance, it is on the roadmap.
//will loads the CacheRules related to REST caching strategies
const instance1 = new Instance('REST', redisConf, err =>{});
//will loads the CacheRules related to HTML caching strategies
const instance2 = new Instance('HTML', redisConf, err =>{});
// cacheEngine 1 & 2 will share the same instance
const cacheEngine1 = new CacheEngine('http://domain1.com', instance1);
const cacheEngine2 = new CacheEngine('http://domain2.com', instance1);
// While cacheEngine 3 will have its own storage space
const cacheEngine3 = new CacheEngine('http://domain1.com', instance2);
This helps to logically cluster Redis storage as well as complex Cache Rule configs in very complex scenarios
constructor(instanceName: string, redisConfig: RedisStorageConfig, config: InstanceConfig, function(err) {})
Loads a CacheRules from Redis with the redisConfig provided.
InstanceConfig Defines some mandatory behavior
interface InstanceConfig {
on_existing_regex?: 'error' | 'ignore' | 'replace'
on_publish_update?: boolean // when the cacheEngine.publish( is called, will scann all existing created url objects, and re-calculate the url's category
}
on_existing_regex: when adding a regex with CacheRuleManager's methods, and an existing Regex is found, either replace it, ignore it, or throws an error
on_publish_update:
when the instance.publish() is called, it will scan all existing created url objects, and re-calculate the url's category
This can have some performances issues in the scenario when your script creates plenty of url in the same runtime,
because it forces the CacheEngine to keep an array listing all urls created in memory.
Example:
const instance = new Instance('HTML', redisConfig, {on_publish_update: true, (err) => {})
const cacheEngine = new CacheEngine('localhost', instance);
const url = cacheEngine.url('/someUrl.html');
//Let's assume the that CacheRule Config mark this url's category as never
const cacheRuleManager = instance.getManager();
//Let's change this url's category dynamically
cacheRuleManager.removeAll()
cacheRuleManager.setDefault('always');
instance.publish();
// at this stage, url's category is now 'always'
// withouth on_publish_update, we would have to manually run to update it.
url.setCacheCategory();
getInstanceName(): string
Returns the name of the instance
getConfig(): CacheRules
Returns the cache rules definition asociated with this instance. It is usefull for cache rule backup - or if you need to build a cache rule UI
getManager(): CacheRuleManager
Returns the Cache rule Manager associated with this instance
A typical usage would be to edit the cache rules definition.
pubish():void
When the Cache Rule Manager associated with this instance has been modified, calling this method will save the changes in the storage and propagate the changes to all open instances
Example
//File A.js on server 1
var instance = new Instance('STORAGE', redisConfig, instanceConfig, function(err) {
if(err) throw err;
var ruleManager = instance.getManager();
ruleManager.setDefault('always'); // We assume it was previously set to `never`
instance.publish();
// Will propagate config changes to all instanciated instances STORAGE.
}
//File B.js on server 2
var instance = new Instance('STORAGE', redisConfig, instanceConfig, function(err) {
if(err) throw err;
var cacheEngine = new CacheEngineCB('domain', instance);
var url1 = new url('http://domain.com/some-un-matched-url.html');
console.log(url1.getCategory());
// `never`
setTimeout( function(){
var url2 = new url('http://domain.com/some-un-matched-url.html');
console.log(url2.getCategory());
// `always`
}, 10000);
setTimeout( function(){
console.log(url1.getCategory());
// `always` or `never` depending on the instanceConfig.on_publish_update value
});
}
UrlCB is the class name for callback support while UrlPromise is the one associated for promises
Internally, UrlPromise ses UrlCB's code. For this reason, we will document only UrlCB's API.
To transpose UrlCb API to UrlPromise API, it is easy to remember that we follow the node.js classic callback parameter order (err, value), with err first.
The promise will return the value on success, and the error on rejection. Example:
var urlCB = cacheEngineCB.url('http://someURL');
var urlPromise = cacheEnginePromise.url('http://someURL');
urlCB.has( (err: string | Error, has: boolean) => {
//do something
});
urlPromise.has().then ( (has: boolean) => {
//do something on success
}, (err: string | Error) => {
//do something on error
});
urlCB.get( (err: string | Error, content: IGetResults) => {
//do something
});
urlPromise.get().then ( (content: IGetResults) => {
//do something on success
}, (err: string | Error) => {
//do something on error
});
url.delete( callback: Function(err: string) )
Deletes a stored url. Will return an error string if the url doesnt exists or for a redis error
url.has( callback: Fuction(err: string, has: boolean) )
Checks if the url is cached.
url.get( callback: Function(err: string, content: IGetResults) )
Retrieves the cached url. If the url is not cached, will return an 'err'
The structure of the content: IGetResults is:
interface IGetResults {
content: string, //the URL file content
createdOn: number, // Cacheing timestamp
extra: any //Any SONmobject stored alongside the URL content
}
url.set(htmlContent: string, extra: Object, force: boolean, callback: Function(err, result: boolean))
Conditionally stores a URL depending on matching rules
htmlContent
url.getDomain(): string
returns the domain name associated with this URL
url.getUrl(): string
Returns the url path. For example:
var url = cacheEngine.url('http://domain.com/some/path.html');
console.log(url.getUrl());
// /some/path.html
url.getCategory(): string
Returns the computed url category. Either always, never or maxAge
url.getTTL(): number
Returns a positive number (seconds) if the url category is maxAge, 0 otherwise
url.getInstanceName(): string
returns the instanceName associated with this urlCB | urlPromise object