# Döngüsel Karmaşıklık: Canary Rollout Risk Yönetimi

URL: https://upstreamapi.com/tr/journal/dongusel-karmasiklik
Type: blog
Locale: tr
Published: 2026-07-25
Updated: 2026-07-25

---

> Döngüsel karmaşıklık sayısı basit bir kod metriği değildir. Bu yazı, SRE'ler için karmaşıklık deltası, test burden matematiği ve rollout pacing'i nasıl enstrüman edileceğini inceliyor.

## Döngüsel Karmaşıklık: Kod İncelemesinden Rollout Hızına Kadar

Döngüsel karmaşıklık, bir fonksiyondan geçen bağımsız yolların sayısını sayar. NIST güvenli sınırı fonksiyon başına 10 olarak tanımlar ve çoğu ekip CI'de buna benzer bir şey zorlar. Ancak bu sayının size anlatmadığı şey, canary'nizin production trafiğinin %5'ine göndermek üzere olduğunuz yolların hangilerinin gerçekten kullanıma sokulacağıdır ve bu boşluk, çoğu rollout olayının başladığı yerdir. Döngüsel karmaşıklığı bir lint kuralı değil, bir rollout riski girişi olarak ele alın, bu noktada sayı gerçek değer sağlamaya başlar.

## Döngüsel Karmaşıklık Gerçekte Neyi Ölçüyor

