본문 바로가기
C.W.K.
Stream
Lesson 04 of 05 · published

같은 방법을 돌리는 관측 지점 둘은 계기 하나야

~13 min · measurement, evidence, independence, verification

Level 0젖은 흙
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

맞는 규칙을 틀리게 적용한 경우

코퍼스 전체 스윕이 외부 참조의 생존 여부를 확인해서 죽은 것들의 작업 목록을 만들었어. 앞선 경험이 여기서 진짜 교훈을 이미 가르쳐줬거든. 호스트 하나에서, 한 순간에, 한 번 찔러본 건 대상에 대한 증거가 아니라 그 찌르기에 대한 증거라는 것. 그래서 스윕은 다른 망에 있는 기계 둘에서 돌았고 양쪽 다 실패한 참조만 목록에 올렸어.

그 규칙은 맞고, 그렇게 나온 작업 목록의 백구십 개 항목 중 여섯이 살아 있었어.

관측 지점 둘이 실제로 공유하던 것

그 검사는 메타데이터만 요청하는 형태를 먼저 보내고, 특정 거부 코드 몇 개에 대해서만 전체 요청으로 재시도했어. 일부 대상은 그 메타데이터 요청엔 없음으로 답하고 전체 요청엔 성공으로 답해. 진짜로 있는, 드물지도 않은 서버 동작이야. 그런 대상은 모든 관측 지점에서 영원히 죽은 걸로 읽혀.

관측 지점 둘은 네트워크 잡음을 걸러줘. 이건 방법 잡음이었고, 관측 지점 둘이 방법을 완전히 공유했어. 거짓 양성을 잡으려고 특별히 지은 그 검사가 구조적으로 이 부류의 거짓 양성을 못 잡았지.

일반형을 갖고 다닐 값어치가 있어. 독립적인 확인들을 둘로 세기 전에 그것들이 뭘 공유하는지 물어봐. 같은 점검표를 쓰는 사람 둘은 점검표 하나야. 같은 상류에 질의하는 서비스 둘은 상류 하나고. 일치는 그 일치하는 것들이 불일치할 수도 있었을 때만 증거야.

독립성이 실제로 어떻게 생겼냐면

이 경우의 처방은 관측 지점을 늘리는 게 아니라 차분이었어. 살아남은 죽은 집합에 요청 형태 둘 다 보내고 비교해. 싸고, 정확히 그 실패를 겨냥하고, 수리가 제안된 뒤가 아니라 진단 시점에 속해.

그리고 더 어려운 질문, 그러니까 이 참조가 존재한 적은 있나 아니면 그냥 옮겨간 건가에 답해야 할 땐 계기가 완전히 다른 방향에서 와야 해. 원본 저장소 자기 이력한테 그 경로를 물어봐. 어떤 커밋에도 안 나타나는 경로는 거기 있었던 적이 없고, 그게 재구성이랑 날조를 갈라. 일반화되는 경계 하나. 대조군을 같이 돌려. 색인 안의 부재는 그 색인이 존재를 아는 것들에 대해 커버리지가 있다는 걸 보이기 전까진 그 색인에 대한 증거야.

방법을 공유하는 계기들 사이의 일치는 독립적인 증거가 아냐. 확인 둘을 둘로 세기 전에 그것들이 뭘 공유하는지 적어. 방법, 라이브러리, 상류, 가정. 그 목록에 오른 게 둘 다 못 보는 그것이야.

Code

관측 지점 둘로는 대체 못 하는 차분·python
def liveness(url):
    """A metadata-only request and a full request can DISAGREE, and
    the disagreement is a property of the server, not the network.
    Running this from two machines does not help: both machines
    send the same two requests and get the same two answers.
    """
    meta = probe(url, method="metadata-only")
    full = probe(url, method="full")
    if meta.status != full.status:
        return ("alive" if full.ok else "unverifiable",
                f"metadata={meta.status} full={full.status} - the"
                " check disagrees with itself")
    if full.status in (404, 410):
        return "dead", f"{full.status} on both forms"
    if full.ok:
        return "alive", ""
    return "unverifiable", f"{full.status} - not proof of absence"


# THREE VERDICTS, NOT TWO. "unverifiable" is what stops a blocked
# request or a bot wall from being filed as rot. A disagreement
# between the two forms can never be filed as DEAD - it resolves
# to alive when the full request succeeds and to unverifiable
# otherwise, and never to the answer you prefer.


# For the harder question - did this ever exist, or did it move?
#   ask the source's OWN history for the path:
#     GET /repos/{owner}/{repo}/commits?path=<path>
#   zero commits  -> the path was never on the default branch
#   but ALWAYS run a control: a sibling path you KNOW exists.
#   an empty answer is evidence about the index until the control
#   proves the index has coverage.

External links

Exercise

팀이 여러 자리에서 돌리는 검사를 하나 잡고, 그 실행들이 공유하는 걸 전부 나열해. 라이브러리, 요청 모양, 시간 제한, 파싱, 실패가 뭘 뜻하는지에 대한 가정. 그다음 그 목록을 최대한 안 공유하는 대안을 하나 설계해서 같은 입력에 둘 다 돌려. 불일치가 네 이중화가 한 번도 못 보던 결함이야.
Hint
제일 잘 숨는 공유 항목은 파싱이야. 대륙 둘에서 망 둘을 거쳐 오는 찌르기 둘도, 둘 다 상태 코드만 보면 로그인 페이지로 가는 전환을 성공이라고 부를 거고, 그 실패는 누가 본문을 읽기 전까진 안 보여.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.