대량 처리 화면에 진행률 표시를 붙여서 서버가 처리하면서 이벤트를 흘려보내고 화면이 막대를 그리게 했다. 며칠 뒤 다른 메뉴에 갔다 오면 진행률이 0으로 보이는데 작업은 계속 돌고 있다는 문의가 왔다.
Table of contents
Open Table of contents
재접속하면 이전 이벤트가 없다
화면이 받는 것은 연결된 이후에 발생한 이벤트뿐이다. 페이지를 떠나면 연결이 끊기고 돌아오면 새 연결이 열린다.
그 사이에 지나간 이벤트는 어디에도 남아 있지 않으므로 클라이언트 입장에서는 없었던 일과 같다. 전체 개수도 첫 이벤트에만 실려 있어서 재접속 후에는 분모조차 몰랐다.
한 채널에 얹힌 두 성격
정리해 보니 한 채널에 성격이 다른 두 가지를 얹고 있었다. 지금 막 처리된 건은 순간의 변화이고 지금까지 얼마나 됐는지는 누적된 상태다.
실시간 전송은 변화를 알리는 데 강하지만 놓친 변화를 되돌려 주지 않는다. 상태는 어딘가에 보관돼 있어야 재접속한 쪽이 받아 갈 수 있다.
조회와 실시간의 순서
이미 처리 상태를 들고 있는 자료구조가 있어서 전체 개수 필드만 추가하고 조회 경로를 하나 열었다. 새 구조를 만든 것이 아니라 있던 것에 한 칸을 더한 정도였다.
화면은 먼저 조회로 현재 상태를 받아 그리고 아직 진행 중일 때만 실시간 연결을 붙이게 했다. 조회로 현재를 복원하고 실시간으로 이후를 따라가는 순서가 핵심이었다.
메모리에 둔 상태의 한계
이 상태는 서버 프로세스 메모리에 있으므로 재시작하면 사라지고 서버가 여러 대면 다른 대에서 조회할 수 없다. 지금은 처리도 그 프로세스가 하므로 프로세스가 죽으면 작업도 함께 죽어서 문제가 안 된다.
다만 메모리에 뒀다는 사실과 그 한계를 주석과 문서에 적어 뒀다. 나중에 서버를 늘리거나 처리를 분리하면 여기가 먼저 깨지고 그때 원인을 다시 찾게 되기 때문이다.
끊김을 다시 확인할 시점으로
처리가 끝났는데 화면이 연결을 붙들고 있는 경우도 있었다. 완료 이벤트를 못 받으면 화면은 계속 기다린다.
서버에서 완료 이벤트 뒤에 명시적으로 닫고 화면은 연결이 끊기면 상태를 한 번 더 조회하게 했다. 끊김을 실패로 보지 않고 상태를 다시 확인할 시점으로 다루니 끝났으면 그대로 두고 아니면 다시 붙었다.
정리
- 실시간 전송은 변화를 알리고 상태 복원은 조회가 한다
- 받지 못한 이벤트는 어디에도 안 남는다
- 한 채널에 둘을 얹으면 재접속마다 화면이 빈다
- 조회로 현재를 그린 뒤 실시간으로 이후를 따라간다
- 새 구조를 만들기 전에 이미 상태를 든 자료구조를 찾는다
- 메모리에 둔 상태는 재시작과 다중 서버에서 깨진다
- 지금 괜찮아도 그 한계를 적어 둔다
- 연결 끊김을 상태를 다시 확인할 시점으로 다룬다