Skip to content

Commit

Permalink
perf: cache process.env value to increase performance (#1238)
Browse files Browse the repository at this point in the history
  • Loading branch information
RomainLanz committed Jun 10, 2020
1 parent fac6bca commit 291399a
Show file tree
Hide file tree
Showing 8 changed files with 28 additions and 51 deletions.
10 changes: 6 additions & 4 deletions providers/AppProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { HealthCheck } from '../src/HealthCheck'
import envChecker from '../src/HealthCheck/Checkers/Env'
import appKeyChecker from '../src/HealthCheck/Checkers/AppKey'
import { HttpExceptionHandler } from '../src/HttpExceptionHandler'
import { EnvContract } from '@ioc:Adonis/Core/Env'

/**
* The application provider that sticks all core components
Expand Down Expand Up @@ -106,10 +107,11 @@ export default class AppProvider {
* Registers base health checkers
*/
protected registerHealthCheckers () {
this.container.with(['Adonis/Core/HealthCheck'], (healthCheck: HealthCheck) => {
envChecker(healthCheck)
appKeyChecker(healthCheck)
})
this.container.with(['Adonis/Core/Env', 'Adonis/Core/HealthCheck'],
(env: EnvContract, healthCheck: HealthCheck) => {
envChecker(healthCheck, env.get('NODE_ENV', undefined) as string | undefined)
appKeyChecker(healthCheck, env.get('APP_KEY', undefined) as string | undefined)
})
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/HealthCheck/Checkers/AppKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ const DISPLAY_NAME = 'App Key Check'
* Check for the APP_KEY to ensure it is present and has
* desired length.
*/
export default function addAppKeyChecker (healthCheck: HealthCheckContract) {
export default function addAppKeyChecker (healthCheck: HealthCheckContract, appKey?: string) {
healthCheck.addChecker('appKey', async () => {
if (!process.env.APP_KEY) {
if (!appKey) {
return {
displayName: DISPLAY_NAME,
health: {
Expand All @@ -44,7 +44,7 @@ export default function addAppKeyChecker (healthCheck: HealthCheckContract) {
}
}

if (process.env.APP_KEY && process.env.APP_KEY.length < 32) {
if (appKey && appKey.length < 32) {
return {
displayName: DISPLAY_NAME,
health: {
Expand Down
8 changes: 4 additions & 4 deletions src/HealthCheck/Checkers/Env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { HealthCheckContract } from '@ioc:Adonis/Core/HealthCheck'
/**
* Message for missing app key
*/
const MISSING_APP_KEY_MESSAGE = [
const MISSING_NODE_ENV_MESSAGE = [
'Missing NODE_ENV environment variable.',
'It can make some parts of the application misbehave',
].join(' ')
Expand All @@ -23,9 +23,9 @@ const DISPLAY_NAME = 'Node Env Check'
* Register the `env` checker to ensure that `NODE_ENV` environment
* variable is defined.
*/
export default function addEnvChecker (healthCheck: HealthCheckContract) {
export default function addEnvChecker (healthCheck: HealthCheckContract, env?: string) {
healthCheck.addChecker('env', async () => {
return process.env.NODE_ENV ? {
return env ? {
displayName: DISPLAY_NAME,
health: {
healthy: true,
Expand All @@ -34,7 +34,7 @@ export default function addEnvChecker (healthCheck: HealthCheckContract) {
displayName: DISPLAY_NAME,
health: {
healthy: false,
message: MISSING_APP_KEY_MESSAGE,
message: MISSING_NODE_ENV_MESSAGE,
},
}
})
Expand Down
9 changes: 5 additions & 4 deletions src/HttpExceptionHandler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import { LoggerContract } from '@ioc:Adonis/Core/Logger'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { NODE_ENV } from '../utils'

/**
* Http exception handler serves as the base exception handler
Expand Down Expand Up @@ -56,7 +57,7 @@ export abstract class HttpExceptionHandler {
*/
protected disableStatusPagesInDevelopment: boolean = true

constructor (protected logger: LoggerContract) {
constructor (protected logger: LoggerContract, protected environement: string | undefined = NODE_ENV) {
}

/**
Expand Down Expand Up @@ -97,7 +98,7 @@ export abstract class HttpExceptionHandler {
* which the app is runing
*/
protected async makeJSONResponse (error: any, ctx: HttpContextContract) {
if (process.env.NODE_ENV === 'development') {
if (this.environement === 'development') {
ctx.response.status(error.status).send({
message: error.message,
stack: error.stack,
Expand All @@ -118,7 +119,7 @@ export abstract class HttpExceptionHandler {
errors: [
{
title: error.message,
...(process.env.NODE_ENV === 'development' ? { detail: error.stack } : {}),
...(this.environement === 'development' ? { detail: error.stack } : {}),
code: error.code,
status: error.status,
},
Expand All @@ -132,7 +133,7 @@ export abstract class HttpExceptionHandler {
*/
protected async makeHtmlResponse (error: any, ctx: HttpContextContract) {
if (
process.env.NODE_ENV === 'development' &&
this.environement === 'development' &&
(!this.expandedStatusPages[error.status] || this.disableStatusPagesInDevelopment)
) {
const Youch = require('youch')
Expand Down
3 changes: 3 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@

import { esmRequire, resolveFrom } from '@poppinss/utils'

export const APP_KEY = process.env.APP_KEY
export const NODE_ENV = process.env.NODE_ENV

/**
* Helper to know if error belongs to a missing module
* error
Expand Down
12 changes: 2 additions & 10 deletions test/app-key-checker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,9 @@ test.group('Env Health Checker', () => {
})

test('fail when APP_KEY is not secure', async (assert) => {
process.env.APP_KEY = '3910200'

const application = new Application(__dirname, new Ioc(), {}, {})
const healthCheck = new HealthCheck(application)
appKeyHealthChecker(healthCheck)
appKeyHealthChecker(healthCheck, '3910200')

const report = await healthCheck.getReport()
assert.deepEqual(report.report, {
Expand All @@ -50,16 +48,12 @@ test.group('Env Health Checker', () => {
},
},
})

delete process.env.APP_KEY
})

test('work fine when APP_KEY is secure', async (assert) => {
process.env.APP_KEY = 'asecureandlongrandomsecret'

const application = new Application(__dirname, new Ioc(), {}, {})
const healthCheck = new HealthCheck(application)
appKeyHealthChecker(healthCheck)
appKeyHealthChecker(healthCheck, 'asecureandlongrandomsecret')

const report = await healthCheck.getReport()
assert.deepEqual(report.report, {
Expand All @@ -72,7 +66,5 @@ test.group('Env Health Checker', () => {
},
},
})

delete process.env.APP_KEY
})
})
10 changes: 1 addition & 9 deletions test/env-health-checker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ import envHealthChecker from '../src/HealthCheck/Checkers/Env'

test.group('Env Health Checker', () => {
test('fail when NODE_ENV is not defined', async (assert) => {
const oldEnvValue = process.env.NODE_ENV
delete process.env.NODE_ENV

const application = new Application(__dirname, new Ioc(), {}, {})
const healthCheck = new HealthCheck(application)
envHealthChecker(healthCheck)
Expand All @@ -33,15 +30,12 @@ test.group('Env Health Checker', () => {
},
},
})

process.env.NODE_ENV = oldEnvValue
})

test('work fine when NODE_ENV is defined', async (assert) => {
process.env.NODE_ENV = 'development'
const application = new Application(__dirname, new Ioc(), {}, {})
const healthCheck = new HealthCheck(application)
envHealthChecker(healthCheck)
envHealthChecker(healthCheck, 'development')

const report = await healthCheck.getReport()
assert.deepEqual(report.report, {
Expand All @@ -52,7 +46,5 @@ test.group('Env Health Checker', () => {
},
},
})

delete process.env.NODE_ENV
})
})
21 changes: 4 additions & 17 deletions test/exception-handler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,6 @@ test.group('HttpExceptionHandler', () => {
})

test('return stack trace when NODE_ENV=development', async (assert) => {
process.env.NODE_ENV = 'development'
class AppHandler extends HttpExceptionHandler {
protected context () {
return { username: 'virk' }
Expand All @@ -259,7 +258,7 @@ test.group('HttpExceptionHandler', () => {
}

const logger = new FakeLogger(loggerConfig)
const handler = new AppHandler(logger)
const handler = new AppHandler(logger, 'development')

const ctx = HttpContext.create(
'/',
Expand All @@ -273,12 +272,9 @@ test.group('HttpExceptionHandler', () => {

await handler.handle(new InvalidAuth('bad request'), ctx)
assert.exists(ctx.response.lazyBody!.args[0].stack)

delete process.env.NODE_ENV
})

test('print youch html in development', async (assert) => {
process.env.NODE_ENV = 'development'
class AppHandler extends HttpExceptionHandler {
protected context () {
return { username: 'virk' }
Expand All @@ -289,7 +285,7 @@ test.group('HttpExceptionHandler', () => {
}

const logger = new FakeLogger(loggerConfig)
const handler = new AppHandler(logger)
const handler = new AppHandler(logger, 'development')

const ctx = HttpContext.create(
'/',
Expand All @@ -303,8 +299,6 @@ test.group('HttpExceptionHandler', () => {

await handler.handle(new InvalidAuth('bad request'), ctx)
assert.isTrue(/youch/.test(ctx.response.lazyBody!.args[0]))

delete process.env.NODE_ENV
})

test('call handle on actual exception when method exists', async (assert) => {
Expand Down Expand Up @@ -451,8 +445,6 @@ test.group('HttpExceptionHandler', () => {
})

test('do not render status page when disabled for development mode', async (assert) => {
process.env.NODE_ENV = 'development'

class AppHandler extends HttpExceptionHandler {
protected statusPages = {
404: '404.edge',
Expand All @@ -472,7 +464,7 @@ test.group('HttpExceptionHandler', () => {
}

const logger = new FakeLogger(loggerConfig)
const handler = new AppHandler(logger)
const handler = new AppHandler(logger, 'development')

const ctx = HttpContext.create(
'/',
Expand All @@ -493,15 +485,11 @@ test.group('HttpExceptionHandler', () => {

assert.isTrue(/youch/.test(ctx.response.lazyBody!.args[0]))
assert.equal(ctx.response.response.statusCode, 404)

delete process.env.NODE_ENV
})

test('always render status page when in production mode', async (assert) => {
assert.plan(3)

process.env.NODE_ENV = 'production'

class AppHandler extends HttpExceptionHandler {
protected statusPages = {
404: '404.edge',
Expand All @@ -521,7 +509,7 @@ test.group('HttpExceptionHandler', () => {
}

const logger = new FakeLogger(loggerConfig)
const handler = new AppHandler(logger)
const handler = new AppHandler(logger, 'production')

const ctx = HttpContext.create(
'/',
Expand All @@ -542,7 +530,6 @@ test.group('HttpExceptionHandler', () => {
await handler.handle(new InvalidAuth('bad request'), ctx)

assert.equal(ctx.response.response.statusCode, 404)
delete process.env.NODE_ENV
})

test('compute status pages from expression', async (assert) => {
Expand Down

0 comments on commit 291399a

Please sign in to comment.