node-appstate
Application state handler without dependency
npm i @vanioinformatika/appstate
Initialization without callback (logger):
const appState =
Initialization with a simple logger:
const appState = { console}
This example is always logging the application state change.
You have two variables:
-
appState: application state
-
newAppState: new application state
You can use any logger library, for example pino.
let logger = const appState = { logger}
Changing application state.
const appState = appStateappStateappStateappStateappState
Checking application state (recommended).
const appState = appStateappStateappStateappStateappState
Reading application state.
const appState = let applicationState = appState
Listing state values.
const appState = let applicationStateValues = appState
Application state values are 'INIT', 'ERROR', 'RUNNING', 'STOPPED', 'FATAL'
Debug
Turn on debugging with env. variable: DEBUG=appState
Debug messages are:
State machine
States:
- INIT - Default state, application is starting, initialization: starting phase (app doesn't handle request)
- RUNNING - application is running
- STOPPED - application is running, but programmatically stopped
- ERROR - application is running, but has a critical error (e.g.: DB connection error): app doesn't serve requests
- FATAL - application doesn't serve request, and never comes to RUNNING state, all other state changes ignored
State machine:
-
INIT -> [INIT, RUNNING, STOPPED, ERROR, FATAL]
-
RUNNING -> [INIT, RUNNING, STOPPED, ERROR, FATAL]
-
STOPPED -> [INIT, RUNNING, STOPPED, ERROR, FATAL]
-
ERROR -> [INIT, RUNNING, STOPPED, ERROR, FATAL]
-
FATAL -> [FATAL]
Best practice
Turn on DEBUG on test environment and check debug messages.
Invalid state changes doesn't throw error, but ignored and logged.
Use a /health endpoint for load-balancers, and set to UP, if appState.isRunning()
, else DOWN.
You can change anytime the application state, for example under initialization process: persistent DB connection error => appState.error()
TypeScript example
- Creating a module, for example appState.ts:
// init application state handler with loggerconst init = logger: PinoLogger: { return }
- Import to, and using in index.ts:
// initialized with loggerconst appStateInstance: AppStateInstance = appState // ... and later you can use it anywhereprocess