update graceful shutdown
This commit is contained in:
@ -28,6 +28,7 @@ import { SetClaimsRole } from './utils/dictionary'
|
||||
import { logger } from './utils/logger'
|
||||
import { ReadingProgressDataSource } from './datasources/reading_progress_data_source'
|
||||
import { createPrometheusExporterPlugin } from '@bmatei/apollo-prometheus-exporter'
|
||||
import { ApolloServerPlugin } from 'apollo-server-plugin-base'
|
||||
|
||||
const signToken = promisify(jwt.sign)
|
||||
const pubsub = createPubSubClient()
|
||||
@ -112,10 +113,20 @@ export function makeApolloServer(app: Express): ApolloServer {
|
||||
},
|
||||
})
|
||||
|
||||
// enforce usage limits for the API
|
||||
const usageLimitPlugin = (): ApolloServerPlugin<RequestContext> => {
|
||||
return {
|
||||
async requestDidStart(contextValue) {
|
||||
// get graphql query from the request
|
||||
console.log(contextValue)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const apollo = new ApolloServer({
|
||||
schema: schema,
|
||||
context: contextFunc,
|
||||
plugins: [promExporter],
|
||||
plugins: [promExporter, usageLimitPlugin],
|
||||
formatError: (err) => {
|
||||
logger.info('server error', err)
|
||||
Sentry.captureException(err)
|
||||
@ -124,6 +135,7 @@ export function makeApolloServer(app: Express): ApolloServer {
|
||||
},
|
||||
introspection: env.dev.isLocal,
|
||||
persistedQueries: false,
|
||||
stopOnTerminationSignals: false, // we handle this ourselves
|
||||
})
|
||||
|
||||
return apollo
|
||||
|
||||
@ -304,8 +304,19 @@ const main = async () => {
|
||||
|
||||
const gracefulShutdown = async (signal: string) => {
|
||||
console.log(`[queue-processor]: Received ${signal}, closing server...`)
|
||||
await new Promise<void>((resolve) => {
|
||||
server.close((err) => {
|
||||
console.log('[queue-processor]: Express server closed')
|
||||
if (err) {
|
||||
console.log('[queue-processor]: error stopping server', { err })
|
||||
}
|
||||
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
await worker.close()
|
||||
await redisDataSource.shutdown()
|
||||
await appDataSource.destroy()
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
|
||||
@ -47,11 +47,7 @@ import { apiLimiter, authLimiter } from './utils/rate_limit'
|
||||
|
||||
const PORT = process.env.PORT || 4000
|
||||
|
||||
export const createApp = (): {
|
||||
app: Express
|
||||
apollo: ApolloServer
|
||||
httpServer: Server
|
||||
} => {
|
||||
export const createApp = (): Express => {
|
||||
const app = express()
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
@ -136,10 +132,7 @@ export const createApp = (): {
|
||||
res.end(await prom.register.metrics())
|
||||
})
|
||||
|
||||
const apollo = makeApolloServer(app)
|
||||
const httpServer = createServer(app)
|
||||
|
||||
return { app, apollo, httpServer }
|
||||
return app
|
||||
}
|
||||
|
||||
const main = async (): Promise<void> => {
|
||||
@ -154,19 +147,17 @@ const main = async (): Promise<void> => {
|
||||
await redisDataSource.initialize()
|
||||
}
|
||||
|
||||
const { app, apollo, httpServer } = createApp()
|
||||
|
||||
const app = createApp()
|
||||
const apollo = makeApolloServer(app)
|
||||
await apollo.start()
|
||||
apollo.applyMiddleware({ app, path: '/api/graphql', cors: corsConfig })
|
||||
|
||||
if (!env.dev.isLocal) {
|
||||
const mwLogger = loggers.get('express', { levels: config.syslog.levels })
|
||||
const transport = buildLoggerTransport('express')
|
||||
const mw = await lw.express.makeMiddleware(mwLogger, transport)
|
||||
app.use(mw)
|
||||
}
|
||||
const mwLogger = loggers.get('express', { levels: config.syslog.levels })
|
||||
const transport = buildLoggerTransport('express')
|
||||
const mw = await lw.express.makeMiddleware(mwLogger, transport)
|
||||
app.use(mw)
|
||||
|
||||
const listener = httpServer.listen({ port: PORT }, async () => {
|
||||
const listener = app.listen({ port: PORT }, async () => {
|
||||
const logger = buildLogger('app.dispatch')
|
||||
logger.notice(`🚀 Server ready at ${apollo.graphqlPath}`)
|
||||
})
|
||||
@ -181,15 +172,14 @@ const main = async (): Promise<void> => {
|
||||
listener.timeout = 640 * 1000 // match headersTimeout
|
||||
|
||||
const gracefulShutdown = async (signal: string) => {
|
||||
console.log(`[api]: Received ${signal}, closing server...`)
|
||||
await apollo.stop()
|
||||
console.log('[api]: Apollo server stopped')
|
||||
|
||||
console.log('[posthog]: flushing events')
|
||||
await analytics.shutdownAsync()
|
||||
console.log('[posthog]: events flushed')
|
||||
|
||||
console.log(`[api]: Received ${signal}, closing server...`)
|
||||
|
||||
await apollo.stop()
|
||||
console.log('[api]: Apollo server stopped')
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
listener.close((err) => {
|
||||
console.log('[api]: Express listener closed')
|
||||
|
||||
@ -7,16 +7,16 @@ export const mochaGlobalTeardown = async () => {
|
||||
await stopApolloServer()
|
||||
console.log('apollo server stopped')
|
||||
|
||||
await appDataSource.destroy()
|
||||
console.log('db connection closed')
|
||||
|
||||
if (env.redis.cache.url) {
|
||||
await redisDataSource.shutdown()
|
||||
console.log('redis connection closed')
|
||||
|
||||
if (redisDataSource.workerRedisClient) {
|
||||
await stopWorker()
|
||||
console.log('worker closed')
|
||||
}
|
||||
|
||||
await redisDataSource.shutdown()
|
||||
console.log('redis connection closed')
|
||||
}
|
||||
|
||||
await appDataSource.destroy()
|
||||
console.log('db connection closed')
|
||||
}
|
||||
|
||||
@ -2,11 +2,13 @@ import { ConnectionOptions, Job, QueueEvents, Worker } from 'bullmq'
|
||||
import { nanoid } from 'nanoid'
|
||||
import supertest from 'supertest'
|
||||
import { v4 } from 'uuid'
|
||||
import { makeApolloServer } from '../src/apollo'
|
||||
import { createWorker, QUEUE_NAME } from '../src/queue-processor'
|
||||
import { createApp } from '../src/server'
|
||||
import { corsConfig } from '../src/utils/corsConfig'
|
||||
|
||||
const { app, apollo } = createApp()
|
||||
const app = createApp()
|
||||
const apollo = makeApolloServer(app)
|
||||
export const request = supertest(app)
|
||||
let worker: Worker
|
||||
let queueEvents: QueueEvents
|
||||
|
||||
Reference in New Issue
Block a user