---
title: 'Eşler Arası'
source: 'https://academia.sh/tr/kurslar/mimari-bicemler/esler-arasi'
course: 'Mimari Biçemler'
language: tr
updated: '2026-08-17T18:10:36+00:00'
license: 'CC BY-SA 4.0'
---

# Eşler Arası

Başlatan ve bekleyen rolünün tek birimde birleştiği merkezsiz düzenin ölçülmesi: altı aktarma merkezinin üç komşuluk düzeninde tanımak zorunda olduğu komşu sayısı, bir tarife güncellemesinin herkese ulaşması için gereken tur ve ileti sayısı, bir birim çekildiğinde öğrenen birim sayısı ve yeni birim eklendiğinde düzenlenen komşu listesi sayısı.

Önceki düzende asimetri kasıtlıydı: bir taraf hep başlatıyor, öbürü hep bekliyor ve bekleyen
taraf tekti. Teslimat operasyonu bağlamında bu tekliğin bir karşılığı var — bütün ücret
sorularının tek bir yere gitmesi, o yerin herkes tarafından bilinmesi anlamına gelir. Aynı işi
birden çok aktarma merkezinin yürüttüğü bir düzende soru tersine döner. Her merkez hem soran hem
yanıtlayan olursa bilme yükümlülüğü tek yöne yığılmak yerine dağılır.

**Eşler arası** (peer-to-peer) biçemin yazılım mimarisi düzeyindeki imzası budur: rol ayrımı
kalkar, iki rol aynı modülde birleşir. Bilgisayar Ağları müfredatındaki İstemci–Sunucu Modeli
dersi bu düzenin talep arttıkça kapasite kazandırdığını, ama kararlı adres ve merkezî denetim
gerektiren web için istemci–sunucu modelinin seçildiğini söylemişti. Adres, bağlantı ve ağ
katmanı oraya aittir. Buradaki soru üç sayıdır: bir birimin tanımak zorunda olduğu komşu sayısı,
bir tarife güncellemesinin bütün birimlere ulaşması için gereken ileti sayısı, bir birim
çekildiğinde iş görmeye devam eden birim sayısı.

Bağlandığı **kalite niteliği** güvenilirliktir ve nitelik sorusu şudur: bir aktarma merkezi
devre dışı kaldığında kaç merkez yeni tarifeyi öğrenemez.

## İki Rolü Taşıyan Modül

Altı aktarma merkezi var ve hepsi için aynı dosya koşuyor. Modülün içinde iki şey birden durur:
gelen isteği karşılayan `istekIsle` ve komşulara istek gönderen `yay`. Önceki dersin iki
dosyası — istemci ve sunucu — burada tek dosyada birleşmiştir.

```sh
mkdir -p es
```

```js
// es/es.mjs — her aktarma merkezi icin kosan tek modul: hem karsilayan hem baslatan
export function es(ad) {
  const komsular = [];
  let surum = "T1", alinan = 0, gonderilen = 0;
  return {
    ad,
    get surum() { return surum; },
    tanit: (komsu) => komsular.push(komsu),
    sayac: () => ({ alinan, gonderilen, komsu: komsular.length }),
    istekIsle(istek) {
      alinan += 1;
      if (istek.islem !== "tarife-duyur") return { durum: "bilinmeyen-islem" };
      if (istek.surum === surum) return { durum: "bilinen" };
      surum = istek.surum;
      return { durum: "yeni" };
    },
    yay() {
      for (const komsu of komsular) {
        gonderilen += 1;
        komsu.istekIsle({ islem: "tarife-duyur", surum });
      }
    },
  };
}
```

Bir eşin bildiği tek şey komşularıdır. Kaç komşu tanıdığı ise dışarıdan verilir; biçemin
ölçülebilir yüzü buradadır.

## Üç Komşuluk Düzeni

Aynı altı birim üç ayrı biçimde bağlanır. Yıldız düzeninde bir merkez herkesi, herkes yalnız
merkezi tanır; bu, önceki dersin düzeninin komşuluk olarak yazılmış hâlidir. Halka düzeninde her
birim iki komşu tanır. Tam ağda her birim diğer beşini tanır.

Güncelleme her üç düzende de aynı yerden girer: `ANK` merkezine yeni tarife sürümü bildirilir.
Sonra tur tur yayılır — her turda sürümü bilen bütün birimler komşularına duyurur.

