Ne Bu Asenkron Programlama ?

Asenkron programlama nedir? Asynchronous, synchronous, blocing, non-blocking ve event based kelimelerinin farkları nelerdir?Örnek…

Ne Bu Asenkron Programlama ?

Çalıştırdığımız kodun nasıl yazıldığı kadar nasıl çalıştığı da hem geliştiriciler hem de kullanıcılar için büyük bir önem taşır. Yazımı kötü olan bir kodun okunması, çalışması ve üzerinde geliştirilme yapılması oldukça zahmetlidir. Kodumuzu clean code codensipleriyle yazsak bile sistemin çalışma sırasındaki işleyişine hakim değilsek bu bize kötü yazılmış kod kadar maaliyet yaratabilir.

Dosya işlemleri, veritabanlarıyla konuşmak veya ağ üzerinden harici yapılara bağlanmak saniyeler alabilir ve hatta fark bile edemeyeceğimiz hızlarda yapılan temel aritmetik işlemler uç uca eklendikçe artık can sıkıcı bir seviyeye gelebilir. Bilgisayarımızın kodları nasıl işlettiğine, zaman gibi bir maliyeti nasıl kısaltabileceğimize ve “Biliyor musun kodu bir refactor ettim, 2 saniyede çalışan kod 300 milisaniyede takır takır çalıştı.” gibi lafları nasıl kurabileceğimize gelin birlikte bakalım.

Programlama Dillerinin İşlemleri Çalıştırma Mantığı Nasıldır?

Propramlama dilleri, derleyiciler veya Node.js gibi çalıştırma ortamları kodumuzda bulunan satırları verdiğimiz parametrelere göre yahut dilin kendi yapısına göre ne zaman bir sonraki satıra geçeceğine farklı farklı karar verebilirler.

Bu işleyişi temel olarak şu şekilde iki bölüme ayırabiliriz:

Synchronous / Blocking

Arka arkaya birden fazla fonksiyon çağırdığımızda bu işleyiş stilinde her fonksiyon çalıştırılır ardından fonksiyondan cevap gelene kadar kodun bir sonraki adıma geçmesi engellenir.

Synchronous(senkron) ve Blocking(bloklamalı) yapılarının mantıkları aynı olsa da kullanıldığı yerler farklıdır.

Network gibi işlerde synchronous kelimesi kullanılırken dosya okuma örneğini verebileceğimiz IO gibi işlemlerinde ise blocking kelimesi kullanılır.

Asynchronous / Non-Blocking / Event Based

Bu yapıda ise fonksiyonlarımız çağrılır ve cevap gelmesi beklenmeden bir sonraki adıma geçilir. Genellikle birbiriyle mantıksal ilişkisi olmayan görevleri yaparken birinin başlaması için öbürünün bitmesinin gerekmediği durumlarda kullanılır.

Event based(olay bazlı) yapıda ise daha önceden belirlenmiş olaylar tetiklenmeden çalıştırma yapılmaz. Burada olayların hangi sırayla tanımlandığı değil hangi sırayla tetiklendiği önemlidir. HTML ve JavaScript’teki event’ler bunun en güzel örneğidir. Bu terim de yeni başlayanlar için soru işaretli olduğu için buna da değinmeyi uygun gördüm.

async/await Kullanımı

C# 5.0, C++20, Python 3.5, F#, Hack, Julia, Dart, Kotlin 1.1, Rust 1.39, Nim 0.9.4, JavaScript ES2017, Swift 5.5, Zig ve bazı eklentilerle birlikte deneysel olarak Scala asenkron porgramlama için uygun koşulları sağlar. Dilden dile bu anahtar kelimelerin yazımı farklılık gösterebilir.

Bir fonksiyonu asenkron işletebilmek için async ile bunu bildirmeliyiz. Tip güvenli dillerde fonksiyonumuzun dönüş tipini Task veya Promise olarak belirterek dönüşün uzun sürebileceğini belirtip içine generic olarak asıl dönüş tipini yazmalıyız.

async Task<int> getUserId(string username){
int id;
// Mantıksal işlemler
return id;
}

“Senkron programlama tamam ama asenkron proramlama yaparken cevap gelmeden nasıl işime devam edeceğim ki?” sorusunu kendinize sorduysanız gelin bir de await anahtar kelimesine bakalım.

await ile asenkron işleyişi kırıp cevap gelene kadar işlemi beklenmesi gerektiğini belirtiyoruz.

async Task<int> getUserId(string username){
User user = await findUserFromDatabase(username);
return user.id;
}

Örnek Senaryo

Büyük bir Excell dosyasınında bulunan malzeme bilgilerini okuyacak, her satır için PDF olarak fatura oluşturacak ardından bunları bir kullanıcıya mail atacak ve excell’deki bilgileri veritabanına kaydedecek bir sistemimiz olduğunu düşünelim.

Bunu yapacak senkron kod basitçe şöyle olurdu:

senkron kod örneği

Fonsiyonların sırasıyla 1, 2, 2 ve 1 birim zamanda çalıştığını varsayarsak şöyle bir zaman grafik elde ederiz.

senkron fonksiyon/zaman çizgisi

Koddaki excellOku ve pdfOlusturVeGetir dışındaki fonksiyonlar birbirinden bağımsızdır. Bundan dolayı onları ayrık olarak çalıştırmayı deneyebiliriz.

asenkron kod örneği

faturaBilgilendirmeMailiGonder ve veritabaninaKaydet fonksiyonları çalıştırılmaya başlanacak ve hemen bir sonraki adıma geçilecek. Buna göre zaman çizelgesi şöyle olurdu:

asenkron fonksiyon/zaman çizgisi

Çizelgeden de anlaşılabildiği üzere son iki işi neredeyse aynı anda başlatarak zamandan tasarruf etmemiz mümkün oldu.

Sonuç

Düzgün kurgulanmış bir asenkron kodla çalışmak bize gözle görülebilir bir zaman kazancı sağlayacaktır. Unutulmamalıdır ki birden fazla yapıyla(fonksiyon, koşul, döngü) ilişki içinde olan verilerimizi korumak için özellikle de ona atama yapılacağı zaman await veya mutex gibi yapılarla o anda sadece bir işlemin onunla ilgilenmesini sağlamalıyız çünkü cpu’daki iş yükü, ağ yoğunluğu gibi belirleyemeyeceğimiz nedenlerden dolayı işlemlerimiz beklediğimizden farklı sürede çalışabilir ve bu da kodda yazdığımız sırayla atama yapılmasına engel olur.

Kaynakça: