Photo by Jiroe on Unsplash

Teknik Muhabbetler #1 (Easy Cache)

Furkan Güngör
Mobiroller Tech
4 min readJun 22, 2020

--

Mobiroller Tech kanalında yeni bir serinin daha başlangıcını yapmak oldukça heyecan verici. Daha önce başlattığım “Sprint Hikayeleri” serisine uzun zamandır içerik üretemediğimin farkındayım. Takdir edersiniz ki her sprint teklonojik bir yazıya dönüştürülemiyor, malum bazen bug fix, bazen ise business tarafının hızını kaybetmemesi için kaliteden biraz ödün verebiliyoruz. :)

Belki bu konuda yazıya başlamadan önce size küçük bir öneride bulunabilirim, takım olmak ve ürün içerisinde değer yaratmak için bazen kaliteden ödün vermemiz gerekebilir, bazen hızlı bir planlama ve geliştirme aşamasında olabiliriz, bu sürecin iyi yönetilmesi durumunda elde edilen teknik borçlar artsa bile tüm takım mutlu olacaktır.

Kısacası bir yere çok ama çok statik bir kod bırakmış olabilirsiniz, binlerce satırlık bir class’ı refactor etmeye çalışırken gördüğünüz yüzlerce if statement’lar kümesine bir if ‘de siz ekleyebilirsiniz, bu tür senaryolarda moral bozmayıp kötü kokan bu yapıların bir gün refactor edileceğini düşünün ve refactor günü geldiğinde işinizin kolaylaşması için döküman oluşturup mutlu olun . :)

BackEnd geliştiricisi olarak günlük hayatta en çok yaptığım işlerden birisi CRUD. Evet CRUD operasyonları, oldukça baş belası olan bu operasyonların arasında beni en çok korkutan şüphesiz READ operasyonudur.

Dışarıdan çok masum duran bu operasyon bazen çok can sıkıcı olabiliyor, left join, right join, inner join, concat falan derken bu operasyonun altında biriken ve sırası geldiğinde başımızı ağrıtacak bir sorunu beslemiş oluyoruz.

Evet tam bu satıra geldiğinizde aklınızdaki cevabı okuyabiliyorum. “Performans”.

Veri tabanında yürütülen bu operasyon günün sonunda bize performans sorunları ile birlikte cevap veriyor. READ işlemlerinde performansı iyileştirmenin birçok yöntemi var; Stored Procudure, Index optimizasyonu gibi yöntemleri kullanabilirsiniz veya Execution Planı açıp öylece dalıp gidersiniz SQL’in derinliklerine. :)

Execution Plan :)

Tam olarak Read operasyonlarının performansını artırmasada Cache mekanizmaları Response Time’ı düşürmek için oldukça etkilidirler.

Basit anlamda belirli bir süre boyunca verilerinizi cache’den okursanız kullanıcıyı bire bir etkileyen response sürelerinizi minumum seviyelere indirebilirsiniz.

Uygulamalarınıza cache implementasyonu gerçekleştirmek istediğinizde, ilk cevaplamanız gereken soru;

“Hangisini kullanmalıyım ?” olacaktır. Kullanabileceğiniz bir çok cache yapısı var (Memory Cache, Redis, NCache, Memcached) size uygun olan bir tanesini seçip implementasyona başlayabilirsiniz.

Ancak Mobiroller’da klavyemin her tuşuna aşılamak istediğim bir standart var;

“Bir gün aşklar biter hatıralar kalır. Üzülmek istemiyorsan kullandığın her third party uygulamanın implementasyonunu generic yap ve istediğin zaman provider değiştir ve yoluna devam et.” :)

Bu düşünce ile yola çıkınca küçük bir kütüphane ile bunu gerçekleştirebileceğimi biliyordum, amacım tüm cache yapılarının implementasyonunu gerçekleştirebileceğim ve startup.cs içerisinde kolayca implemente edilebilecek bir yapı kurmaktı.

Cache Service interface

Provider’dan bağımsız olarak cache kullanırken muhakkak kullanmamız gereken yapıları bir interface ile tanımlayabiliriz.

ICacheService bir interface ve bu interface’i implemente eden birçok yapı olabilir.

Memcached

Memcache implementation for Easy Cache

Redis

Redis implementation for Easy Cache

Böylece istediğiniz kadar provider implementasyonu yapabilirsiniz.

Bu esnekliği startup.cs içerisinde kullanabilmek için ServiceCollection nesnesine extension method yazmamız gerekecek. Bu sayede startup.cs içerisinde sadece bu extension methodu çağırarak kolayca provider değişikliği yapılabilecektir.

Service Collection extensions
Startup.cs for Easy Cache

Extension method sayesinde startup.cs içerisinde kolay bir şekilde provider değişikliğine gidebilirsiniz.

Genelde uygulamalarımızda bir teklonojiyi implemente ettiğimizde sanki yıllar boyunca o teklonoji bizim sorunumuzu çözebilecekmiş gibi davranırız ama gerçek dünyada bu kurallar her zaman değişebilir ve bu teklonojilere “göbekten bağlı” olmamak gerekiyor, kolay bir şekilde provider değiştirmek değişen kurallar doğrultusunda işinizi kolaylaştıracaktır.

Default Controller for Easy Cache

Controller seviyesinde iki farklı yöntem ile implementasyonu gerçekleştirebilirsiniz.

  • AutoCache Attribute

AutoCache Attribute ile endpoint seviyesinde cache uygulayabilirsiniz. Eğer herhangi bir logic olmadan key değeri ile ulaşabileceğiniz ve değişmeyecek bir veriniz var ise AutoCache kullanabilirsiniz.

Eğer belirtilen key ile data bulunamazsa, istek çalışmaya devam eder ve response değerinizi belirttiğiniz key ile cache’leyecektir.

  • Get And Set

GetAndSet extension methodu ile eğer belirlenen key ile cache bulunamazsa verinin nereden okunacağını Func<T> olarak yazabilirsiniz. AutoCache gibi GetAndSet’ de eğer cache boş ise Func execute edildikten sonra return değerinizi cache’leyecektir.

Eğer birden fazla provider arasında hızlıca geçiş yapmak, AutoCache gibi bir attribute kullanmak istiyorsanız sizin için yazdığımız bu kodları küçük bir kütüphane haline getirdim.

Install-Package EasyCacheDotnetCore -Version 1.0.1

Yazımı Enis Necipoğlu Hocamın Coder vs Developer yazısından küçük bir alıntı ile bitiriyorum.

Hayatınızda hiçbir zaman önünüzdeki çimento torbalarını hemen sırtlanıp bir an önce işe koyulayım da hemen bitsin diye düşünmeyin. Öncelikle o torbaları kaç farklı şekilde taşıyabileceğiniz düşünün. Fırsatları analiz edin. Çözüm üretin. Emin olun o torbaları hemen sırtlanıp taşımak herkesin aklına gelecektir. Düşünün, planlayın, farklı olun. Bu dünyaya bir tool daha katarak iz bırakın.

Happy Coding.

Kaynaklar

--

--

Furkan Güngör
Mobiroller Tech

Solution Developer — I want to change the world, give me the source code.