2021-10-11 00:21:57 +00:00
import { performance } from 'perf_hooks'
2022-04-07 17:15:27 +00:00
import { Flaska , QueryHandler , JsonHandler , HttpError } from 'flaska'
2021-10-11 00:21:57 +00:00
import TestRoutes from './test/routes.mjs'
import MediaRoutes from './media/routes.mjs'
2021-07-03 13:56:53 +00:00
import config from './config.mjs'
2021-10-11 00:21:57 +00:00
2022-08-13 21:52:45 +00:00
export default class Server {
constructor ( http , port , core , opts = { } ) {
Object . assign ( this , opts )
this . http = http
this . port = port
this . core = core
2021-10-11 00:21:57 +00:00
2022-08-13 21:52:45 +00:00
this . jsonHandler = JsonHandler
this . queryHandler = QueryHandler
2021-10-11 00:21:57 +00:00
2022-08-13 21:52:45 +00:00
this . flaskOptions = {
log : this . core . log ,
2022-04-07 17:15:27 +00:00
}
2022-08-13 21:52:45 +00:00
this . routes = {
test : new TestRoutes ( ) ,
media : new MediaRoutes ( ) ,
2022-04-07 17:15:27 +00:00
}
2021-10-11 00:21:57 +00:00
}
2022-08-13 21:52:45 +00:00
run ( ) {
// Create our server
this . flaska = new Flaska ( this . flaskOptions , this . http )
// configure our server
if ( config . get ( 'NODE_ENV' ) === 'development' ) {
this . flaska . devMode ( )
}
this . flaska . before ( function ( ctx ) {
ctx . _ _started = performance . now ( )
ctx . log = ctx . log . child ( {
ip : ctx . req . headers [ 'x-forwarded-for' ] || ctx . req . connection . remoteAddress ,
} )
} )
2022-08-15 08:39:59 +00:00
let healthChecks = 0
2022-08-15 20:22:21 +00:00
let healthCollectLimit = 60 * 60 * 12
2022-08-13 21:52:45 +00:00
this . flaska . after ( function ( ctx ) {
let ended = performance . now ( ) - ctx . _ _started
let status = ''
let level = 'info'
if ( ctx . status >= 400 ) {
status = ctx . status + ' '
level = 'warn'
}
if ( ctx . status >= 500 ) {
level = 'error'
}
2022-08-15 08:39:59 +00:00
if ( ctx . url === '/health' ) {
healthChecks ++
2022-08-15 20:22:21 +00:00
if ( healthChecks >= healthCollectLimit ) {
2022-08-15 08:39:59 +00:00
ctx . log [ level ] ( {
duration : Math . round ( ended ) ,
status : ctx . status ,
} , ` <-- ${ status } ${ ctx . method } ${ ctx . url } {has happened ${ healthChecks } times} ` )
healthChecks = 0
}
return
}
2022-08-13 21:52:45 +00:00
ctx . log [ level ] ( {
duration : Math . round ( ended ) ,
status : ctx . status ,
} , ` <-- ${ status } ${ ctx . method } ${ ctx . url } ` )
} )
this . flaska . onerror ( function ( err , ctx ) {
if ( err . status && err . status >= 400 && err . status < 500 ) {
if ( err . body && err . body . request ) {
ctx . log . warn ( { request : err . body . request } , err . message )
} else {
ctx . log . warn ( err . message )
}
} else {
ctx . log . error ( err )
}
ctx . status = err . status || 500
if ( err instanceof HttpError ) {
ctx . body = err . body || {
status : ctx . status ,
message : err . message ,
}
} else {
ctx . body = {
status : ctx . status ,
message : err . message ,
}
}
} )
2021-10-11 00:21:57 +00:00
2022-08-13 21:52:45 +00:00
// Register our routes
let keys = Object . keys ( this . routes )
for ( let key of keys ) {
this . routes [ key ] . register ( this )
}
2021-10-11 00:21:57 +00:00
2022-08-13 21:52:45 +00:00
// Start listening
2021-10-11 00:21:57 +00:00
2022-08-13 21:52:45 +00:00
return this . flaska . listenAsync ( this . port ) . then ( ( ) => {
2022-08-14 00:03:57 +00:00
this . core . log . info ( { sites : Object . keys ( config . get ( 'sites' ) ) } , ` Server is listening on port ${ this . port } , uploading to ${ config . get ( 'uploadFolder' ) } for following sites ` )
2022-08-13 21:52:45 +00:00
} )
}
}