this.diag = diag || false
}
-Resources.prototype.ref = function(key, factory_func, destroy_func) {
+Resources.prototype.ref = async function(key, factory_func, destroy_func) {
result = this.map.get(key)
+ let value
if (result === undefined) {
- result = {refs: 0, value: factory_func(), destroy_func: destroy_func}
+ result = {
+ refs: 0,
+ value: factory_func(), // don't await it here
+ destroy_func: destroy_func
+ }
this.map.set(key, result)
+ try {
+ value = await result.value
+ }
+ catch (err) {
+ this.map.delete(key)
+ throw err
+ }
}
+ else
+ value = await result.value
result.refs += 1
if (this.diag)
console.log(`ref ${key} refs -> ${result.refs}`)
- return result.value
+ return value
}
-Resources.prototype.unref = function(key) {
+Resources.prototype.unref = async function(key) {
result = this.map.get(key)
assert(result !== undefined && result.refs > 0)
result.refs -= 1
if (this.diag)
console.log(`unref ${key} refs -> ${result.refs}`)
if (result.refs === 0) {
- if (result.destroy_func !== undefined)
- result.destroy_func(result.value)
this.map.delete(key)
+ if (result.destroy_func !== undefined)
+ try {
+ await result.destroy_func(await result.value)
+ }
+ catch (err) {
+ console.err(err.stack || err.message)
+ }
}
}
/*await*/ this.respond(request, response, listener.options.protocol)
}
-Server.prototype.start = function() {
+Server.prototype.start = async function() {
assert(this.jst_cache === undefined)
- this.jst_cache = this.resources.ref(
+ this.jst_cache = await this.resources.ref(
'jst_cache:.',
- () => new JSTCache('.', {_jst_server: jst_server}, true)
+ async () => new JSTCache('.', {_jst_server: jst_server}, true)
)
assert(this.listeners === undefined)
default:
assert(false)
}
- let listener = this.resources.ref(
+ let listener = await this.resources.ref(
`listener:${JSON.stringify(options)}`,
- () => new Listener(/*this.request_func*/undefined, options, true),
- listener => listener.stop() // ignore returned Promise
+ async () => new Listener(undefined, options, true),
+ listener => /*await*/ listener.stop()
)
listener.request_func = this.request_func
this.listeners.push(listener)
}
}
-Server.prototype.stop = function() {
+Server.prototype.stop = async function() {
assert(this.jst_cache !== undefined)
- this.resources.unref('jst_cache:.')
+ await this.resources.unref('jst_cache:.')
assert(this.listeners !== undefined)
for (let i = 0; i < this.listeners.length; ++i)
- this.resources.unref(
+ await this.resources.unref(
`listener:${JSON.stringify(this.listeners[i].options)}`
)
}
root = this.roots[host.root]
else {
root = {
- jst_cache: this.resources.ref(
+ jst_cache: await this.resources.ref(
`jst_cache:${host.root}`,
- () => new JSTCache(host.root, {_jst_server: jst_server}, true)
+ async () =>
+ new JSTCache(host.root, {_jst_server: jst_server}, true)
),
site: undefined
}
`${host.root}/_config/site.jst`,
true
)
- if (config !== undefined)
- root.site = await config(this.resources, host.root, root.site)
+ if (config !== undefined) {
+ // we should somehow block further config changes during this:
+ let prev_site = root.site
+ let site = await config(this.resources, host.root, prev_site)
+ await site.start()
+ root.site = site
+ if (prev_site !== undefined)
+ await prev_site.stop()
+ }
return root.site.respond(
{
parsed_url: parsed_url,
options || {}
)
+ this.json_cache = undefined
+ this.json_cache_rw = undefined
+ this.jst_cache = undefined
+ this.less_css_cache = undefined
+ this.min_css_cache = undefined
+ this.min_js_cache = undefined
+ this.min_html_cache = undefined
+ this.min_svg_cache = undefined
+ this.text_cache = undefined
+ this.zip_cache = undefined
+
this.socket_io_connect_listeners = [] // later will use this for destruction
- this.json_cache = resources.ref(
+}
+
+Site.prototype.start = async function() {
+ assert(this.json_cache === undefined)
+ this.json_cache = await this.resources.ref(
'json_cache',
- () => new JSONCache(true)
+ async () => new JSONCache(true)
)
- this.json_cache_rw = resources.ref(
+
+ assert(this.json_cache_rw === undefined)
+ this.json_cache_rw = await this.resources.ref(
'json_cache_rw',
- () => new JSONCacheRW(true)
+ async () => new JSONCacheRW(true)
)
- this.jst_cache = resources.ref(
- `jst_cache:${root}`,
- () => new JSTCache(root, {_jst_server: jst_server}, true)
+
+ assert(this.jst_cache === undefined)
+ this.jst_cache = await this.resources.ref(
+ `jst_cache:${this.root}`,
+ async () => new JSTCache(this.root, {_jst_server: jst_server}, true)
)
- this.less_css_cache = resources.ref(
- `less_css_cache:${root}`,
- () => new LessCSSCache(root, true)
+
+ assert(this.less_css_cache === undefined)
+ this.less_css_cache = await this.resources.ref(
+ `less_css_cache:${this.root}`,
+ async () => new LessCSSCache(this.root, true)
)
- this.min_css_cache = resources.ref(
+
+ assert(this.min_css_cache === undefined)
+ this.min_css_cache = await this.resources.ref(
'min_css_cache',
- () => new MinCSSCache(true)
+ async () => new MinCSSCache(true)
)
- this.min_js_cache = resources.ref(
+
+ assert(this.min_js_cache === undefined)
+ this.min_js_cache = await this.resources.ref(
'min_js_cache',
- () => new MinJSCache(true)
+ async () => new MinJSCache(true)
)
- this.min_html_cache = resources.ref(
+
+ assert(this.min_html_cache === undefined)
+ this.min_html_cache = await this.resources.ref(
'min_html_cache',
- () => new MinHTMLCache(true)
+ async () => new MinHTMLCache(true)
)
- this.min_svg_cache = resources.ref(
+
+ assert(this.min_svg_cache === undefined)
+ this.min_svg_cache = await this.resources.ref(
'min_svg_cache',
- () => new MinSVGCache(true)
+ async () => new MinSVGCache(true)
)
- this.text_cache = resources.ref(
+
+ assert(this.text_cache === undefined)
+ this.text_cache = await this.resources.ref(
'text_cache',
- () => new TextCache(true)
+ async () => new TextCache(true)
)
- this.zip_cache = resources.ref(
+
+ assert(this.zip_cache === undefined)
+ this.zip_cache = await this.resources.ref(
'zip_cache',
- () => new ZipCache(true)
+ async () => new ZipCache(true)
)
}
-Site.prototype = Object.create(Site.prototype)
+Site.prototype.stop = async function() {
+ assert(this.json_cache !== undefined)
+ await this.resources.unref('json_cache')
+
+ assert(this.json_cache_rw !== undefined)
+ await this.resources.unref('json_cache_rw')
+
+ assert(this.jst_cache !== undefined)
+ await this.resources.unref(`jst_cache:${this.root}`)
+
+ assert(this.less_css_cache !== undefined)
+ await this.resources.unref(`less_css_cache:${this.root}`)
+
+ assert(this.min_css_cache !== undefined)
+ await this.resources.unref('min_css_cache')
+
+ assert(this.min_js_cache !== undefined)
+ await this.resources.unref('min_js_cache')
+
+ assert(this.min_html_cache !== undefined)
+ await this.resources.unref('min_html_cache')
+
+ assert(this.min_svg_cache !== undefined)
+ await this.resources.unref('min_svg_cache')
+
+ assert(this.text_cache !== undefined)
+ await this.resources.unref('text_cache')
+
+ assert(this.zip_cache !== undefined)
+ await this.resources.unref('zip_cache')
+}
Site.prototype.serve_internal = function(response, status, mime_type, data) {
response.statusCode = status
let Resources = require('./Resources')
let Server = require('./Server')
-let resources = new Resources()
-let jst_cache = resources.ref(
- 'jst_cache:.',
- () => new JSTCache('.', {_jst_server: jst_server}, true)
-)
-let server = undefined
+;(
+ async () => {
+ let resources = new Resources()
+ let jst_cache = await resources.ref(
+ 'jst_cache:.',
+ async () => new JSTCache('.', {_jst_server: jst_server}, true)
+ )
+ let server = undefined
-// refresh the config immediately, then every 5 seconds,
-// use setTimeout() instead of setInterval() to avoid bunches
-// of calls after the computer has been suspended for a while
-let refresh_config = async () => {
- let config = await jst_cache.get('_config/server.jst', true)
- if (config !== undefined) {
- let prev_server = server
- server = await config(resources, prev_server)
- await server.start()
- if (prev_server !== undefined)
- await prev_server.stop()
+ // refresh the config immediately, then every 5 seconds,
+ // use setTimeout() instead of setInterval() to avoid bunches
+ // of calls after the computer has been suspended for a while
+ let refresh_config = async () => {
+ let config = await jst_cache.get('_config/server.jst', true)
+ if (config !== undefined) {
+ let prev_server = server
+ server = await config(resources, prev_server)
+ await server.start()
+ if (prev_server !== undefined)
+ await prev_server.stop()
+ }
+ server.kick()
+ setTimeout(refresh_config, 5000)
+ // returned Promise will be ignored
+ }
+ refresh_config()
}
- server.kick()
- setTimeout(refresh_config, 5000)
- // returned Promise will be ignored
-}
-refresh_config()
+)()