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

세션이 아니라 신원당 바인딩해

~13 min · sidekick, binding, conversation, idempotency

Level 0릴 입문자
0 XP0/39 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"사이드킥은 cwkPippa 의 ashenreel 대화 바인더(ASHEN-REEL 시스템 폴더)를 통해 media identity 당 바인딩해."

무언가에 대한 대화는 그 무언가랑 같이 살아야 해

Pippa 한테 영상에 대해 물었어. 다음에 그 영상을 다시 열면 뭐가 일어나야 할까? 약한 설계는 실행할 때마다 새 채팅을 열고, 네 지난 질문은 증발해. Ashen Reel 은 반대로 가. 사이드킥은 media identity 당 canonical 대화 하나에 바인딩해. 오늘 그 2019년 클립을 열어서 어떤 순간에 대해 묻고, 다음 달에 다시 오면, 같은 대화 안이야. 그 대화가 그 영상에 대한 거고, 영상이 사는 만큼 같이 사니까.

바인딩 키는 media identity 야. 세션도, 창도, 실행도 아니고. 같은 영상이면 같은 대화, 시간이 지나도 안정적으로. 파일 열 때마다 리셋되는 채팅은 절대 기억으로 안 쌓이거든. 신원에 바인딩하는 게 사이드킥을 기억하게 만드는 거야.

대화는 덧없는 세션이 아니라 주제의 안정된 신원에 바인딩해. 스레드가 X 에 대한 거면, X 의 durable 신원으로 key 해. 그러면 X 가 중요한 딱 그만큼 지속되고, X 가 돌아올 때마다 다시 찾을 수 있어. 아무것으로도 key 안 된 일회성 채팅 더미로 흩어지는 대신에.

바인드는 cwkPippa 라우트로 가는 call 이고, 일부러 idempotent 하게 만들었어.

진실 하나, 표면 둘. 사이드킥이 바인딩하는 대화는 플레이어의 사적인 물건이 아니야. canonical cwkPippa 대화고, 서버가 소유한 ASHEN-REEL 시스템 폴더에 투영돼. 그래서 정확히 같은 채팅이 WebUI 에도 떠. 플레이어의 dock 이랑 웹앱의 폴더는 한 대화를 들여다보는 두 창이지, 두 사본이 절대 아니야. 플레이어에서 묻고 웹에서 이어가도 전부 한 스레드고.

왜 idempotent 바인딩이 중요한가

바인더는 일부러 idempotent 해. media identity 로 부르면, 기존 대화가 있으면 그걸 돌려주고 없으면 canonical 한 걸 만들어서 돌려줘. 그 속성 하나가 표면 전체를 튼튼하게 만들어. 같은 영상을 두 번 열든, 창 두 개에서 열든, 크래시 뒤에 열든, WebUI 랑 dock 에서 동시에 열든, 모든 경로가 같은 대화로 떨어지고 아무도 실수로 중복을 안 낳아. idempotency 가 있어야 '신원당 바인딩' 이 반복 열기랑 병렬 표면이라는 지저분한 현실을 만나고도 살아남아. 두 번 묻는 게 한 번 묻는 거랑 같아지게 바인딩을 설계해.

Code

바인딩은 idempotent 해. 같은 신원은 항상 같은 대화로 떨어져·swift
/// Bind the Sidekick to ONE canonical conversation for this media identity.
/// Same video -> same conversation, forever. Not a new chat per launch.
func bindConversation(for media: MediaIdentity) async throws -> ConversationRef {
    // The ashenreel binder is a cwkPippa route. It returns the EXISTING
    // conversation for this identity, or creates the canonical one and returns
    // it. Calling it twice is the same as calling it once (idempotent).
    return try await cwkPippa.bindAshenReel(hostMedia: media.stableKey)

    // The conversation lives in cwkPippa's DB, projected into the ASHEN-REEL
    // system folder. The WebUI sees the SAME chat. One truth, two surfaces.
    // Ashen Reel stores only this reference -- never the messages themselves.
}

External links

Exercise

네 시스템에서, 실제론 어떤 durable 엔티티에 '대한' 건데 세션이나 요청이나 타임스탬프로 key 된 레코드를 만드는 데를 찾아. 그걸 엔티티의 안정된 신원으로 다시 key 해. 그다음 create-or-get 연산을 idempotent 하게 만들어서, 반복 요청이나 동시 요청이 중복을 낳는 대신 같은 레코드로 떨어지게 해. 그리고 테스트해봐. 그 연산을 동시에 두 번 쏘면 레코드가 하나 나와, 둘 나와?
Hint
두 수를 같이 둬야 해. 하나, 오래 사는 스레드를 그걸 연 덧없는 세션이 아니라 durable 한 주제로 key 하기. 둘, 'get or create' 를 idempotent 하게 만들어서 병렬이나 재시도로 열려도 레코드 하나로 수렴하게 하기. 연산을 두 번 쏴서 레코드가 둘 생길 수 있으면, 결국 같은 주제에 중복 스레드가 쌓여. idempotent 한 get-or-create 가 그걸 막아주고.

Progress

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

댓글 0

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

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