글 / 시스템 연계

연결 복구 후 상태 재동기화

재연결 시 마지막으로 수신한 순번을 통지하여 누락된 메시지만 수신하고, 상태가 일치할 때까지 새 지시는 보류한다.

작성일 · 읽는 시간 2분

단절 중 상태 불일치

연결이 단절되어도 장비는 진행 중인 작업을 계속한다. 그동안 전송한 상태 메시지는 관제에 전달되지 않으며, 관제는 단절 직전의 상태를 현재 상태로 간주한다. 그 결과 재연결 시점에 양측이 보유한 상태가 불일치한다.

순번 기반 누락 메시지 재전송

순번(sequence number)은 메시지마다 1씩 증가하는 번호이다. 송신 측은 메시지마다 순번을 부여하고, 최근 메시지를 버퍼에 보관한다. 수신 측은 마지막으로 반영한 순번을 저장하고, 재연결되면 먼저 그 값을 통지한다. 송신 측은 그 이후의 메시지만 재전송한다.

재연결 후 마지막 순번 이후의 누락 메시지만 재전송하는 순서

pythonsender.py
from collections import deque


class Sender:
    def __init__(self, keep: int = 1000):
        self.seq = 0
        self.buffer = deque(maxlen=keep)  # 최근 메시지만 남긴다

    def emit(self, state: dict) -> None:
        self.seq += 1
        self.buffer.append((self.seq, state))

    def replay(self, last_seq: int):
        # 버퍼에 남은 것보다 앞을 요구하면 이어 줄 수 없다
        if self.buffer and last_seq + 1 < self.buffer[0][0]:
            return None
        return [m for m in self.buffer if m[0] > last_seq]

None은 누락 구간이 버퍼에서 이미 제거되었음을 나타낸다. 이 경우 전체 상태(snapshot)를 한 번 수신하고 그 순번부터 수신을 재개한다. 수신 측은 마지막 순번보다 크지 않은 메시지를 폐기하여 같은 메시지를 두 번 반영하지 않는다.

버퍼 보관 여부에 따라 재전송과 전체 상태 수신으로 분기되는 흐름

동기화 중 지시 보류

재동기화가 완료되기 전에 관제가 보유한 상태는 과거 상태이다. 이 상태를 근거로 지시하면 이미 완료된 작업을 다시 지시하거나, 위치가 변경된 장비에 부적합한 지시를 전송하게 된다.

  • 재연결되면 장비를 동기화 중으로 표시하고, 새 지시는 전송하지 않고 보관한다.
  • 누락된 메시지를 모두 반영한 뒤에 정상으로 변경한다.
  • 보관한 지시는 새 상태에서도 유효한 것만 전송한다.

연결 단절에서 동기화 중을 거쳐 정상으로 전환되는 상태 전이