İki eş düğümümüz olduğunu varsayalım: ilk düğüm ikincisine bir bağlantı isteği gönderebilir, ancak ikincisi de birincisine bir bağlantı isteği gönderebilir. İki düğüm arasında çift bağlantı nasıl önlenir? Bu sorunu gidermek için, gelen veya giden TCP bağlantıları oluşturmak için gerçekleştirilen işlemleri sırayla yapmak yeterli olacaktır.
Bu, her düğümün hem gelen bağlantılar hem de giden bağlantılar için her yeni bağlantı oluşturma işlemini sırayla işlemesi gerektiği anlamına gelir. Bu şekilde, bir düğümden yeni bir gelen bağlantı kabul etmeden veya bir düğüme bir bağlantı isteği göndermeden önce, bağlı düğümlerin bir listesini tutmak, bu düğümün listede zaten mevcut olup olmadığını kontrol etmek için yeterli olacaktır.
Bağlantı oluşturma işlemlerini sırayla yapmak için , bağlı düğümler listesinde bir kilit gerçekleştirmek yeterlidir : aslında, her yeni bağlantı için, yeni bağlı düğümün tanımlayıcısı bu listeye eklenir. Ancak, bu yaklaşım dağıtılmış kilitlenmeye neden olup olmadığını merak ediyorum :
- ilk düğüm ikincisine bir bağlantı isteği gönderebilir;
- ikinci düğüm birincisine bir bağlantı isteği gönderebilir;
- iki bağlantı isteğinin eşzamansız olmadığını varsayarsak, her iki düğüm de gelen bağlantı isteklerini kilitler.
Bu sorunu nasıl çözebilirim?
GÜNCELLEŞTİRME: Ancak, diğer bir iş parçacığı bu listeye erişebildiğinden, her yeni (gelen veya giden) bağlantı oluşturulduğunda listeyi kilitlemem gerekir, sonra kilitlenme sorunu hala devam edecektir.
GÜNCELLEME 2: Tavsiyenize dayanarak bir giriş talebinin karşılıklı olarak kabul edilmesini önlemek için bir algoritma yazdım. Her düğüm bir eş olduğundan, yeni bağlantı istekleri göndermek için bir istemci rutini ve gelen bağlantıları kabul etmek için bir sunucu rutini olabilir.
ClientSideLoginRoutine() {
for each (address in cache) {
lock (neighbors_table) {
if (neighbors_table.contains(address)) {
// there is already a neighbor with the same address
continue;
}
neighbors_table.add(address, status: CONNECTING);
} // end lock
// ...
// The node tries to establish a TCP connection with the remote address
// and perform the login procedure by sending its listening address (IP and port).
boolean login_result = // ...
// ...
if (login_result)
lock (neighbors_table)
neighbors_table.add(address, status: CONNECTED);
} // end for
}
ServerSideLoginRoutine(remoteListeningAddress) {
// ...
// initialization of data structures needed for communication (queues, etc)
// ...
lock(neighbors_table) {
if(neighbors_table.contains(remoteAddress) && its status is CONNECTING) {
// In this case, the client-side on the same node has already
// initiated the procedure of logging in to the remote node.
if (myListeningAddress < remoteListeningAddress) {
refusesLogin();
return;
}
}
neighbors_table.add(remoteListeningAddress, status: CONNECTED);
} // end lock
}
Örnek: A düğümünün IP: bağlantı noktası A: 7001 - B düğümünün IP: bağlantı noktası B: 8001'dir.
A düğümünün B: 8001 düğümüne bir oturum açma isteği gönderdiğini varsayalım. Bu durumda, A düğümü kendi dinleme adresini göndererek giriş rutinini çağırır (A: 7001). Sonuç olarak, A düğümünün neighbors_table'ı uzak düğümün adresini içerir (B: 8001): bu adres BAĞLANMA durumuyla ilişkilidir. A düğümü, B düğümü giriş isteğini kabul etmeyi veya reddetmeyi bekliyor.
Bu arada, B düğümü de A düğümünün (A: 7001) adresine bir bağlantı isteği göndermiş olabilir, daha sonra A düğümü B düğümünün isteğini işliyor olabilir. Bu nedenle, B düğümünün neighbors_table'ı uzaktan düğüm (A: 7001): bu adres BAĞLANMA durumuyla ilişkilendirilir. B düğümü, A düğümünün oturum açma isteğini kabul etmesini veya reddetmesini bekliyor.
A düğümünün sunucu tarafı B: 8001'den gelen isteği reddederse, B düğümünün sunucu tarafının A: 7001'den gelen isteği kabul edeceğinden emin olmalıyım. Benzer şekilde, B düğümünün sunucu tarafı A: 7001'den isteği reddederse, A düğümünün sunucu tarafının B: 8001'den isteği kabul edeceğinden emin olmalıyım.
Göre "küçük adresi" kuralı düğüm B düğümü A'dan isteği kabul ederken, bu durumda düğüm A, B düğümü tarafından giriş isteğini reddeder
Bunun hakkında ne düşünüyorsun?