Изящное завершение работы API-интерфейса узла при закрытии сервера, когда Chrome не использует сокеты - PullRequest
0 голосов
/ 24 сентября 2018

Сценарий : API отдыха Nodejs, использующий http.createServer()

Цель : Когда приходит SIGNINT (в моем случае из-за перезагрузки PM2) сделать изящноезавершение работы сервера, затем отключение соединения с БД и затем мирный выход.

Код :

// index.js

server.keepAliveTimeout = 10

process.on('SIGINT', () => {
    server.close(err => {
        // close the DB
        ...
        process.exit(0)
    })
})

// the code related to any API response
const headers = {
   ...
   'Connection': 'close'
}
response.writeHead(statusCode, headers)
return response.end(JSON.stringify(data))

Проблема : server.closeобратный вызов никогда не срабатывает.Процесс PM2 достигает тайм-аута через (в моем случае) 20 секунд, и поэтому отключение больше не происходит корректно.

Причина расследования : Обратный вызов срабатывает, если нет открытых подключений браузера (например, если никто не вызывает API) или если вызов API выполняется с помощью Firefox.Вместо Chrome я могу видеть в chrome://net-internals/#sockets 1 простое transport_socket_pool после запуска запроса.В этом случае обратный вызов close не срабатывает.Как только я очищаю незанятые сокеты в Chrome, обратный вызов срабатывает правильно.Обратите внимание, что в режиме инкогнито Chrome сокет не остается в режиме ожидания, а закрывается должным образом, поэтому обратный вызов срабатывает.

Вопросы :

  • Это ошибка вХром или нормальное поведение?
  • Разве заголовка Connection: close и короткого keepAliveTimeout не должно быть достаточно, чтобы уведомить любого клиента, что он не должен держать ни один сокет открытым так долго?
  • Как правильно обрабатывать клиенты, которые мешают завершить server.close?
  • Должен ли я пройти по всем созданным сокетам и закрыть их вручную?
...