게시글
React Query / SWR / Apollo는 재요청 중 이전 데이터를 어떻게 다룰까
React Query, SWR, Apollo는 조회 조건이 바뀔 때 비는 화면을 비슷한 옵션으로 메운다. 이전 값을 자동으로 병합할지와 이전 데이터라고 알려 줄지는 서로 다르고, Apollo는 값만 넘겨줘서 같은 자원을 다시 조회하는지부터 직접 구분해야 한다.
previousData로 variables 바뀔 때 이전 데이터 유지하기
Apollo Client에서 variables가 바뀌면 useQuery의 data만 비고, previousData가 그 공백을 메운다. 캐시에 값이 남아 있어도 data는 undefined가 됐고, 프로젝트의 커스텀 훅은 useQuery를 감싸 같은 일을 하고 있었다.
nginx와 애플리케이션 코드의 리버스 프록시 구분하기
nginx와 애플리케이션 코드의 reverse proxy는 이름이 같아도 실행되는 프로세스와 네트워크 경계가 다르다. Node.js 코드의 reverse proxy를 보고 서버 세 대가 통신한다고 잘못 그렸고, 요청이 프로세스 경계를 몇 번 넘는지부터 세어야 했다.
Apollo Client의 fetchPolicy 기본값이 cache-first인 이유
Apollo Client의 fetchPolicy 옵션 중, 최신값까지 확인하는 cache-and-network가 가장 좋은 선택이라 생각했다. 하지만, 라이브러리의 기본값은 캐시에 값이 있으면 네트워크조차 안 쓰는 cache-first였다. 왜 라이브러리는 이쪽을 선택했을까?
getServerSideProps는 페이지 요청마다 다시 실행된다
getServerSideProps는 최초 접속 때만 실행되고 그 뒤로는 클라이언트가 화면을 채운다고 생각했다. 하지만 next/link로 이동할 때도 /_next/data 요청이 새로 떴다. 이 함수는 요청에 묶여 있어서 요청이 서버에 닿을 때마다 다시 실행된다.
웹소켓 클라이언트 Socket.IO와 STOMP
구형 브라우저 지원은 Socket.IO나 SockJS가, 메시지 형식의 통일은 STOMP가 WebSocket 위에 얹어 메운다. 표준 API로 연결을 열고 메시지를 보내는 일은 몇 줄이면 끝나지만 이 둘은 거기서 풀리지 않는다. 둘 다 필요 없다면 표준 API로 충분하다.
WebSocket부터 이해하자
WebSocket이 HTTP와 다른 지점은 결국 핸드셰이크가 끝난 뒤에도 연결을 끊지 않고 유지한다는 것 하나로 좁혀진다. 덕분에 서버가 먼저 메시지를 보낼 수 있지만, 한쪽이 죽거나 네트워크가 끊기면 그 연결을 다시 살리는 일은 온전히 애플리케이션의 몫이 된다.
터미널 명령어 실행 과정
fork와 exec이 나뉜 덕분에 자식 프로세스는 새 프로그램이 시작되기 전 짧은 틈에 파일 디스크립터를 바꿔치고 파이프를 연결할 수 있다. 토이 셸에서 리다이렉션 코드를 어디에 넣을지 찾다가 ls -l /home이 실행되는 과정을 시스템 콜 단위로 따라갔다.
컴퓨터 부팅 이후 프로세스 실행 과정
전원 버튼부터 로그인 화면까지는 여러 프로세스가 차례로 바통을 넘기는 과정이다. 커널이 하드웨어와 파일 시스템을 준비하면 PID 1번 init이 나머지 모든 프로세스를 깨운다. 알아서 뜨는 줄 알았던 로그인 화면도 결국 PID 1로 거슬러 올라간다.
쉘 내부 명령어와 외부 명령어
cd와 ls는 실행되는 경로부터 다르다. 서브셸 안에서 cd로 옮긴 디렉터리가 빠져나오면 원래대로 돌아오는 건, 서브셸도 fork로 만든 별도 프로세스라 그 안의 상태 변경이 함께 사라지기 때문이다. 쉘 자신의 상태를 바꿔야 하는 동작만 내부 명령어로 남는다.
로그인 쉘과 비로그인 쉘: 프롬프트가 뜨기까지 갈라지는 지점
로그인 쉘인지는 쉘을 실행할 때 넘긴 argv[0]가 하이픈으로 시작하느냐로 갈린다. 새 터미널마다 ~/.bash_profile이 다시 실행되는 줄 알았는데, 로그인 직후의 쉘만 전체 체인을 읽고 새 터미널은 ~/.bashrc만 읽었다.
컴퓨터 부팅 과정
전원 버튼을 누른다고 운영체제가 곧바로 켜지는 것은 아니다. 버튼이 깨우는 것은 ROM 속 BIOS이고, BIOS는 MBR의 부트로더에게, 부트로더는 커널에게 제어권을 넘긴다. 세부 동작보다 한 프로그램이 다음을 깨우고 물러나는 릴레이 구조를 봐야 한다.