```js
// es/ag.mjs — ayni birimlerin uc komsuluk duzeni ve bir guncellemenin yayilim kosumu
import { es } from "./es.mjs";

export const AD = ["IST", "ANK", "IZM", "BUR", "ADA", "TRA"];
export const GIRIS = "ANK";

export const yildiz = (ad) => new Map(ad.map((a, i) => [a, i === 0 ? ad.slice(1) : [ad[0]]]));
export const halka = (ad) =>
  new Map(ad.map((a, i) => [a, [ad[(i + 1) % ad.length], ad[(i - 1 + ad.length) % ad.length]]]));
export const tamAg = (ad) => new Map(ad.map((a) => [a, ad.filter((b) => b !== a)]));
export const DUZENLER = [["yildiz", yildiz], ["halka", halka], ["tam ag", tamAg]];

export function yayilim(harita) {
  const esler = new Map([...harita.keys()].map((a) => [a, es(a)]));
  for (const [a, komsular] of harita) for (const k of komsular) esler.get(a).tanit(esler.get(k));
  esler.get(GIRIS).istekIsle({ islem: "tarife-duyur", surum: "T2" });
  const hepsi = [...esler.values()];
  let tur = 0;
  while (hepsi.some((e) => e.surum !== "T2") && tur < 20) {
    tur += 1;
    for (const e of hepsi.filter((e) => e.surum === "T2")) e.yay();
  }
  return {
    tur,
    ileti: hepsi.reduce((t, e) => t + e.sayac().gonderilen, 0),
    komsu: hepsi.reduce((t, e) => t + e.sayac().komsu, 0),
    ogrenen: hepsi.filter((e) => e.surum === "T2").length,
    birim: hepsi.length,
  };
}
```

```js
// yayilim.mjs — bilinen komsu sayisi, yayilim turu ve ileti sayisi uc duzende
import { AD, DUZENLER, yayilim } from "./es/ag.mjs";

console.log("duzen   birim  bilinen komsu  tur  ileti  ogrenen");
for (const [etiket, kurucu] of DUZENLER) {
  const s = yayilim(kurucu(AD));
  console.log(
    `${etiket.padEnd(7)}${String(s.birim).padStart(4)}${String(s.komsu).padStart(13)}` +
      `${String(s.tur).padStart(6)}${String(s.ileti).padStart(7)}${`${s.ogrenen}/${s.birim}`.padStart(9)}`,
  );
}
```

```sh
node yayilim.mjs
```

```
duzen   birim  bilinen komsu  tur  ileti  ogrenen
yildiz    6           10     2      7      6/6
halka     6           12     3     18      6/6
tam ag    6           30     1      5      6/6
```

Yayılım burada bir modeldir, ağ ölçümü değil: sayılan şey ileti ve tur sayısıdır, hiçbir süre
ölçülmemiştir.

## Sayıların Okunması

Üç düzen de altı birimin altısına ulaştı, yani aynı işi yapıyorlar. Farklar üç sütunda toplanır.

Bilinen komşu sayısı bilme yükümlülüğünün toplamıdır. Yıldızda 10: merkez beşini, beş birim
birer merkezi tanıyor. Halkada 12, tam ağda 30. Tam ağ en pahalı bilme düzenidir ve bu, birim
sayısının karesiyle büyür.

İleti ve tur sayıları ters yönde hareket eder. Tam ağ en az iletiyle (5) ve tek turda bitirdi,
çünkü giriş birimi herkesi tanıyordu. Halka en çok iletiyi harcadı (18) ve üç tur sürdü, çünkü
haber komşudan komşuya atlamak zorunda; her turda haberi bilen bütün birimler yeniden duyurur ve
duyuruların çoğu bilinen bir sürümü taşır. Yıldız ikisinin arasında kaldı: 7 ileti, 2 tur —
haberin ilk turda merkeze çıkması, ikinci turda merkezden dağılması gerekti.

Bu üç sütun bir **ödünleşim** tablosudur: bilme yükümlülüğünü azaltmak ileti sayısını artırır.

## Bir Birim Çekildiğinde

Güvenilirlik sorusunun ölçümü şu deneydir: giriş birimi dışındaki her birim sırayla ağdan
çıkarılır, yayılım baştan koşturulur ve kalan birimlerden kaçının yeni sürümü öğrendiği sayılır.
Aynı betik ağa yedinci bir merkez eklendiğinde kaç komşu listesinin düzenlenmek zorunda kaldığını
da hesaplar.