McCabe'nin metriği bir grafik sayısıdır: düğümler, kenarlar, bağlı bileşenler. Her if, for, while, case ve boolean operatörü bir yol ekler. Karmaşıklığı 25 olan bir fonksiyonun içinden en az 25 doğrusal bağımsız yolu vardır. Bu fikir değil, basis path testing matematiğidir ve fonksiyonu uçtan uca bir kez kapsayacak kaç test durumuna ihtiyacınız olduğunu belirler. [Sourcegraph'ın açıklaması](https://sourcegraph.com/blog/cyclomatic-complexity-what-it-is-and-how-to-reduce-it) tam eşikleri içerir: 1-10 düşük risk, 11-20 orta, 21-50 yüksek, 50+ konuşmamız gerekiyor seviyesi. Bu sayı sürekli artar, işlemeniz gereken bağımsız test senaryosu sayısı direkt orantılı olarak artar.

Çoğu ekip bu sınıra ulaşmaz. Kapsama araçları yol kapsamasını değil satır kapsamasını bildirir, dolayısıyla bir fonksiyon %90 kapsama göstererek, yarısı hiç CI'de çalışmayan dallar içerebilir. Bu, PR şablonuna kimse koymaz ve testler geçti ile bunu gönderme güvenlidir iki farklı iddia olduğunun sebebidir. Bir ekip hemen sıfır testler yazarken, bir başka ekip bütün yolu test eder. Sayı böyle değişmez, risk profili işe. SonarQube raporlarında %90 coverage gösterir ama path coverage %40 olabileceğini gözlemledik. Production'a gittiğinde örtülü yol tetikleniyor ve incident geldi.

![Bir dizüstü bilgisayarın ekranında yuvalanmış girintiler içeren bir kod diff'ini inceleyen ellerin yakın çekimi](https://fdzlnqpwsaniezitwiuw.supabase.co/storage/v1/object/public/cms-media/upstreamapi/2026-07/91e851-inline1.webp)

## Düz Bir Sayı Gerçek Blast Radiüsü Nasıl Gizler

İşte her karmaşıklık dashboard'unun yanlış yaptığı kısım: iki fonksiyon aynı döngüsel karmaşıklık puanı verebilir ve yüksek düzeyde farklı riskler taşıyabilir. İyi test edilmiş işleyicilere yönlendiren 20 dalı olan bir switch ifadesi, 80 satırda dağılmış dört ayrı koşullu cep içeren, her biri üç seviye derinliğinde yuvalanmış bir fonksiyon ile aynı hayvan değildir. CodeScene buna çarpık yol diyor ve isim doğru. İçiçe geçme derinliği, ham dal sayısı değil, çalışma belleğini vergilendirir ve kimsenin test etmeyi düşünmediği uç durumu gizler. [CodeScene'nin yazısı](https://codescene.com/blog/bumpy-road-code-complexity-in-context/) karşılaştırmayı ayrıntılı olarak açıklar ve rollout verilerimize temiz şekilde eşlenir.

Bu bizi özel olarak ilgilendirir çünkü bir canary ortalama karmaşıklık üzerinde başarısız olmaz. Tek bir çarpık fonksiyonun üzerinde başarısız olur, bu diff'de saat 2'de, kimsenin yük testi yapmadığı yük altında. Platform ekipleriyle incelediğimiz post-mortem'lerde desen tekrarlanır: root-cause fonksiyonu neredeyse hiçbir zaman repo'daki en yüksek karmaşıklık puanını almaz. En yüksek karmaşıklık deltası vardır, gönderilen diff'de. Bu farklı bir sinyal ve neredeyse kimse bunu enstrüman eder.

Kod tabanının karmaşıklığının aşağı doğru eğilim gösterdiğini söyleyen bir dashboard, bu rollout'un, şu anda üç yeni yuvalanmış dal alan bir fonksiyona dokunduğunu söyleyen dashboard'la aynı değildir. Biri çeyrek yılda bir okunan sağlık raporu. Diğeri, SLO check yanında deployment pipeline'da oturmak istediğiniz ve incident sırasında kimsenin açmadığı statik analiz aracında gömülü bir kapıdır. Fark kritiktir, sağlık raporu geçmiş söyler, deployment kapısı şu an söyler.

Ring tabanlı ve yüzde tabanlı rollout'lar zaten bazı diff'lerin diğerlerinden daha riskli olduğunu varsayar, bu canary'nin tüm amacıdır. Çoğu pipeline'ın yapmadığı şey, diff'in kendisinin karmaşıklık şekli canary'nin ne kadar hızlı genişlemesi gerektiğini bilmesidir. Bu code review endişesi, sonra PR merge'lenirse unutulur. SRE'ler buradaki boşluğu hissediyorlar.
Özet olarak, deployment pipeline'ındaki complexity metrikleri, sadece code quality dashboard'u olarak değil, aktif bir risk yönetim aracı olarak düşünülmelidir. Platform mühendisleri ve SRE'ler bu metriği canary rollout kararlarına direkt olarak entegre etmelidir. Bu bağlam, metriği operasyonel hale getirir ve gerçek incident riskini azaltır.

## Herkesin 10'da Ayarladığı CI Kapısı ve Neden İğneyi Hareket Ettirmediği

Standart tavsiye: döngüsel karmaşıklığı 10'da kap ve build başarısız kıl. Neredeyse her mühendislik blog'u önerir ve neredeyse kimse gerçek incident verilerine karşı doğrulamaz. Tamamen yanlış değil. Ekiplerin riski ele aldıklarına inanmalarını sağlayan şekilde eksik, ama ağırlıklı olarak onu sadece yer değiştirdi.

İki başarısızlık modu, ikisi de konuştuğumuz ekiplerinde yaygın:

- 
**Sayıyı oyunlaştırma.** Extract Method metinsel çözümdür ve çalışır: fonksiyon başına döngüsel karmaşıklık düşer. Ama çıkarma gerçek karar sayısını azaltmadıysa, sadece bir yerde üç fonksiyon üzerinde yer değiştirmişse, sistem karmaşıklığı değişmez. Kapı yeşile döner. Blast radiüsü küçülmez, tek diff view'ında görünmesi daha zor hale gelir. Rollout riskinde hiç kısılma yok.

- 
**Şekli göz ardı etme.** Düz eşik 12-dal dispatcher'ı ve 12-yol çarpık yolu eşit riskli muamele eder. Değiller. Dispatcher muhtemelen iyidir, mekanik yönlendirme. Çarpık yol, sonraki rollback'inizi nerede yaşayacağınızdır, çünkü onu inceleyenler üç seviye derinlikte devlet izini kaybetti. Nesting complexity düşük test coverage'ı gizler.

AI coding agensleri durumu daha kötüleştirmeden daha iyisini yapıyor. Devin ve benzeri özerk agenler PR'ları hızlı gönderirler ve hızlı genellikle zaten orada olanı refactor etmek yerine dal eklemeyi anlamına gelir. Bu, test paketi geçmeyi optimize eden bir modelin yolu. Code reviewer'ın bilişsel yüküne değil. Ekibiniz hacim halinde AI tarafından yazılmış diff merge ediyorsa, karmaşıklık delta PR başına metrik, dashboard'da görmek istediğiniz bir şey, incident review bulgusu değil. Bu, AI tarafından yazılmış kod üzerinde gözlemlediğimiz spesifik risk.

![İki mühendisin cam beyaz tahta'da çizilen bir dallanma akış çizelgesini inceleyen görüntüsü](https://fdzlnqpwsaniezitwiuw.supabase.co/storage/v1/object/public/cms-media/upstreamapi/2026-07/4479b1-inline2.webp)

## Karmaşıklık Delta Gerçekte Test Yükü Hakkında Söyledikleri

Mutlak puanı bir saniye için unut. Incident riskini tahmin eden sayı, tek bir diff tarafından tanıtılan karmaşıklıkta değişilme, test deltası'na karşı çapraz referanslı. Bir fonksiyonun karmaşıklığı 8'den 19'a giderse, basis path testing math'e göre, test sayısı kaba olarak ikiyle artmalıdır. Eksik testler geldiyse, kapsama boşluğu oluştu.

Karmaşıklığı 8'den 19'a bir PR'da giden fonksiyon, yukarıda basis-path-testing matematik'ten, kaba olarak test sayısını ikiyle artırmıştır. PR iki test eklediyse, kapsama boşluğu passing CI run sunan bir şey ile karıştırılmıştır. Bu boşluk, canary %5 traffic dilimini başına kadar devreye girmez, o zaman incident, PR thread'de çözülmemiş code review yorum değil. Canary'de birisi sorunla karşı karşıya geldiğinde, testler yazma zamanı geçti. Post-mortem'lerde bu paternin sayısı endişe verici: coverage yeşil gösterdi, testler geçti, review'de eksik bir şey görmediğim. Risk enstrümanı yanlış yerinde idi.

Bu, upstreamapi'nin AI Pilot'u kapatmak istediği enstrüman boşluğudur: canary yüzdesine tutun ve bekleme süresi karmaşıklık deltası tarafından gönderilen diff'e bağlı, sadece aşağı yönde error-rate SLO'ya değil. Error-rate SLO, bir şey zaten kırılmış olduğu söyler. Karmaşıklık delta kapısı, diff'in muhtemelen live traffic'e hizmet etmeden önce bir şeyi kırmak için daha olası olduğunu söyler, bu tek hala actionable olduğu nokta.

`// Basitleştirilmiş canary kapısı: düşük riskli diff'lerde yavaş geniş, yüksek riskli'de tutma
function canaryStep(diff: DiffMetrics): CanaryDecision {
  const complexityRisk = diff.complexityDelta / Math.max(diff.testDelta, 1);

  if (complexityRisk > 3 && diff.slo.errorBudgetBurn > 0.1) {
    return { action: "hold", trafficPct: diff.currentTrafficPct };
  }
  if (complexityRisk > 3) {
    return { action: "extend_bake_time", bakeMinutes: 45 };
  }
  return { action: "advance", trafficPct: diff.currentTrafficPct + 10 };
}`
## Araştırma Bunu Kabul Ediyor mu
Hayır ve bunu açıkça söylemek buna değer. Bazı uygulayıcı araştırmaları, döngüsel karmaşıklığın başlı başına kusur tahmincisi olmadığı konusunda sert şekilde geri itiyor, ekipler daha düşük puan için optimize olanlar, sadece daha az görünür yere karmaşıklık yer değiştirir. [GetDX'in eleştirisi](https://getdx.com/blog/cyclomatic-complexity/) bu davayı sunmuş ve ekipleri geliştiriciler deneyimi metriklerine yöneltmiş. Metriği öldürdüğüne inanmıyoruz, ölümlü tek başına static repo genelinde puan, diff ve rollout'dan kesilmiş. Doğru bağlamda: diff delta ve canary gating cihazında, güçlü bir sinyaldir. Operasyonel bağlam önemi.

## Canary'yi Sadece Error Rate Değil Karmaşıklık Üzerinde Nasıl Gate Yaparsınız

Sırada üç şey, PR'da katlandıkları friction'a göre:

- 
**Repo başına değil, diff başına delta karmaşıklığını hesaplayın.** Repo genelinde ortalamalar bu hafta önemli olan fonksiyonu gizler. Delta PR başına çoğu statik analiz araçlarında ucuz hesapla ve gelişen 48 saatte gerçekte kıran şeyle bağlantılı. SonarQube ve CodeClimate'de bunu varsayılan olarak sunuyorlar.

- 
**Test sayısı değil, test delta'ya karşı çapraz referans yapın.** 40 test içeren ve karmaşıklık 8'den 19'a yeni test sıfırı ile giden fonksiyon, gün bir'den 15 karmaşıklık ve matching kapsaması yeni işlevinden daha büyük risk. Coverage yüzdeleri bu kararı yakalayamıyor.

- 
**Rollout pacing'e feed'ı yapın, sadece merge onayı değil.** Yüksek karmaşıklık delta diff block gerektirmez code review'de, meşru karmaşık domain mantığı devlet makineleri, protokol parser'ları her zaman yüksek puan tutacak. Canary'yi yavaş tutması gerek ve daha kısa bir hata bütçesi kelepçesi gerek, bu rollout karar, code review karar değil. Kapı CI değil, release automation'da oturmalı.

Incident sonra değil, rollout'dan önce runbook giriş yazın. On-call mühendisinin açık kanala 3am'de girip temiz PR'ın hata bütçesini ateşlemesiyle neden bunu ters-mühendislik yapması gerek, dokümantasyon koddan önce başarısız oldu. Bir satır deploy log'a (karmaşıklık delta 11, test delta 1, %20'de tutma) yazmak hiçbir şey malı ve takip eden her incident review'nun ilk on beş dakika kaydediliyor. Zamanında bir operasyonel metin milyonlarca satır debugging'den daha iyi.

![Gece sunucu odasında LED durumları ve arka planda bir tablet tutarak yürüyen yalnız bir mühendisli koridor](https://fdzlnqpwsaniezitwiuw.supabase.co/storage/v1/object/public/cms-media/upstreamapi/2026-07/a58df0-inline3.webp)

## Takip Etme Değer mi, Yoksa Sadece Başka Bir Dashboard Sayı

Bu paternlerin göz önüne alındığında, complexity metrikleri yalnızca code review sürecinde değil, aynı zamanda canary rollout'u ve deployment automation'ında aktif olarak kullanılmalıdır. Metrik yalnız bağlamında değerli değildir. Operasyonel bağlam ve deployment risk yönetiminde bağlantı kritikal hale gelir. Canary döneminde metrik devreye girer.

Tamamen nereye takıp ettiğinize bağlı. Repo sağlık trend çizgisi olarak döngüsel karmaşıklık çoğunlukla süsleme: üçüncü kat sunum için iyi, 2am'de kısıtlı. Karmaşıklık delta elde gelen canary pacing'e girdiler ve test büyümesine karşı çapraz referanslı, bu rollout birinin sayfayı kaydırması için gideceği daha ucuz bir öncü gösterge bulduk. Metrik bağlamda işe yarar.

Post-mortem SLO bütçesi rollback'ten önce sorar. Giderek bizim hemen de shipping diff'de karmaşıklık delta sorarsın. Kendi runbook'unuza incident değil, incident sonra soruyu sorma faydasıdır, zamanı shrug ve promise sonra daha iyi testler add çünkü cevap böyledir. Metric operasyonel olmadıkça, bulgu çok geçtir. Metrik bağlamda işe yarar ve operasyonel impact taşır.Risk enstrümanı deployment time'da gerekir, review time'da değil.

## FAQ

### Basis path testing nedir ve karmaşıklık deltasıyla ilgisi nedir?

Basis path testing, bir fonksiyondaki tüm bağımsız yolları kapsayan minimum test sayısını hesaplayan bir metodolojidir. Döngüsel karmaşıklık 25 olan bir fonksiyon en az 25 test durumuna ihtiyaç duyar. Karmaşıklık deltası bir diff'de eklenen yeni yolların sayısıdır ve test deltaması ile karşılaştırıldığında, coverage boşluklarını ortaya koymak için kritik bir metriktir.

### Static complexity score'lar neden yanıltıcı olabilir?

Düz karmaşıklık eşikleri, 20-dal dispatcher'ı ve 20-yol çarpık fonksiyonu eşit riskli muamele eder. CodeScene'ın bumpy road deseni gösteriyor ki, iç içe koşullular olan fonksiyonlar daha riskli olabilir, çünkü yer değiştirme derinliği test kapsamasını gizler ve çalışma belleğini yıpratır. Blast radiüsü metric'in şeklinde, sadece sayıda değil.

### Canary rollout sırasında kompleks delta nasıl kullanmalı?

Canary pacing'i error-rate SLO'ya ek olarak, kompleks delta ve test delta oranına bağlı yapın. Ratio > 3 ise, canary yüzdesini tut veya bake time'ı uzat. Deployment log'a metriği yazın: sadece SLO değil, kanary'nin hızını ve riski yönetimi hakkındaki kararları inform eder.

### Extract Method refactoring'i neden oyunlaştırma kabul edilir?

Bir fonksiyonun karmaşıklığını üç fonksiyona çıkarmak skor'u düşürür ama karar sayısını değişmez, sistem karmaşıklığı değişmez. Kapı green dönüyor, blast radiüsü küçülmüyor. Oyunlaştırma-proof gating, test coverage artışını isteyen delta-based gates'dir.

### Nesting depth neden flat complexity scores'dan daha iyi bir risk göstergesi?

Flat score bir 20-dal dispatcher'ı ve 20-yol çarpık fonksiyonu aynı şekilde gösterir. Ama CodeScene'ın araştırması gösteriyor ki, iç içe derinlik bilinişsel yükü arttırır ve test coverage'ı gizler. 3 seviye yuvalanmış koşullu, aynı branch sayısına sahip düz bir switch'den daha risklidir.

### CI'de karmaşıklık kapısı bloking olmalı mı yoksa advisory mı?

Karmaşıklık yüksek diff'leri blocking yaparsanız, gerçek domain mantığı (state machines, format parser'ları) bloke edilir. Bunun yerine, advisory sinyali kullanın ve release pipeline'da canary pacing'i inform edin. Blocking CI'de, advisory operasyonel kararı code review sonrası deployment time'da verir.