Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: update shutdown process #1813

Merged
merged 11 commits into from
Sep 6, 2023
6 changes: 0 additions & 6 deletions packages/auth/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ import { InteractionRoutes } from './interaction/routes'

export interface AppContextData extends DefaultContext {
logger: Logger
closeEmitter: EventEmitter
container: AppContainer
// Set by @koa/router
params: { [key: string]: string }
Expand Down Expand Up @@ -88,7 +87,6 @@ export interface DatabaseCleanupRule {
export interface AppServices {
logger: Promise<Logger>
knex: Promise<Knex>
closeEmitter: Promise<EventEmitter>
config: Promise<IAppConfig>
clientService: Promise<ClientService>
grantService: Promise<GrantService>
Expand All @@ -106,7 +104,6 @@ export class App {
private introspectionServer!: Server
private adminServer!: Server
public apolloServer!: ApolloServer
private closeEmitter!: EventEmitter
private logger!: Logger
private config!: IAppConfig
private databaseCleanupRules!: {
Expand All @@ -124,7 +121,6 @@ export class App {
*/
public async boot(): Promise<void> {
this.config = await this.container.use('config')
this.closeEmitter = await this.container.use('closeEmitter')
this.logger = await this.container.use('logger')

this.databaseCleanupRules = {
Expand Down Expand Up @@ -374,7 +370,6 @@ export class App {
const koa = new Koa<DefaultState, AppContext>()

koa.context.container = this.container
koa.context.closeEmitter = await this.container.use('closeEmitter')
koa.context.logger = await this.container.use('logger')

koa.use(
Expand Down Expand Up @@ -402,7 +397,6 @@ export class App {
public async shutdown(): Promise<void> {
return new Promise((resolve): void => {
this.isShuttingDown = true
this.closeEmitter.emit('shutdown')

if (this.adminServer) {
this.adminServer.close((): void => {
Expand Down
2 changes: 0 additions & 2 deletions packages/auth/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ export function initIocContainer(
return db
})

container.singleton('closeEmitter', async () => new EventEmitter())

container.singleton('openPaymentsClient', async (deps) => {
const logger = await deps.use('logger')
return createOpenPaymentsClient({ logger })
Expand Down
1 change: 0 additions & 1 deletion packages/auth/src/tests/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export function createContext<T extends AppContext>(
ctx.params = params
ctx.query = reqOpts.query || {}
ctx.session = { ...req.session }
ctx.closeEmitter = new EventEmitter()
ctx.container = container
return ctx as T
}
Expand Down
64 changes: 35 additions & 29 deletions packages/backend/src/app.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { join } from 'path'
import http, { Server } from 'http'
import { EventEmitter } from 'events'
import { ParsedUrlQuery } from 'querystring'
import { Client as TigerbeetleClient } from 'tigerbeetle-node'

import { IocContract } from '@adonisjs/fold'
import { Knex } from 'knex'
Expand Down Expand Up @@ -74,10 +74,10 @@ import { CombinedPaymentService } from './open_payments/payment/combined/service
import { FeeService } from './fee/service'
import { AutoPeeringService } from './auto-peering/service'
import { AutoPeeringRoutes } from './auto-peering/routes'
import { Rafiki as ConnectorApp } from './connector/core'

export interface AppContextData {
logger: Logger
closeEmitter: EventEmitter
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wasn't used

container: AppContainer
// Set by @koa/router.
params: { [key: string]: string }
Expand Down Expand Up @@ -177,7 +177,6 @@ const PAYMENT_POINTER_PATH = '/:paymentPointerPath+'
export interface AppServices {
logger: Promise<Logger>
knex: Promise<Knex>
closeEmitter: Promise<EventEmitter>
config: Promise<IAppConfig>
httpTokenService: Promise<HttpTokenService>
assetService: Promise<AssetService>
Expand Down Expand Up @@ -207,21 +206,21 @@ export interface AppServices {
feeService: Promise<FeeService>
autoPeeringService: Promise<AutoPeeringService>
autoPeeringRoutes: Promise<AutoPeeringRoutes>
connectorApp: Promise<ConnectorApp>
tigerbeetle: Promise<TigerbeetleClient>
Comment on lines +209 to +210
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adds these services so they are properly typed when doing container.use

}

export type AppContainer = IocContract<AppServices>

export class App {
private openPaymentsServer!: Server
private ilpConnectorService!: Server
private adminServer!: Server
private autoPeeringServer!: Server
public apolloServer!: ApolloServer
public closeEmitter!: EventEmitter
public isShuttingDown = false
private logger!: Logger
private config!: IAppConfig
private outgoingPaymentTimer!: NodeJS.Timer
private deactivateInvoiceTimer!: NodeJS.Timer

public constructor(private container: IocContract<AppServices>) {}

Expand All @@ -233,7 +232,6 @@ export class App {
*/
public async boot(): Promise<void> {
this.config = await this.container.use('config')
this.closeEmitter = await this.container.use('closeEmitter')
this.logger = await this.container.use('logger')

// Workers are in the way during tests.
Expand All @@ -253,7 +251,7 @@ export class App {
}
}

public async startAdminServer(port: number | string): Promise<void> {
public async startAdminServer(port: number): Promise<void> {
const koa = await this.createKoaServer()
const httpServer = http.createServer(koa.callback())

Expand Down Expand Up @@ -321,7 +319,7 @@ export class App {
this.adminServer = httpServer.listen(port)
}

public async startOpenPaymentsServer(port: number | string): Promise<void> {
public async startOpenPaymentsServer(port: number): Promise<void> {
const koa = await this.createKoaServer()

const router = new Router<DefaultState, AppContext>()
Expand Down Expand Up @@ -482,7 +480,7 @@ export class App {
this.openPaymentsServer = koa.listen(port)
}

public async startAutoPeeringServer(port: number | string): Promise<void> {
public async startAutoPeeringServer(port: number): Promise<void> {
const koa = await this.createKoaServer()

const autoPeeringRoutes = await this.container.use('autoPeeringRoutes')
Expand All @@ -497,28 +495,37 @@ export class App {
this.autoPeeringServer = koa.listen(port)
}

public async startIlpConnectorServer(port: number): Promise<void> {
const ilpConnectorService = await this.container.use('connectorApp')
this.ilpConnectorService = ilpConnectorService.listenPublic(port)
}

public async shutdown(): Promise<void> {
return new Promise((resolve): void => {
this.isShuttingDown = true
this.closeEmitter.emit('shutdown')
this.isShuttingDown = true

if (this.openPaymentsServer) {
this.openPaymentsServer.close((): void => {
resolve()
})
}
if (this.openPaymentsServer) {
await this.stopServer(this.openPaymentsServer)
}
if (this.adminServer) {
await this.stopServer(this.adminServer)
}
if (this.ilpConnectorService) {
await this.stopServer(this.ilpConnectorService)
}
if (this.autoPeeringServer) {
await this.stopServer(this.autoPeeringServer)
}
}

if (this.adminServer) {
this.adminServer.close((): void => {
resolve()
})
}
private async stopServer(server: Server): Promise<void> {
return new Promise((resolve, reject) => {
server.close((err) => {
if (err) {
reject(err)
}

if (this.autoPeeringServer) {
this.autoPeeringServer.close((): void => {
resolve()
})
}
resolve()
})
})
}

Expand Down Expand Up @@ -583,7 +590,6 @@ export class App {
const koa = new Koa<DefaultState, AppContext>()

koa.context.container = this.container
koa.context.closeEmitter = await this.container.use('closeEmitter')
koa.context.logger = await this.container.use('logger')

koa.use(
Expand Down
30 changes: 14 additions & 16 deletions packages/backend/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { EventEmitter } from 'events'
import { Server } from 'http'
import path from 'path'
import createLogger from 'pino'
import { knex } from 'knex'
Expand Down Expand Up @@ -55,7 +53,6 @@ BigInt.prototype.toJSON = function () {

const container = initIocContainer(Config)
const app = new App(container)
let connectorServer: Server

export function initIocContainer(
config: typeof Config
Expand Down Expand Up @@ -106,7 +103,6 @@ export function initIocContainer(
)
return db
})
container.singleton('closeEmitter', async () => new EventEmitter())
container.singleton('redis', async (deps): Promise<Redis> => {
const config = await deps.use('config')
return new Redis(config.redisUrl, {
Expand Down Expand Up @@ -445,19 +441,12 @@ export const gracefulShutdown = async (
const logger = await container.use('logger')
logger.info('shutting down.')
await app.shutdown()
if (connectorServer) {
await new Promise((resolve, reject) => {
connectorServer.close((err?: Error) =>
err ? reject(err) : resolve(null)
)
})
}
const knex = await container.use('knex')
await knex.destroy()
const tigerbeetle = await container.use('tigerbeetle')
await tigerbeetle.destroy()
tigerbeetle.destroy()
const redis = await container.use('redis')
await redis.disconnect()
Comment on lines -458 to -460
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not async functions

redis.disconnect()
}

export const start = async (
Expand Down Expand Up @@ -493,6 +482,15 @@ export const start = async (
logger.info('received SIGTERM attempting graceful shutdown')

try {
if (shuttingDown) {
logger.warn(
'received second SIGTERM during graceful shutdown, exiting forcefully.'
)
process.exit(1)
}

shuttingDown = true

// Graceful shutdown
await gracefulShutdown(container, app)
logger.info('completed graceful shutdown.')
Expand All @@ -518,12 +516,12 @@ export const start = async (
const config = await container.use('config')
await app.boot()
await app.startAdminServer(config.adminPort)
await app.startOpenPaymentsServer(config.openPaymentsPort)
logger.info(`Admin listening on ${app.getAdminPort()}`)

await app.startOpenPaymentsServer(config.openPaymentsPort)
logger.info(`Open Payments listening on ${app.getOpenPaymentsPort()}`)

const connectorApp = await container.use('connectorApp')
connectorServer = connectorApp.listenPublic(config.connectorPort)
await app.startIlpConnectorServer(config.connectorPort)
logger.info(`Connector listening on ${config.connectorPort}`)
logger.info('🐒 has 🚀. Get ready for 🍌🍌🍌🍌🍌')

Expand Down
4 changes: 2 additions & 2 deletions packages/backend/src/shared/ilp_plugin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { LiquidityAccount } from '../accounting/service'
import { ConnectorAccount } from '../connector/core'

// Maybe @interledger/pay should export this interface.
export interface IlpPlugin {
Expand Down Expand Up @@ -37,6 +37,6 @@ export class OutgoingIlpPlugin implements IlpPlugin {
}

export interface IlpPluginOptions {
sourceAccount: LiquidityAccount
sourceAccount: ConnectorAccount
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updating to the the correct type

unfulfillable?: boolean
}
2 changes: 0 additions & 2 deletions packages/backend/src/tests/context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import EventEmitter from 'events'
import * as httpMocks from 'node-mocks-http'
import Koa from 'koa'
import { AppContext, AppContextData, AppRequest } from '../app'
Expand All @@ -18,6 +17,5 @@ export function createContext<T extends AppContext>(
if (reqOpts.body !== undefined) {
ctx.request.body = reqOpts.body
}
ctx.closeEmitter = new EventEmitter()
return ctx as T
}