优化订单流程与数据库关闭
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import type { Server } from 'node:http'
|
||||
|
||||
import { createShutdownController } from './shutdown.js'
|
||||
import type { StartupState } from './state.js'
|
||||
|
||||
function createStartupState(): StartupState {
|
||||
return {
|
||||
phase: 'ready',
|
||||
core: {
|
||||
running: false,
|
||||
ready: true,
|
||||
attemptCount: 1,
|
||||
lastAttemptAt: '',
|
||||
lastError: '',
|
||||
readyAt: '',
|
||||
},
|
||||
process: {
|
||||
lastUnhandledRejection: null,
|
||||
lastUncaughtException: null,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
test('shutdown closes the HTTP server and database pool', async () => {
|
||||
let serverClosed = false
|
||||
let databaseClosed = false
|
||||
const server = {
|
||||
listening: true,
|
||||
close(callback: (error?: Error) => void) {
|
||||
serverClosed = true
|
||||
callback()
|
||||
},
|
||||
} as unknown as Server
|
||||
const controller = createShutdownController(server, createStartupState(), {
|
||||
closeDatabase: async () => {
|
||||
databaseClosed = true
|
||||
},
|
||||
})
|
||||
|
||||
await controller.shutdown('test')
|
||||
|
||||
assert.equal(serverClosed, true)
|
||||
assert.equal(databaseClosed, true)
|
||||
assert.equal(controller.isShutdownStarted(), true)
|
||||
})
|
||||
|
||||
test('shutdown closes the database pool when the server is already stopped', async () => {
|
||||
let databaseClosed = false
|
||||
const server = {
|
||||
listening: false,
|
||||
close() {
|
||||
throw new Error('close should not be called')
|
||||
},
|
||||
} as unknown as Server
|
||||
const controller = createShutdownController(server, createStartupState(), {
|
||||
closeDatabase: async () => {
|
||||
databaseClosed = true
|
||||
},
|
||||
})
|
||||
|
||||
await controller.shutdown('test')
|
||||
|
||||
assert.equal(databaseClosed, true)
|
||||
})
|
||||
@@ -2,10 +2,19 @@ import type { Server } from 'node:http'
|
||||
|
||||
import { stopKuaishouIndustrySendCallbackRetryWorker } from '../services/platforms/kuaishou-industry/send-code-service.js'
|
||||
import { stopScheduledJobs } from '../services/scheduler/scheduler-service.js'
|
||||
import { closeDb } from '../db/client.js'
|
||||
import { logError, logInfo } from '../utils/logger.js'
|
||||
import type { StartupState } from './state.js'
|
||||
|
||||
export function createShutdownController(server: Server, startupState: StartupState) {
|
||||
type ShutdownOptions = {
|
||||
closeDatabase?: () => Promise<void>
|
||||
}
|
||||
|
||||
export function createShutdownController(
|
||||
server: Server,
|
||||
startupState: StartupState,
|
||||
{ closeDatabase = closeDb }: ShutdownOptions = {},
|
||||
) {
|
||||
let shutdownStarted = false
|
||||
|
||||
async function shutdown(signal: string) {
|
||||
@@ -20,20 +29,25 @@ export function createShutdownController(server: Server, startupState: StartupSt
|
||||
stopScheduledJobs()
|
||||
stopKuaishouIndustrySendCallbackRetryWorker()
|
||||
|
||||
if (!server.listening) {
|
||||
return
|
||||
if (server.listening) {
|
||||
await new Promise<void>((resolve) => {
|
||||
server.close((error) => {
|
||||
if (error) {
|
||||
logError('[shutdown]', 'failed to close HTTP server', error)
|
||||
process.exitCode = 1
|
||||
}
|
||||
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
server.close((error) => {
|
||||
if (error) {
|
||||
logError('[shutdown]', 'failed to close HTTP server', error)
|
||||
process.exitCode = 1
|
||||
}
|
||||
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
try {
|
||||
await closeDatabase()
|
||||
} catch (error) {
|
||||
logError('[shutdown]', 'failed to close database pool', error)
|
||||
process.exitCode = 1
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user