openlang

합쳐진 메일박스 로그와 인과 관계

합쳐진 메일박스 로그가 A1, B1, B2, A2로 찍혀 있어도, 보이는 만큼 많은 걸 알려 주지는 않아요.

평범한 Erlang 메시지, 우선순위 수신 없음, 네 이벤트를 모두 같은 패턴으로 받는 수신자 하나. A는 A1, 그다음 A2를 보내요. B는 B1, 그다음 B2를 보내요. 한 송신자가 보낸 신호는 그 송신자의 순서를 지키고, 보장되는 순서는 그것뿐이에요. 위 로그는 두 송신자의 순서를 다 지켜요.

이제 B1을 한 칸 앞당겨 A1보다 먼저 두어 볼게요. 두 순서는 여전히 지켜져요. 그러니 A1 다음에 B1이 보인다고 해서 B가 A1이 처리된 걸 보고 움직였다는 뜻은 아니에요. B는 A1을 아예 몰랐을 수도 있어요.

B1이 정말 A1의 처리에 기대고 있다면 그 연결은 프로토콜이 실어 날라야 해요. 로그를 읽는 사람이 짐작할 일이 아니에요. 출처별 순번 태그에 촉발한 이벤트를 가리키는 명시적 참조를 붙이면 되고, 도착 순서는 도착 순서로만 읽으면 돼요.

이어지는 대화 3

서로의 근거를 따라
  1. 고유 링크

    이벤트 ID와 의존 ID는 각 레코드에 직접 넣는다. 화면의 행 위치는 연결이 아니고, 행을 다시 묶어도 아무것도 깨지면 안 된다. Odin에서는 저장 쪽에도 함정이 하나 있다. 동적 배열은 자기 할당자를 그대로 쥐고 있어서, 나중에 context.allocator가 바뀌어도 달라지지 않는다. 레코드가 임시 저장소의 텍스트를 가리킨다면, 로그가 그 텍스트를 쓰는 동안에는 임시 저장소를 비울 수 없다. 비우는 시점은 로그가 텍스트를 다 쓴 뒤로 잡아야 한다.

  2. 고유 링크

    순서는 보내는 쪽과 받는 쪽 한 쌍 안에서만 지켜지고 다른 데서는 아닌데, 사람들이 제일 많이 늘려 해석하는 규칙이 바로 이거예요. P가 Q에게 m1을 보내고 나서 S에게 Q한테 알려 달라고 하면, S의 메시지가 m1보다 먼저 Q에 닿을 수 있어요. 같은 VM이라 Elixir 쪽도 똑같아요. 인과 관계는 세 번째 프로세스를 거쳐 공짜로 전달되지 않아요. 그러니 말씀대로 B1이 A1에 의존한다면 그 연결은 메시지 안에 있어야 해요.

같은 질문의 다른 갈래

  1. start_link가 반환되면 캐시도 준비된 건가요?

    start_link는 이름부터 든든하지만, 이게 반환됐을 때 클라이언트가 실제로 알게 된 건 뭘까요? 이 캐시 서비스에서 init은 {:ok, state, {:continue, :warm_cache}}를 반환해요. 시작 호출…

  2. 큐가 8칸이어도 고루틴 88개가 기다릴 수 있어요

    버퍼 채널이 제한하는 건 채널 안에 들어간 작업 수예요. 보내려고 막혀 있는 고루틴 수는 제한하지 않아요. 서버에 요청 100개가 한꺼번에 몰린다고 해 볼게요. 요청마다 작업이 하나씩이고, 워커는 넷, 채널 버퍼는 여덟 칸이…