Commit b3f9bdef authored by Kelvin Fichter's avatar Kelvin Fichter

feat(cmn): gracefully handle BaseServiceV2 exits

Gracefully handles BaseServiceV2 exits by default. Adds a new function
for stopping the service and catches SIGTERM and SIGINT correctly.
parent b5dd1f9f
---
'@eth-optimism/common-ts': patch
---
Have BaseServiceV2 gracefully catch exit signals
......@@ -52,6 +52,16 @@ export abstract class BaseServiceV2<
*/
protected loopIntervalMs: number
/**
* Whether or not the service is currently running.
*/
protected running: boolean
/**
* Whether or not the service has run to completion.
*/
protected done: boolean
/**
* Logger class for this service.
*/
......@@ -181,14 +191,24 @@ export abstract class BaseServiceV2<
}, {}) as TMetrics
this.logger = new Logger({ name: params.name })
// Gracefully handle stop signals.
const stop = async (signal: string) => {
this.logger.info(`stopping service`, { signal })
await this.stop()
process.exit(0)
}
process.on('SIGTERM', stop)
process.on('SIGINT', stop)
}
/**
* Runs the main function. If this service is set up to loop, will repeatedly loop around the
* main function. Will also catch unhandled errors.
*/
public run(): void {
const _run = async () => {
public async run(): Promise<void> {
this.done = false
if (this.init) {
this.logger.info('initializing service')
await this.init()
......@@ -197,7 +217,8 @@ export abstract class BaseServiceV2<
if (this.loop) {
this.logger.info('starting main loop')
while (true) {
this.running = true
while (this.running) {
try {
await this.main()
} catch (err) {
......@@ -208,16 +229,30 @@ export abstract class BaseServiceV2<
})
}
// Always sleep between loops
// Sleep between loops if we're still running (service not stopped).
if (this.running) {
await sleep(this.loopIntervalMs)
}
}
} else {
this.logger.info('running main function')
await this.main()
}
this.done = true
}
_run()
/**
* Tries to gracefully stop the service. Service will continue running until the current loop
* iteration is finished and will then stop looping.
*/
public async stop(): Promise<void> {
this.running = false
// Wait until the main loop has finished.
while (!this.done) {
await sleep(1000)
}
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment