fastify사용 중 close가 되지 않는다면 확인해 봐야 할 것

김성현·2022년 5월 28일
0

만약 fastify 사용 중 fastify.close를 사용하면 callback이나 promise가 리턴되지않는 에러를 마주한다면 한번 확인해 봐야 하는 부분이 있다.

이 경우 @fastify/websocket을 사용하는지 확인해 봐야 한다.

@fastify/websocket, fastify-websocket 플러그인 사용 중 소켓에 달린 이벤트 리스너를 삭제하면 에러가 일어난다.

다만 이 경우 에러 핸들링이 되지도 않고 fastify.close를 호출하면 바로 알 수 없는 종료와 함께 콜백도, 프로미스도 리턴되지 않는다.

즉 다음과 같은 코드를 실행한 후 fastify.close를 호출하면 원인 추론이 힘들 버그가 생겨난다.

import Fastify from "fastify";
import FastifyWebsocket from "@fastify/websocket";
import WebSocket from "ws";

const fastify = Fastify()
await fastify.register(FastifyWebsocket)
// 
fastify.get('/ws', { websocket: true }, (socket, rep) => {
    socket.socket.removeAllListeners('close') // it make error
    socket.destroy()
})
await fastify.listen(3000)

// websocket
const ws = new WebSocket("ws://localhost:3000/ws")
ws.onopen = () => {
    console.log('websocket open')
    ws.close()
}
await new Promise(resolve => {
    ws.onclose = () => {
        console.log('websocket closed')
        resolve()
    }
})
try {

    // error expected
    await fastify.close()
} catch {
    console.log('closed') // 이걸 트리거하지 못함
}

console.log('closed') // 이것 역시 마찬가지.

아마 저수준 소켓의 close 이벤트에 자원 정리 관련한 코드가 심어져 있어서 생기는 것으로 추측되는데, readme.md에는 딱히 관련된 주의사항이 없었던 것 같다.(물론 대충봐서 그럴수도 있는데 좀 더 확인해보고 메인테이너한테 얘기해 보는 게 좋을 것 같다.)

만약 나와 같이 fastify 사용중 웹소켓 서버를 닫을 때 예상치 못하게 바로 끝나는 상황을 마주치면 코드 중 위와 같이 핸들러를 삭제하는 코드가 있는지 확인해 보자.

profile
수준 높은 기술 포스트를 위해서 노력중...

0개의 댓글