https://github.com/vanioinformatika/node-appstate
Application state handler
https://github.com/vanioinformatika/node-appstate
Last synced: 4 months ago
JSON representation
Application state handler
- Host: GitHub
- URL: https://github.com/vanioinformatika/node-appstate
- Owner: vanioinformatika
- License: mit
- Created: 2018-05-25T15:35:01.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2023-01-06T14:29:29.000Z (almost 3 years ago)
- Last Synced: 2025-06-01T10:03:25.206Z (4 months ago)
- Language: JavaScript
- Size: 438 KB
- Stars: 0
- Watchers: 6
- Forks: 0
- Open Issues: 6
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# node-appstate
[](https://travis-ci.org/vanioinformatika/node-appstate)
Application state handler without dependency
---
`npm i @vanioinformatika/appstate`
Initialization without callback (logger):
```javascript
const appState = require('@vanioinformatika/appstate')()
```Initialization with a simple logger:
```javascript
const appState = require('@vanioinformatika/appstate')((appState, newAppState) => {
console.log(`App state has changed from ${appState} to ${newAppState}`)
})
```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.
```javascript
let logger = require('pino')()
const appState = require('@vanioinformatika/appstate')((appState, newAppState) => {
logger.warn(`App state has changed from ${appState} to ${newAppState}`)
})
```Changing application state.
```javascript
const appState = require('@vanioinformatika/appstate')()
appState.init()
appState.running()
appState.stopped()
appState.error()
appState.fatal()
```Checking application state (recommended).
```javascript
const appState = require('@vanioinformatika/appstate')()
appState.isInit()
appState.isRunning()
appState.isStopped()
appState.isError()
appState.isFatal()
```Reading application state.
```javascript
const appState = require('@vanioinformatika/appstate')()
let applicationState = appState.get()
```Listing state values.
```javascript
const appState = require('@vanioinformatika/appstate')()
let applicationStateValues = appState.list()
```**Application state values are 'INIT', 'ERROR', 'RUNNING', 'STOPPED', 'FATAL'**
## Debug
Turn on debugging with env. variable: `DEBUG=appState`
Debug messages are:
```javascript
debug('info: appState has already set: ' + newAppState)
debug('warn: invalid state changes from ' + appState + ' to ' + newAppState)
debug('warn: unknow appState: ' + newAppState)
```## 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 ignoredState 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
1. Creating a module, for example appState.ts:
```javascript
import * as AppState from '@vanioinformatika/appstate'
import { AppStateInstance } from '@vanioinformatika/appstate'
import * as Pino from 'pino'// init application state handler with logger
export const init = (logger: Pino.Logger): AppStateInstance => {
return AppState(
(appState: string, newAppState: string): void => {
if (newAppState === AppState.state.ERROR || newAppState === AppState.state.FATAL) {
logger.error(`appstate ${appState} to ${newAppState}`)
} else {
logger.warn(`appstate ${appState} to ${newAppState}`)
}
},
)
}
```2. Import to, and using in index.ts:
```javascript
import { AppStateInstance } from '@vanioinformatika/appstate'
import * as appState from './appstate'// initialized with logger
const appStateInstance: AppStateInstance = appState.init(logger)// ... and later you can use it anywhere
process.on(
'uncaughtException',
(err): void => {
appStateInstance.fatal()
// ...
},
)
```