Skip to content

Instantly share code, notes, and snippets.

@grimen
Last active October 23, 2016 20:23
Show Gist options
  • Save grimen/e253e8236add04a4eadb6df6f1da1f70 to your computer and use it in GitHub Desktop.
Save grimen/e253e8236add04a4eadb6df6f1da1f70 to your computer and use it in GitHub Desktop.
'use strict'
const cluster = require('cluster')
const assert = require('assert')
const util = require('util')
const os = require('os')
const PrettyError = require('pretty-error')
process.env.NODE_ENV = process.env.NODE_ENV || 'development'
process.env.NODE_CLUSTER = process.env.NODE_CLUSTER || process.env.WEB_CONCURRENCY // heroku
process.env.DEBUG = process.env.DEBUG || 'app*'
process.env.HOST = process.env.HOST || '0.0.0.0'
process.env.PORT = process.env.PORT || 1331
global.pe = new PrettyError()
pe.skipNodeFiles()
pe.skipPackage('babel-cli')
pe.skipPackage('promise')
pe.skipPackage('bluebird')
pe.skipPackage('express')
pe.start()
global.debug = require('debug')
debug.enable(process.env.DEBUG)
debug('app master')('env', util.inspect({
NODE_ENV: process.env.NODE_ENV,
NODE_CLUSTER: process.env.NODE_CLUSTER,
HOST: process.env.HOST,
PORT: process.env.PORT
}, false, null, true))
const clusterEnabled = /true|[1-9]+(?:[0-9]+)?/.test(process.env.NODE_CLUSTER)
if (clusterEnabled && cluster.isMaster) {
const concurrency = /true/.test(process.env.NODE_CLUSTER) ? os.cpus().length : parseInt(process.env.NODE_CLUSTER)
for (let i = 0; i < concurrency; i++) {
const host = '0.0.0.0'
const port = process.env.PORT // if different ports: parseInt(process.env.PORT) + i
const env = {
HOST: host,
PORT: port
}
debug('app master')('fork', i, env)
cluster.fork(env)
}
cluster.on('exit', (worker, code, signal) => {
debug('app master')('exit', `Worker ${worker.process.pid} died`)
})
process.on('uncaughtException', (err) => {
debug('app master')('error', `uncaughtException`, pe.render(err))
// handleError(err)
})
process.on('unhandledRejection', (err) => {
debug('app master')('error', `unhandledRejection`, pe.render(err))
// handleError(err)
})
process.on('beforeExit', (code) => {
debug('app master')('event', `beforeExit`, code)
})
process.on('exit', (code) => {
debug('app master')('event', `exit`, code)
})
process.on('SIGINT', () => {
debug('app master')('signal', `SIGINT`)
})
} else {
// require('babel-register')
require('./server')
}
{
"name": "GuessBrand-Redirect",
"version": "0.1.0",
"main": "index.js",
"scripts": {
"clean": "rm -rf build && mkdir build",
"start": "./node_modules/.bin/cross-env NODE_ENV=production NODE_CLUSTER=true ./node_modules/.bin/babel-node index.js",
"start-nf": "./node_modules/.bin/cross-env NODE_ENV=production NODE_CLUSTER=true ./node_modules/.bin/nf start",
"start-pm2": "./node_modules/.bin/cross-env NODE_ENV=production NODE_CLUSTER=true ./node_modules/.bin/pm2 start",
"start-dev": "./node_modules/.bin/cross-env NODE_ENV=development NODE_CLUSTER=false ./node_modules/.bin/babel-watch index.js",
"build": "npm run clean && ./node_modules/.bin/cross-env NODE_ENV=production NODE_CLUSTER=true ./node_modules/.bin/babel index.js server.js -d build",
"serve": "./node_modules/.bin/cross-env NODE_ENV=production NODE_CLUSTER=true node build/index.js",
"test": "./node_modules/.bin/cross-env NODE_ENV=test NODE_CLUSTER=false mocha --compilers js:babel-register",
"postinstall": "npm run build"
},
"engines": {
"node": "^6.0.0"
},
"dependencies": {
"babel-cli": "^6.16.0",
"babel-preset-es2015": "^6.16.0",
"babel-preset-stage-0": "^6.16.0",
"babel-register": "^6.16.3",
"cross-env": "^3.1.3",
"debug": "^2.2.0",
"express": "^4.14.0",
"foreman": "^2.0.0",
"http-status": "^0.2.3",
"morgan": "^1.7.0",
"pm2": "^2.0.18",
"pretty-error": "^2.0.2"
},
"devDependencies": {
"babel-eslint": "^7.0.0",
"babel-watch": "^2.0.3",
"chai": "^3.5.0",
"eslint": "^3.8.1",
"mocha": "^3.1.2"
}
}
'use strict'
import cluster from 'cluster'
import assert from 'assert'
import util from 'util'
import express from 'express'
import morgan from 'morgan'
import status from 'http-status'
if (typeof pe === 'undefined') {
const PrettyError = require('pretty-error')
const pe = new PrettyError()
pe.skipNodeFiles()
pe.skipPackage('babel-cli')
pe.skipPackage('promise')
pe.skipPackage('bluebird')
pe.skipPackage('express')
pe.start()
}
if (typeof debug === 'undefined') {
const debug = require('debug')
debug.enable(process.env.DEBUG || 'app*')
}
assert.ok(process.env.PORT, 'process.env.PORT')
assert.ok(process.env.HOST, 'process.env.HOST')
debug('app server')('env', util.inspect({
NODE_ENV: process.env.NODE_ENV,
HOST: process.env.HOST,
PORT: process.env.PORT
}, false, null, true))
const app = express()
app.set('workerId', cluster.worker ? ` ${cluster.worker.id}` : '')
app.use(morgan('dev'))
app.get('/', (req, res) => {
debug(`app server${app.get('workerId')}`)(`GET /`, `url`, req.query.url)
if (req.query.url) {
res.redirect(req.query.url)
} else {
res.set('Content-Type', 'text/plain')
res.end(`Specify \`url\` param for redirect.`)
}
})
app.use((req, res, next) => {
let err = new Error(status[404])
// err.level = 'info'
// err.request = req
// err.response = res
// debug(`app server${app.get('workerId')}`)('error', err.level, pe.render(err))
// handleError(err)
res.set('Content-Type', 'text/plain')
res.status(404).end(`${404} ${status[404]}`)
})
app.use((err, req, res, next) => {
debug(`app server${app.get('workerId')}`)('error', err)
// err.level = 'critical'
// err.request = req
// err.response = res
// debug(`app server${app.get('workerId')}`)('error', err.level, pe.render(err))
// handleError(err)
res.set('Content-Type', 'text/plain')
res.status(res.status || 500).end(`${res.status || 500} ${status[res.status || 500]}`)
})
app.listen(parseInt(process.env.PORT), process.env.HOST, () => {
debug(`app server${app.get('workerId')}`)
('listen', `Worker${app.get('workerId')} listening on ${process.env.HOST}:${process.env.PORT}`)
})
'use strict'
import http from 'http'
import assert from 'assert'
import chai from 'chai'
process.env.PROTOCOL = `http`
process.env.HOST = `localhost`
process.env.PORT = 1331
process.env.NODE_ENV = 'test'
// import '../index'
// import '../server'
require('../index')
// require('../server') // BUG: when using `import '../server'` the `process.env.*` variables are not passed. =S
const endpoint = `${process.env.PROTOCOL}://${process.env.HOST}:${process.env.PORT}`
describe('GET /', () => {
it('should return status 200', done => {
http.get(`${endpoint}/`, res => {
assert.equal(200, res.statusCode)
done()
})
})
it('should return status 404', done => {
http.get(`${endpoint}/undefined`, res => {
assert.equal(404, res.statusCode)
done()
})
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment