4.4 KiB
4.4 KiB
decisions.md — Port Sırasında Alınan Kararlar
Geri-dönülebilir kararlar burada kayıt altına alındı; CLAUDE.md gereği seçildi, gerekçe yazıldı, devam edildi.
Mimari
- Klasör yapısı: Go repo kökünde (
go.mod+main.go+internal/). Kullanıcı onayıyla.loadtest/ayrı modül.frontend/yerinde. EskiSource/referans olarak bırakıldı. - WebSocket kütüphanesi:
gorilla/websocketv1.5.3. Kullanıcı onayıyla. En yaygın, en okunaklı; tek-yazıcı hub deseni doğrudan uyuyor. Modül önbelleğinde mevcut olduğundan ağ gerekmedi. - Concurrency: RWMutex + bağlantı-başına-tek-yazıcı (actor yerine). İzin verilen iki seçenekten (#22) bu seçildi çünkü gerçek race "tek yazıcı +
doneseçimliSend" ile zaten çözülüyor; RWMutex versiyonu yeni Go geliştiricisi için belirgin biçimde daha okunaklı. Actor (reply-channel) modeli senkron request/response handler'larına ceremoni ekler. →REVIEW.md'de onaya açık. - Modül yolu:
git.saqut.com/saqut/mwse(engine),git.saqut.com/saqut/mwse-loadtest(yük testi). Mantıksal isim; repo dizininin Türkçe karakterli olması etkilemez. - Dolu outbound buffer politikası: mesajı düşür, bağlantıyı KAPATMA. İlk versiyon (gorilla hub örneği gibi) yavaş peer'i komple düşürüyordu; yük testinde bu, ani trafik altında zincirleme kopmalara yol açtı (relay'de %92 kayıp). Best-effort relay için doğru politika: tek frame'i düşür, bağlantıyı koru. Gerçekten ölü peer zaten write-deadline ile temizlenir. Düzeltme sonrası teslim %98.5'e çıktı.
Client.Dropped()ile gözlemlenebilir.
Node'daki hataların düzeltilmesi (tel sözleşmesi korunarak)
Kullanıcı talimatı: "tüm fonksiyonların aynı olması önemli değil; amaç/iş aynı kalsın." Node kaynağındaki bariz bug'lar doğru çalışacak şekilde yeniden yazıldı; mesaj isimleri/şekilleri (SDK'nın gördüğü tel) korundu:
- Pairing akışı (Auth): Node'da
accept/pairyanlış tarafınpairssetini kontrol ediyordu (akış asla tamamlanmıyordu). Doğru el sıkışma uygulandı:request/pairisteyen tarafı kaydeder + hedeferequest/pairsinyali;accept/pairisteyenin gerçekten istek attığını doğrular +accepted/pairsinyali. Frontend'in beklediği{from, info}yükü gönderiliyor. is/reachable: NodeotherPeer.pairs.has(to)(kendi id'sini) kontrol ediyordu — her zaman false. Doğrusu: hedef pairing istemiyorsa VEYA gönderenle eşleşmişse erişilebilir.- Davet sistemi (Room
accept/invite-room/reject/invite-room): NodeSetüzerinde.includes/.filterçağırıyordu (çalışmaz, HANDLER_ERROR) vejoinType=='invite'kontrolü ters çevrilmişti. Doğru akış: sadece davet odaları, sadece bekleme listesindeki id'ler. closeroom: Noderoom.owner === client.idile Client nesnesini string'e kıyaslıyordu (her zaman false). Go'daOwnerID stringtutuluyor; doğru kıyas.create-roomdoğrulaması: Node tanımsızCreateRoomValidatedeğişkenine referans veriyordu (throw). joi şemasının niyetini taşıyan hafif bir doğrulama yazıldı. (Not: Node'un doğrulama hatasında döndürdüğümessagesanahtarı —tekil değil— korundu.)joinroominvite dalı: Node davet gönderdikten sonraNOT-FOUND-ROOMdöndürüyordu (yanıltıcı).{status:"success", message:"INVITE-REQUESTED"}ile değiştirildi.pack/topairing kontrolü: NodeotherPeer.pairs.has(to)(kendi id'si) kullanıyordu. Doğrusu hedefin gönterene pairing'i:other.HasPair(c.ID).
Bilinçli sadakat (Node davranışı korundu)
request/to→ 'E' yanıtı: SDK request'i action 'R' ile gönderdiğinden generic dispatcher hemen[null, id, 'E']yanıtlar; eş cevabıresponse/toile sonra gelir. Bu Node ile bire bir aynı (ve aynı uyumsuzluğu taşır). Dispatcher'ı özel-durumlamak tel sözleşmesini değiştirebileceğinden DOKUNULMADI. →REVIEW.md.auth/infoçift gönderim: Hem pair hem roompair olan bir peer ikipair/infoalır (Node ile aynı).- Heartbeat: 10sn
saQutping; pong "saQut" değilse bağlantı kapanır (Node ile aynı).
Session varsayılanları
packrecaive/packsending/notifyPairInfo/notifyRoomInfo varsayılanları NewClient constructor'ında set ediliyor (listener sırasından bağımsız her zaman mevcut). Session servisinin connect hook'u parite için yine de bunları yeniden uyguluyor.