```js
// dayaniklilik.mjs — bir birim cekildiginde ogrenen birim, yeni birim eklemenin maliyeti, tek dosyadaki iki rol
import { readFileSync } from "node:fs";
import { AD, GIRIS, DUZENLER, yayilim } from "./es/ag.mjs";

const cikar = (harita, ad) =>
  new Map([...harita].filter(([a]) => a !== ad).map(([a, k]) => [a, k.filter((x) => x !== ad)]));

console.log("duzen    en kotu ogrenen  kritik birim  yeni birim icin duzenlenen liste");
for (const [etiket, kurucu] of DUZENLER) {
  const tam = kurucu(AD);
  let kritik = 0, enKotu = [Infinity, 0];
  for (const ad of AD.filter((a) => a !== GIRIS)) {
    const s = yayilim(cikar(tam, ad));
    if (s.ogrenen < s.birim) kritik += 1;
    if (s.ogrenen < enKotu[0]) enKotu = [s.ogrenen, s.birim];
  }
  const buyuk = kurucu([...AD, "ESK"]);
  const degisen = AD.filter((a) => tam.get(a).join(",") !== buyuk.get(a).join(",")).length;
  console.log(
    `${etiket.padEnd(9)}${`${enKotu[0]}/${enKotu[1]}`.padStart(16)}${String(kritik).padStart(14)}` +
      `${String(degisen).padStart(34)}`,
  );
}

const kaynak = readFileSync("es/es.mjs", "utf8");
const karsilayan = (kaynak.match(/istekIsle\(istek\)/g) ?? []).length;
const baslatan = (kaynak.match(/\.istekIsle\(\{/g) ?? []).length;
console.log(`es/es.mjs: karsilayan tanim = ${karsilayan}, baslatan cagri = ${baslatan}`);
```

```sh
node dayaniklilik.mjs
```

```
duzen    en kotu ogrenen  kritik birim  yeni birim icin duzenlenen liste
yildiz                1/5             1                                 1
halka                 5/5             0                                 2
tam ag                5/5             0                                 6
es/es.mjs: karsilayan tanim = 1, baslatan cagri = 1
```

Yıldızda kritik birim sayısı 1'dir ve o birim merkezdir: çekildiğinde kalan beş birimden yalnız
biri — haberin girdiği birim — sürümü biliyor, dördü öğrenemiyor. Halkada ve tam ağda kritik
birim sayısı 0; hangi birim çekilirse çekilsin kalan beşinin beşi öğreniyor. Merkezsizliğin
sayısı budur. Sözcük bir yapı betimlemesi değil, bir ölçüm sonucudur: çekildiğinde başkalarının
işini durduran birim sayısı sıfır.

Son sütun bedelin öbür yarısıdır. Yedinci merkez eklendiğinde yıldızda tek bir liste — merkezin
listesi — düzenlenir. Halkada iki, tam ağda altı liste düzenlenir. Tam ağın tek turda bitirme
kazancı, her yeni birimde var olan bütün birimlerin bilgisini güncellemekle ödenir.

Son satır biçemin kod imzasını verir. Tek dosyada bir karşılayan tanım ve bir başlatan çağrı
bulunuyor. Önceki dersin iki ayrı dosyası burada bir dosyaya indi ve bu, ölçümün nedenidir:
başlatma yönü tek yöne yığılmadığı için ağdan bir birim çıkarmak kalanların konuşmasını
engellemiyor.

## Özet

- Eşler arası biçemin kod imzası rol ayrımının kalkmasıdır: karşılayan tanım ile başlatan çağrı
  aynı modülde durur, altı birim için tek dosya koşar.
- Bilinen komşu sayısı yıldızda 10, halkada 12, tam ağda 30 çıktı; bilme yükümlülüğü tam ağda
  birim sayısının karesiyle büyür.
- İleti ve tur sayıları ters yönde hareket etti: tam ağ 5 ileti ve 1 tur, yıldız 7 ileti ve 2
  tur, halka 18 ileti ve 3 tur harcadı; üçü de altı birimin altısına ulaştı.
- Kritik birim sayısı yıldızda 1, halkada ve tam ağda 0; merkez çekildiğinde kalan beş birimden
  dördü yeni tarifeyi öğrenemedi.
- Merkezsizliğin bedeli yeni birim eklemenin maliyetidir: yedinci merkez için yıldızda 1,
  halkada 2, tam ağda 6 komşu listesi düzenlendi.

## Sonraki Adım

Buraya kadarki iki biçem de aynı türden birimler arasındaki etkileşimi ele aldı: konuşan
tarafların ikisi de ücret hesaplayan ya da tarife duyuran birimlerdi, aradaki fark yalnız kimin
başlattığıydı. Kitaplıkta bir de türü farklı bir sınır var. Operasyon masasındaki görevli
ücretin nasıl hesaplandığını değil, ekranda ne yazdığını görür: bölge adı, kademe, indirim
gerekçesi ve ödenecek tutar belirli bir biçimde dizilmiş olmalıdır. Bu sınırın iki tarafı eşit
değildir — biri kuralı ve veriyi taşır, öbürü onu gösterir. Sonraki ders bu sorumluluğun üç
ayrı dağıtımını karşılaştırır: gösteren dosyanın alan adlarından kaç tanesini tanıdığını,
biçimlendirmenin kaç ayrı yerde yapıldığını ve bir görünüm değişikliğinin kaç dosyaya
dokunduğunu sayar.
