start-stop-state-machine
v1.2.0
Published
[![Node.js CI](https://github.com/digidem/start-stop-state-machine/workflows/Node.js%20CI/badge.svg)](https://github.com/digidem/start-stop-state-machine/actions/workflows/node.js.yml) [![Coverage Status](https://coveralls.io/repos/github/digidem/start-st
Downloads
789
Readme
start-stop-state-machine
A simple state machine for managing a service that asynchronously starts and stops.
Table of Contents
Install
npm install start-stop-state-machine
Usage
const StateMachine = require('start-stop-state-machine')
async function startService() {
console.log('starting')
await new Promise((res) => setTimeout(res, 200))
console.log('started')
}
async function stopService() {
console.log('stopping')
await new Promise((res) => setTimeout(res, 200))
console.log('stopped')
}
const sm = new StateMachine({ start: startService, stop: stopService })
;(async () => {
sm.start()
sm.start()
await sm.started()
// logs "starting" then "started", but only once
await sm.stop()
// lots "stopping", then "stopped"
})()
API
Table of Contents
ServiceState
Type: ({value: Exclude<ServiceStateValue, "error"
>} | {value: "error"
, error: Error})
ExternalEvents
Type: Object
StartStopStateMachine
Extends TypedEmitter
A state machine for managing a service that has asynchronous "start" and
"stop" methods. Create an instance passing async opts.start()
and
opts.stop()
methods. It manages state following some basic rules:
- Most importantly: You can call start() and stop() multiple times, but the
service will end in the state of the last call (e.g. if the last call was
to
stop()
then it will end up stopped) - Calling
start()
when the service is "stopped" calls theopts.start()
method and resolves when it completes. - Calling
start()
when the service is "starting" (e.g.start()
has been called but has not completed) will not callopts.start()
again, but will resolve once the service has started - Calling
start()
when the service is "started" will resolve immediately and do nothing. - If
opts.start()
oropts.stop()
throw, then the service is left in an unrecoverable "error" state. - Calling
start()
orstop()
when the service is in "error" state will throw with the error from the error state
Logic for calling stop()
follows the inverse of start()
.
To wait for the service to be in the "started" state from other methods, use
await stateMachine.started()
. Note that if the services is "stopping" or
"stopped" then this will await (e.g. queue) until next start
Parameters
opts
Object? (optional, default{}
)opts.start
(optional, defaultasync()=>{}
)opts.stop
(optional, defaultasync()=>{}
)
state
Get the current state of the service.
Returns ServiceState
started
Will resolve when the service is in started state. E.g. to ensure an async method only runs when the service is in "started" state, use:
await this.started()
Will reject if the service is in "error" state.
Note: If the service is in "stopping" or "stopped" state this will queue until the next time the service starts. If this is not desirable behaviour, check this.#state.value first
Returns Promise<void>
stopped
Will resolve when the service is in stopped state. Less useful than
started()
E.g. to ensure an async method only runs when the service is in
"stopped" state, use:
await this.stopped()
Will reject if the service is in "error" state.
Note: If the service is in "starting" or "started" state this will queue until the next time the service stops. If this is not desirable behaviour, check this.#state.value first
Returns Promise<void>
start
Start service. If the service is starting or started, will resolve when the service is started, and will not call opts.start() for than once. If the service is in the process of stopping, will wait until it stops before starting and will not call opts.stop() more than once
Parameters
args
TStartArgs
Returns Promise<void> Resolves when service is started
stop
Stop the service.
Parameters
args
TStopArgs
Returns Promise<void>
state
Type: ServiceState
emitter
Type: TypedEmitter<InternalEvents>
Maintainers
Contributing
PRs accepted.
Small note: If editing the README, please conform to the standard-readme specification.
License
MIT © 2022 Digital Democracy