-
Yannis Barlas authoredf1214e29
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
startServer.js 4.87 KiB
const express = require('express')
const { promisify } = require('util')
const http = require('http')
const config = require('config')
const passport = require('passport')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const helmet = require('helmet')
const morgan = require('morgan')
const logger = require('./logger')
const { logInit, logTask, logTaskItem } = require('./logger/internals')
const { migrate } = require('./dbManager/migrate')
const { startJobQueue, subscribeJobsToQueue, stopJobQueue } = require('./jobs')
const { connectToFileStorage } = require('./services/fileStorage')
const api = require('./routes/api')
const authentication = require('./authentication')
const healthcheck = require('./healthcheck')
const seedGlobalTeams = require('./startup/seedGlobalTeams')
const ensureTempFolderExists = require('./startup/ensureTempFolderExists')
const checkConfig = require('./startup/checkConfig')
const errorStatuses = require('./startup/errorStatuses')
const mountStatic = require('./startup/static')
const registerComponents = require('./startup/registerComponents')
const { cors } = require('./startup/cors')
const {
runCustomStartupScripts,
runCustomShutdownScripts,
} = require('./startup/customScripts')
let server
let useJobQueue = true
let useGraphQLServer = true
if (config.has('useJobQueue') && config.get('useJobQueue') === false) {
useJobQueue = false
}
if (
config.has('useGraphQLServer') &&
config.get('useGraphQLServer') === false
) {
useGraphQLServer = false
}
const startServer = async () => {
if (server) return server
const startTime = performance.now()
logInit('Coko server init tasks')
checkConfig()
if (config.has('useFileStorage') && config.get('useFileStorage')) {
await connectToFileStorage()
}
await ensureTempFolderExists()
await migrate()
await seedGlobalTeams()
const app = express()
await runCustomStartupScripts()
const port = config.port || 3000
app.set('port', port)
const httpServer = http.createServer(app)
httpServer.app = app
logTask(`Starting HTTP server`)
const startListening = promisify(httpServer.listen).bind(httpServer)
await startListening(port)
logTaskItem(`App is listening on port ${port}`)
app.use(bodyParser.json({ limit: '50mb' }))
app.use(bodyParser.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(helmet())
app.use(cors())
morgan.token('graphql', ({ body }, res, type) => {
if (!body.operationName) return ''
switch (type) {
case 'query':
return body.query.replace(/\s+/g, ' ')
case 'variables':
return JSON.stringify(body.variables)
case 'operation':
default:
return body.operationName
}
})
app.use(
morgan(
(config.has('morganLogFormat') && config.get('morganLogFormat')) ||
'combined',
{
stream: logger.stream,
},
),
)
mountStatic(app)
app.use(passport.initialize())
passport.use('bearer', authentication.strategies.bearer)
passport.use('anonymous', authentication.strategies.anonymous)
passport.use('local', authentication.strategies.local)
app.locals.passport = passport
registerComponents(app)
app.use('/api', api) // REST API
app.get('/healthcheck', healthcheck) // Server health endpoint
if (useGraphQLServer) {
/* eslint-disable-next-line global-require */
const gqlApi = require('./graphqlApi')
gqlApi(app)
}
errorStatuses(app)
if (useGraphQLServer) {
/* eslint-disable-next-line global-require */
const { addSubscriptions } = require('./graphql/subscriptions')
addSubscriptions(httpServer)
}
if (useJobQueue) {
await startJobQueue()
await subscribeJobsToQueue()
}
if (config.has('cron.path')) {
/* eslint-disable-next-line global-require, import/no-dynamic-require */
require(config.get('cron.path'))
}
server = httpServer
const endTime = performance.now()
const durationInSeconds = (endTime - startTime) / 1000 // Convert to seconds
logInit(
`Coko server init finished in ${durationInSeconds.toFixed(4)} seconds`,
)
return httpServer
}
const shutdown = async signal => {
logInit(`Coko server graceful shutdown after receiving signal ${signal}`)
const startTime = performance.now()
await runCustomShutdownScripts()
logTask('Shut down http server')
await server.close()
logTaskItem('Http server successfully shut down')
if (useJobQueue) {
logTask('Shut down job queue')
await stopJobQueue()
logTaskItem('Successfully shut down job queue')
}
const endTime = performance.now()
const durationInSeconds = (endTime - startTime) / 1000 // Convert to seconds
logInit(
`Coko server graceful shutdown finished in ${durationInSeconds.toFixed(
4,
)} seconds`,
)
process.exit()
}
process.on('SIGINT', () => shutdown('SIGINT'))
process.on('SIGTERM', () => shutdown('SIGTERM'))
module.exports = startServer