Skip to content
Snippets Groups Projects
server.js 2.31 KiB
Newer Older
process.title = 'Jetsam API Server'
Louis's avatar
Louis committed

const redbird = require('redbird')
const Koa = require('koa')
const app = require('app')
const http = require('http')
const { config, env, fs, boot } = require('bootstrap')
const debug = require('debug')('server:boot')
const pkg = require('./package.json')
Louis's avatar
Louis committed

const Sentry = require('@sentry/node')
const Tracing = require("@sentry/tracing");
let server = null
let worker = null
function bindSentry(app) {
	const sentryUtil = require('vendor/sentry')
	sentryUtil.configure()
	debug('Binding sentry to app level errors')

	app.on("error", (err, ctx) => {
		console.error(err)
		Sentry.withScope(function(scope) {
			scope.addEventProcessor(function(event) {
				return Sentry.Handlers.parseRequest(event, ctx.request);
			});
			Sentry.captureException(err);
		});
	});
}

async function launch(port = 0, host = config('app.host.web', `http://localhost:${ port }`)) {
	const koa = new Koa()
	const appserver = await app(koa)

	if (config('sentry.enabled')) {
		bindSentry(koa)
	}

	const httpServer = http.createServer(appserver.callback())
	httpServer.listen(port)
	debug(`Listening on ${ host }`)

	server = httpServer

	maybeSpawnWorker()

	return httpServer
}

async function runProxy() {
	const port = config('app.port')
	const proxy = redbird({ port, bunyan: false })
	const hosts = config('services.proxy.hosts')

	await launch()

	const address = server.address()
	if (!address) {
		throw new Error('Failed to start')
	}

	debug(`Binding hosts [${ hosts.join(', ') }] to server port ${ address.port}`)
	for (const host of hosts) {
		proxy.register(host, `http://127.0.0.1:${ address.port }`)
	}
}

function maybeSpawnWorker() {
	if (config('queue.driver') === 'async') {
		debug('Spawning async worker')
		const bindQueue = require('core/utils/queue')
		const { queue } = require('services')

		bindQueue()
		worker = queue.listen()
	}
}

async function main() {
	await boot()

	if (config('services.proxy.enabled')) {
		return await runProxy()
	} else {
		return await launch(config('app.port'))
	}
Louis's avatar
Louis committed
}

main()
	.catch(e => {
		console.error(e)
		process.exit(1)
	})


const cleanupsigs = [
	'SIGINT',
	'SIGTERM',
	'SIGUSR2',
]

cleanupsigs.forEach(signal => {
	process.on(signal, () => {
		if (worker) {
			worker()
		}
		if (server) {
			server.close()
		}
		Sentry.close(2000).then(() => {
			process.exit(0)
		})
	})
Louis's avatar
Louis committed
})